Draw curve with multiple points

Hello,

I’m currently trying to develop a small project about procedural animation and i’m now struggling to make a good render around my “creature”.

The creature is made of multiple segment on which i have a right side point and a left side point that i use to draw the outline of the creature. Currently i only join a segment to the next one using draw_line resulting in a straight line. it works but the result is really ugly.

My goal would be to join all the point in a curvy way making the result more biologic. But i have no idea how to do that.

All i want is a way to join those points in a smooth way, do you have any idea ?

Can you show your code? Since you are using draw_line I don’t suspect an easy solution outside of “add more points”.

A very different but probably easier and more performant solution may be to use metaballs, a shader technique (mostly the step function and gradients) that creates connected blobs

https://john-wigg.dev/2DMetaballs/

class_name CreatureSegment

var radius = 20
var color = Color.WHITE
var fixed_distance = 30
var previous_segment = null
var target = false
var left_point = Vector2(0, 0)
var right_point = Vector2(0, 0)

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	if target:
		self.position = get_global_mouse_position()
		
	if previous_segment != null:
		update(previous_segment)
	queue_redraw()
	pass

func _draw() -> void:
	if !target:
		#draw_circle(Vector2(0, 0), radius, color, false, 5, true)
		#draw_circle(left_point, 1, Color.BLACK, true, 2, true)
		#draw_circle(right_point, 1, Color.BLACK, true, 2, true)
		draw_line(left_point, previous_segment.left_point + previous_segment.global_position - self.global_position, Color.BLUE, 2, true)
		draw_line(right_point, previous_segment.right_point + previous_segment.global_position - self.global_position, Color.BLUE, 2, true)

func update(previous_segment: CreatureSegment):
	var theta = atan2(previous_segment.position.y-self.position.y, previous_segment.position.x-self.position.x)
	var distance = sqrt(pow(previous_segment.position.x-self.position.x, 2)+pow(previous_segment.position.y-self.position.y, 2))
	var delta: float = distance - fixed_distance
	self.position.x += delta*cos(theta)
	self.position.y += delta*sin(theta)
	left_point = getPointWithAngle(-90)
	right_point = getPointWithAngle(90)


func getPointWithAngle(angle):
	var theta = atan2(previous_segment.position.y-self.position.y, previous_segment.position.x-self.position.x)
	theta += angle * PI/180
	return Vector2(radius * cos(theta), radius * sin(theta))

here is the code, i use multiple segments to create a creture, each segment linked with the other to follow it. Then i get the right and left point of a segment and link it to the left and right point of the linked segment.

Seems like metabells is a good idea, i have no experience with shader but i’ll try to learn thanks