Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to specify miter limit and arc tolerance for polypath offsetting #29758

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions core/bind/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,9 +1695,9 @@ Array _Geometry::intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_pol
return ret;
}

Array _Geometry::offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
Array _Geometry::offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, real_t p_miter_limit, real_t p_arc_tolerance) {

Vector<Vector<Point2> > polys = Geometry::offset_polygon_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type));
Vector<Vector<Point2> > polys = Geometry::offset_polygon_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type), p_miter_limit, p_arc_tolerance);

Array ret;

Expand All @@ -1707,9 +1707,9 @@ Array _Geometry::offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_de
return ret;
}

Array _Geometry::offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
Array _Geometry::offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type, real_t p_miter_limit) {

Vector<Vector<Point2> > polys = Geometry::offset_polyline_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type), Geometry::PolyEndType(p_end_type));
Vector<Vector<Point2> > polys = Geometry::offset_polyline_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type), Geometry::PolyEndType(p_end_type), p_miter_limit);

Array ret;

Expand Down Expand Up @@ -1795,8 +1795,8 @@ void _Geometry::_bind_methods() {
ClassDB::bind_method(D_METHOD("clip_polyline_with_polygon_2d", "polyline", "polygon"), &_Geometry::clip_polyline_with_polygon_2d);
ClassDB::bind_method(D_METHOD("intersect_polyline_with_polygon_2d", "polyline", "polygon"), &_Geometry::intersect_polyline_with_polygon_2d);

ClassDB::bind_method(D_METHOD("offset_polygon_2d", "polygon", "delta", "join_type"), &_Geometry::offset_polygon_2d, DEFVAL(JOIN_SQUARE));
ClassDB::bind_method(D_METHOD("offset_polyline_2d", "polyline", "delta", "join_type", "end_type"), &_Geometry::offset_polyline_2d, DEFVAL(JOIN_SQUARE), DEFVAL(END_SQUARE));
ClassDB::bind_method(D_METHOD("offset_polygon_2d", "polygon", "delta", "join_type", "miter_limit", "arc_tolerance"), &_Geometry::offset_polygon_2d, DEFVAL(JOIN_SQUARE), DEFVAL(2.0), DEFVAL(0.25));
ClassDB::bind_method(D_METHOD("offset_polyline_2d", "polyline", "delta", "join_type", "end_type", "miter_limit"), &_Geometry::offset_polyline_2d, DEFVAL(JOIN_SQUARE), DEFVAL(END_SQUARE), DEFVAL(2.0));

ClassDB::bind_method(D_METHOD("make_atlas", "sizes"), &_Geometry::make_atlas);

Expand Down
4 changes: 2 additions & 2 deletions core/bind/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,8 @@ class _Geometry : public Object {
END_SQUARE,
END_ROUND
};
Array offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE);
Array offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE, PolyEndType p_end_type = END_SQUARE);
Array offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE, real_t p_miter_limit = 2.0, real_t p_arc_tolerance = 0.25);
Array offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE, PolyEndType p_end_type = END_SQUARE, real_t p_miter_limit = 2.0);

Dictionary make_atlas(const Vector<Size2> &p_rects);

Expand Down
4 changes: 2 additions & 2 deletions core/math/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1137,7 +1137,7 @@ Vector<Vector<Point2> > Geometry::_polypaths_do_operation(PolyBooleanOperation p
return polypaths;
}

Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type, real_t p_miter_limit, real_t p_arc_tolerance) {

using namespace ClipperLib;

Expand All @@ -1158,7 +1158,7 @@ Vector<Vector<Point2> > Geometry::_polypath_offset(const Vector<Point2> &p_polyp
case END_SQUARE: et = etOpenSquare; break;
case END_ROUND: et = etOpenRound; break;
}
ClipperOffset co(2.0, 0.25 * SCALE_FACTOR); // Defaults from ClipperOffset.
ClipperOffset co(p_miter_limit, p_arc_tolerance * SCALE_FACTOR);
Xrayez marked this conversation as resolved.
Show resolved Hide resolved
Path path;

// Need to scale points (Clipper's requirement for robust computation).
Expand Down
10 changes: 5 additions & 5 deletions core/math/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -820,16 +820,16 @@ class Geometry {
return _polypaths_do_operation(OPERATION_INTERSECTION, p_polyline, p_polygon, true);
}

static Vector<Vector<Point2> > offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
static Vector<Vector<Point2> > offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, real_t p_miter_limit, real_t p_arc_tolerance) {

return _polypath_offset(p_polygon, p_delta, p_join_type, END_POLYGON);
return _polypath_offset(p_polygon, p_delta, p_join_type, END_POLYGON, p_miter_limit, p_arc_tolerance);
}

static Vector<Vector<Point2> > offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
static Vector<Vector<Point2> > offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type, real_t p_miter_limit) {

ERR_FAIL_COND_V_MSG(p_end_type == END_POLYGON, Vector<Vector<Point2> >(), "Attempt to offset a polyline like a polygon (use offset_polygon_2d instead).");

return _polypath_offset(p_polygon, p_delta, p_join_type, p_end_type);
return _polypath_offset(p_polygon, p_delta, p_join_type, p_end_type, p_miter_limit);
}

static Vector<int> triangulate_delaunay_2d(const Vector<Vector2> &p_points) {
Expand Down Expand Up @@ -1025,7 +1025,7 @@ class Geometry {

private:
static Vector<Vector<Point2> > _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
static Vector<Vector<Point2> > _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
static Vector<Vector<Point2> > _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type, real_t p_miter_limit = 2.0, real_t p_arc_tolerance = 0.25);
};

#endif
9 changes: 9 additions & 0 deletions doc/classes/Geometry.xml
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,15 @@
</argument>
<argument index="2" name="join_type" type="int" enum="Geometry.PolyJoinType" default="0">
</argument>
<argument index="3" name="miter_limit" type="float" default="2.0">
</argument>
<argument index="4" name="arc_tolerance" type="float" default="0.25">
</argument>
<description>
Inflates or deflates [code]polygon[/code] by [code]delta[/code] units (pixels). If [code]delta[/code] is positive, makes the polygon grow outward. If [code]delta[/code] is negative, shrinks the polygon inward. Returns an array of polygons because inflating/deflating may result in multiple discrete polygons. Returns an empty array if [code]delta[/code] is negative and the absolute value of it approximately exceeds the minimum bounding rectangle dimensions of the polygon.
Each polygon's vertices will be rounded as determined by [code]join_type[/code], see [enum PolyJoinType].
[code]miter_limit[/code] sets the maximum distance in multiples of [code]delta[/code] that vertices can be offset from their original positions before squaring is applied. The default value is 2.0 (twice delta) which is the smallest value that's allowed to avoid generating unacceptably long 'spikes' at very acute angles.
[code]arc_tolerance[/code] sets the maximum distance the flattened path will deviate from the mathematical representation of an arc. Smaller values will increase smoothness at a cost of performance. Only relevant when [code]join_type[/code] is set to [code]JOIN_ROUND[/code].
The operation may result in an outer polygon (boundary) and inner polygon (hole) produced which could be distinguished by calling [method is_polygon_clockwise].
</description>
</method>
Expand All @@ -312,10 +318,13 @@
</argument>
<argument index="3" name="end_type" type="int" enum="Geometry.PolyEndType" default="3">
</argument>
<argument index="4" name="miter_limit" type="float" default="2.0">
</argument>
<description>
Inflates or deflates [code]polyline[/code] by [code]delta[/code] units (pixels), producing polygons. If [code]delta[/code] is positive, makes the polyline grow outward. Returns an array of polygons because inflating/deflating may result in multiple discrete polygons. If [code]delta[/code] is negative, returns an empty array.
Each polygon's vertices will be rounded as determined by [code]join_type[/code], see [enum PolyJoinType].
Each polygon's endpoints will be rounded as determined by [code]end_type[/code], see [enum PolyEndType].
[code]miter_limit[/code] sets the maximum distance in multiples of [code]delta[/code] that vertices can be offset from their original positions before squaring is applied. The default value is 2.0 (twice delta) which is the smallest value that's allowed to avoid generating unacceptably long 'spikes' at very acute angles.
The operation may result in an outer polygon (boundary) and inner polygon (hole) produced which could be distinguished by calling [method is_polygon_clockwise].
</description>
</method>
Expand Down