Godot: CanvasItem.draw_polyline draws incorrect, distorted geometry

Created on 7 Feb 2018  路  11Comments  路  Source: godotengine/godot

Godot version:
cbdd410

Issue description:
image

the problem is inside
https://github.com/godotengine/godot/blob/cbdd410a6f476503ee4bc27ac2f475a73960236d/servers/visual/visual_server_canvas.cpp#L464

Minimal reproduction project:
PolylineBug.zip

bug rendering

Most helpful comment

Redirected from #34073 being archived as a duplicate.

Godot version:
Mono 3.2 Beta 2

OS/device including version:
Manjaro Arch Linux "Juhraya" 18.1.2

Issue description:
draw_polyline draws the start and end points wider then the rest of the points.

This is using the draw_polyline_color function but it results in the same shape
image

Steps to reproduce:

  • Add a _draw override to a CanvasItem
  • Add draw_polyline([Vector2(), Vector2(0, 100), Vector2(100, 100), Vector2(100, 0), Vector2(-25, 0)], Color.white, 50, false)
  • Have the node draw either in editor or in game

Minimal reproduction project:
polyline_issue_project.zip

All 11 comments

It doesn't look like a bug, when you think about it. You would need to expand those corners so that the segment has the same thickness, however it can lead to infinitely sized turns in some cases.

It looks like draw_polyline is not using the algorithm used by the Line2D node, which is able to render this kind of line better IMO

This is a fundamental problem of the idea used in the function ("replace every point by two points").

If there is a very small angle at some point, the replacement points either extend far into outer space or the lines attached to this corner are very thin. However, you can use three points (one for the inner corner, two for the outer almost-180掳-"bend") to reduce these problems to sane levels.

After that, there might be some adjustments to make, depending on whether you want to keep the directions (in which case the original vertices might get cut off) or the points (in which case you have to move the above construction "outwards", changing the direction of the lines).

It's similar to planning a racetrack using the points as guidance for the straight segments vs. fitting a racetrack through the given points (or, B茅zier curves vs. splines; in the sense that B茅zier curves need not hit the intermediate points).

Yeah other method for smooth lines should be used.

@Chaosus what do you mean? There is no fix planned? Should users just use Line2D to have better results?

Yeah, I suspect Line2D is better choise

But it's not if you want custom draw (note that the Line2D node actually uses a LineBuilder, which can also be used as implementation for draw_polyline, not sure why it wasn't done)

Zylann, got it, should I reopen this ?

Yeah, although it's possible to use LineBuilder with some predefined params to get a better looking line, I wonder why it wasn't used in the first place (draw_polyline was added long after Line2D)

May be improved in 3.2

Redirected from #34073 being archived as a duplicate.

Godot version:
Mono 3.2 Beta 2

OS/device including version:
Manjaro Arch Linux "Juhraya" 18.1.2

Issue description:
draw_polyline draws the start and end points wider then the rest of the points.

This is using the draw_polyline_color function but it results in the same shape
image

Steps to reproduce:

  • Add a _draw override to a CanvasItem
  • Add draw_polyline([Vector2(), Vector2(0, 100), Vector2(100, 100), Vector2(100, 0), Vector2(-25, 0)], Color.white, 50, false)
  • Have the node draw either in editor or in game

Minimal reproduction project:
polyline_issue_project.zip

Wanted to open a bug report but seeing this, so attaching my own reproduction project.

GLES2, GLES3, Godot 3.2.4 beta.

draw_polyline vs draw_line, width 3.0

Screenshot 2020-11-16 112005

draw_polyline vs draw_line, width 20.0

Screenshot 2020-11-16 112049

So, currently draw_polyline is not useful to use in most cases for width > 1.0 (I'd expect it to work like draw_line at least), and I think draw_line is kind of expected to draw rectangles with width > 5.0, so indeed Line2D is superior out of them all, unfortunately I just cannot allow myself to use Line2D as a dependency of other similar class for line drawing.

Minimal reproduction project:

extends Node2D

export(float, 0.1, 20.0, 0.1) var width = 5.0 setget set_width

func set_width(p_width):
    width = p_width
    update()

var points = [Vector2(100, 100), Vector2(100, 200), Vector2(200, 200), Vector2(300, 100)]

func _draw():
    draw_polyline(points, Color.orange, width)

    draw_set_transform(Vector2(300, 0), 0, Vector2.ONE)

    for i in points.size() - 1:
        var p1 = points[i]
        var p2 = points[i + 1]
        draw_line(p1, p2, Color.cornflower, width)

draw_polyline_malformed.zip

Also, I have a little feature request: make draw_polyline (or similar) also draw closed lines, as needed by #34923.

Was this page helpful?
0 / 5 - 0 ratings