diff options
| -rw-r--r-- | core/core_bind.cpp | 15 | ||||
| -rw-r--r-- | core/core_bind.h | 2 | ||||
| -rw-r--r-- | core/math/geometry_2d.h | 12 | ||||
| -rw-r--r-- | doc/classes/Geometry2D.xml | 14 | ||||
| -rw-r--r-- | doc/classes/InputEventMouseMotion.xml | 2 |
5 files changed, 38 insertions, 7 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 891e3a28c9..095c6c44dd 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -920,6 +920,19 @@ Dictionary Geometry2D::make_atlas(const Vector<Size2> &p_rects) { return ret; } +TypedArray<Point2i> Geometry2D::bresenham_line(const Point2i &p_from, const Point2i &p_to) { + Vector<Point2i> points = ::Geometry2D::bresenham_line(p_from, p_to); + + TypedArray<Point2i> result; + result.resize(points.size()); + + for (int i = 0; i < points.size(); i++) { + result[i] = points[i]; + } + + return result; +} + void Geometry2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_point_in_circle", "point", "circle_position", "circle_radius"), &Geometry2D::is_point_in_circle); ClassDB::bind_method(D_METHOD("segment_intersects_circle", "segment_from", "segment_to", "circle_position", "circle_radius"), &Geometry2D::segment_intersects_circle); @@ -954,6 +967,8 @@ void Geometry2D::_bind_methods() { ClassDB::bind_method(D_METHOD("make_atlas", "sizes"), &Geometry2D::make_atlas); + ClassDB::bind_method(D_METHOD("bresenham_line", "from", "to"), &Geometry2D::bresenham_line); + BIND_ENUM_CONSTANT(OPERATION_UNION); BIND_ENUM_CONSTANT(OPERATION_DIFFERENCE); BIND_ENUM_CONSTANT(OPERATION_INTERSECTION); diff --git a/core/core_bind.h b/core/core_bind.h index d59a2c55f1..b690376551 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -324,6 +324,8 @@ public: Dictionary make_atlas(const Vector<Size2> &p_rects); + TypedArray<Point2i> bresenham_line(const Point2i &p_from, const Point2i &p_to); + Geometry2D() { singleton = this; } }; diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index 83ebdc5a84..abd395d8df 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -451,17 +451,17 @@ public: return H; } - static Vector<Point2i> bresenham_line(const Point2i &p_start, const Point2i &p_end) { + static Vector<Point2i> bresenham_line(const Point2i &p_from, const Point2i &p_to) { Vector<Point2i> points; - Vector2i delta = (p_end - p_start).abs() * 2; - Vector2i step = (p_end - p_start).sign(); - Vector2i current = p_start; + Vector2i delta = (p_to - p_from).abs() * 2; + Vector2i step = (p_to - p_from).sign(); + Vector2i current = p_from; if (delta.x > delta.y) { int err = delta.x / 2; - for (; current.x != p_end.x; current.x += step.x) { + for (; current.x != p_to.x; current.x += step.x) { points.push_back(current); err -= delta.y; @@ -473,7 +473,7 @@ public: } else { int err = delta.y / 2; - for (; current.y != p_end.y; current.y += step.y) { + for (; current.y != p_to.y; current.y += step.y) { points.push_back(current); err -= delta.x; diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml index 2dd76ad989..71e6cf93ae 100644 --- a/doc/classes/Geometry2D.xml +++ b/doc/classes/Geometry2D.xml @@ -9,6 +9,20 @@ <tutorials> </tutorials> <methods> + <method name="bresenham_line"> + <return type="Vector2i[]" /> + <param index="0" name="from" type="Vector2i" /> + <param index="1" name="to" type="Vector2i" /> + <description> + Returns the [url=https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm]Bresenham line[/url] between the [param from] and [param to] points. A Bresenham line is a series of pixels that draws a line and is always 1-pixel thick on every row and column of the drawing (never more, never less). + Example code to draw a line between two [Marker2D] nodes using a series of [method CanvasItem.draw_rect] calls: + [codeblock] + func _draw(): + for pixel in Geometry2D.bresenham_line($MarkerA.position, $MarkerB.position): + draw_rect(Rect2(pixel, Vector2.ONE), Color.WHITE) + [/codeblock] + </description> + </method> <method name="clip_polygons"> <return type="PackedVector2Array[]" /> <param index="0" name="polygon_a" type="PackedVector2Array" /> diff --git a/doc/classes/InputEventMouseMotion.xml b/doc/classes/InputEventMouseMotion.xml index bcfe5b70fd..4c1461d03a 100644 --- a/doc/classes/InputEventMouseMotion.xml +++ b/doc/classes/InputEventMouseMotion.xml @@ -5,7 +5,7 @@ </brief_description> <description> Stores information about a mouse or a pen motion. This includes relative position, absolute position, and velocity. See [method Node._input]. - [b]Note:[/b] By default, this event is only emitted once per frame rendered at most. If you need more precise input reporting, set [member Input.use_accumulated_input] to [code]false[/code] to make events emitted as often as possible. If you use InputEventMouseMotion to draw lines, consider implementing [url=https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm]Bresenham's line algorithm[/url] as well to avoid visible gaps in lines if the user is moving the mouse quickly. + [b]Note:[/b] By default, this event is only emitted once per frame rendered at most. If you need more precise input reporting, set [member Input.use_accumulated_input] to [code]false[/code] to make events emitted as often as possible. If you use InputEventMouseMotion to draw lines, consider using [method Geometry2D.bresenham_line] as well to avoid visible gaps in lines if the user is moving the mouse quickly. [b]Note:[/b] This event may be emitted even when the mouse hasn't moved, either by the operating system or by Godot itself. If you really need to know if the mouse has moved (e.g. to suppress displaying a tooltip), you should check that [code]relative.is_zero_approx()[/code] is [code]false[/code]. </description> <tutorials> |
