geom

Polylines and Paths

Joins, per-point color and thickness.

A polyline is a line drawn with a list of points.

Points

polyline_points_2d(points, closed) draws a PackedVector2Array in the current style. closed joins the last point back to the first.

extends Node2D
func _process(_delta: float) -> void:
	GeomDraw.reset_all_draw_states()
	GeomDraw.thickness = 8.0
	GeomDraw.color = Color(0.42, 0.85, 1.0)

	# An open zigzag path
	var zigzag := PackedVector2Array()
	zigzag.resize(6)
	for i in 6:
		zigzag[i] = Vector2(60 + i * 44, 110 + 120 * (i % 2))
	GeomDraw.polyline_points_2d(zigzag, false)

	# A closed pentagon path
	var pentagon := PackedVector2Array()
	pentagon.resize(5)
	for i in 5:
		var angle := -TAU / 4 + i * TAU / 5
		pentagon[i] = Vector2(460, 170) + Vector2(cos(angle), sin(angle)) * 70
	GeomDraw.polyline_points_2d(pentagon, true)
using Godot;

public partial class PolylinePoints : Node2D
{
    public override void _Process(double delta)
    {
        Geom.Draw.ResetAllDrawStates();
        Geom.Draw.Thickness = 8.0f;
        Geom.Draw.Color = new Color(0.42f, 0.85f, 1.0f);

        // An open zigzag path
        var zigzag = new Vector2[6];
        for (int i = 0; i < 6; i++)
        {
            zigzag[i] = new Vector2(60 + i * 44, 110 + 120 * (i % 2));
        }
        Geom.Draw.PolylinePoints2D(zigzag, false);

        // A closed pentagon path
        var pentagon = new Vector2[5];
        for (int i = 0; i < 5; i++)
        {
            var angle = -Mathf.Tau / 4 + i * Mathf.Tau / 5;
            pentagon[i] = new Vector2(460, 170) + new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * 70;
        }
        Geom.Draw.PolylinePoints2D(pentagon, true);
    }
}

polyline_points

Per-Point Style

For a color or thickness per point, build a GeomPolylinePath and draw it with polyline_2d(path, closed). add_point_2d_full(position, color, scale) adds a point with its own color and a thickness scale. The point’s color multiplies color, and its scale multiplies thickness.

extends Node2D

func _process(_delta: float) -> void:
	GeomDraw.reset_all_draw_states()
	GeomDraw.thickness = 24.0
	GeomDraw.polyline_join = Geom.JOIN_ROUND

	var path := GeomPolylinePath.new()
	for i in 30:
		var u := i / 29.0
		var position := Vector2(60 + u * 520, 170 + sin(u * TAU) * 70)
		var color := Color(1.0, 0.78, 0.36, u)
		path.add_point_2d_full(position, color, u)
	GeomDraw.polyline_2d(path, false)
using Godot;

public partial class PolylinePath : Node2D
{
    public override void _Process(double delta)
    {
        Geom.Draw.ResetAllDrawStates();
        Geom.Draw.Thickness = 24.0f;
        Geom.Draw.PolylineJoin = Geom.PolylineJoin.Round;

        var path = Geom.PolylinePath.New();
        for (int i = 0; i < 30; i++)
        {
            var u = i / 29.0f;
            var position = new Vector2(60 + u * 520, 170 + Mathf.Sin(u * Mathf.Tau) * 70);
            var color = new Color(1.0f, 0.78f, 0.36f, u);
            path.AddPoint2DFull(position, color, u);
        }
        Geom.Draw.Polyline2D(path, false);
    }
}

polyline_path

The 3D forms drop the _2d: polyline_points, polyline and add_point_full.

Joins

polyline_join sets how the corners are drawn:

JOIN_SIMPLEthe two segments meet at plain width, so the outside pinches in
JOIN_MITERthe outside edges extend until they meet, clamped on sharp turns
JOIN_ROUNDa disc over each corner
JOIN_BEVELthe outside of the corner cut off square
extends Node2D

func _process(_delta: float) -> void:
	GeomDraw.reset_all_draw_states()
	GeomDraw.thickness = 26.0
	GeomDraw.color = Color(0.42, 0.85, 1.0)

	var corner := PackedVector2Array()
	corner.resize(3)
	corner[0] = Vector2(-50, 240)
	corner[1] = Vector2(0, 110)
	corner[2] = Vector2(50, 240)

	GeomDraw.transform_2d = Transform2D(0.0, Vector2(90, 0))
	GeomDraw.polyline_join = Geom.JOIN_SIMPLE
	GeomDraw.polyline_points_2d(corner, false)

	GeomDraw.transform_2d = Transform2D(0.0, Vector2(240, 0))
	GeomDraw.polyline_join = Geom.JOIN_MITER
	GeomDraw.polyline_points_2d(corner, false)

	GeomDraw.transform_2d = Transform2D(0.0, Vector2(390, 0))
	GeomDraw.polyline_join = Geom.JOIN_ROUND
	GeomDraw.polyline_points_2d(corner, false)

	GeomDraw.transform_2d = Transform2D(0.0, Vector2(540, 0))
	GeomDraw.polyline_join = Geom.JOIN_BEVEL
	GeomDraw.polyline_points_2d(corner, false)
using Godot;

public partial class PolylineJoins : Node2D
{
    public override void _Process(double delta)
    {
        Geom.Draw.ResetAllDrawStates();
        Geom.Draw.Thickness = 26.0f;
        Geom.Draw.Color = new Color(0.42f, 0.85f, 1.0f);

        var corner = new Vector2[3];
        corner[0] = new Vector2(-50, 240);
        corner[1] = new Vector2(0, 110);
        corner[2] = new Vector2(50, 240);

        Geom.Draw.Transform2D = new Transform2D(0.0f, new Vector2(90, 0));
        Geom.Draw.PolylineJoin = Geom.PolylineJoin.Simple;
        Geom.Draw.PolylinePoints2D(corner, false);

        Geom.Draw.Transform2D = new Transform2D(0.0f, new Vector2(240, 0));
        Geom.Draw.PolylineJoin = Geom.PolylineJoin.Miter;
        Geom.Draw.PolylinePoints2D(corner, false);

        Geom.Draw.Transform2D = new Transform2D(0.0f, new Vector2(390, 0));
        Geom.Draw.PolylineJoin = Geom.PolylineJoin.Round;
        Geom.Draw.PolylinePoints2D(corner, false);

        Geom.Draw.Transform2D = new Transform2D(0.0f, new Vector2(540, 0));
        Geom.Draw.PolylineJoin = Geom.PolylineJoin.Bevel;
        Geom.Draw.PolylinePoints2D(corner, false);
    }
}

polyline_joins

JOIN_ROUND draws its discs as separate shapes, so a translucent polyline is darker where a disc overlaps the line.

Limits

dashed and fill are not supported on a polyline.