46 BOOST_CHECK_SMALL( aActual.
x - aExpected.
x, aTolerance );
47 BOOST_CHECK_SMALL( aActual.
y - aExpected.
y, aTolerance );
60 BOOST_CHECK_SMALL( aActual.
AsDegrees() - aExpectedDegrees, aTolerance );
66 BOOST_CHECK_MESSAGE( aActual.
AsDegrees() > aMinDegrees && aActual.
AsDegrees() < aMaxDegrees,
67 "Expected angle " << aActual.
AsDegrees() <<
" to be between " << aMinDegrees <<
" and "
74 for(
SHAPE* shape : aShapes )
95 "Issue 13626: clockwise semicircle",
96 {-428880000, 117229160 },
97 {-430060565, 113472820 },
99 {-431241130, 109716480 },
103 "Issue 13626: anticlockwise arc",
104 { -431241130, 109716480 },
105 { -434923630, 112954230 },
107 { -439827050, 112936200 },
117 BOOST_TEST_INFO_SCOPE( c.m_CaseName );
154 "Issue 15694: clockwise arc",
165 "Issue 15694: anticlockwise arc",
179 const double angle_tol = 0.1;
183 BOOST_TEST_INFO_SCOPE( c.m_CaseName );
213 ( angle.
AsDegrees() )( c.m_ExpectedAngleAfterSwapDeg )( 360.0 )( angle_tol ) );
226 const VECTOR2I mid( 6000000, 8000000 );
228 for(
bool swap : {
false,
true } )
230 BOOST_TEST_INFO_SCOPE( (
swap ?
"swapped" :
"unswapped" ) );
277 arc2.SetArcGeometry( start, mid,
end );
298 poly.
Append( { 1000000, 0 } );
299 poly.
Append( { 1000000, 1000000 } );
327 poly.
Append( { 1000000, 0 } );
328 poly.
Append( { 1000000, 1000000 } );
329 poly.
Append( { 0, 1000000 } );
339 shape.
SetEnd( { 1000000, 1000000 } );
356 poly.
Append( { 1000, 0 } );
357 poly.
Append( { 1000, 1000 } );
360 poly.
Append( { 5000, 5000 } );
361 poly.
Append( { 6000, 5000 } );
363 const std::vector<VECTOR2I>
expected = {
364 { 0, 0 }, { 1000, 0 }, { 1000, 1000 }, { 5000, 5000 }, { 6000, 5000 }
369 BOOST_REQUIRE_EQUAL( points.size(),
expected.size() );
371 for(
size_t ii = 0; ii <
expected.size(); ++ii )
448 BOOST_CHECK( !shapes.empty() );
450 for(
SHAPE* s : shapes )
504 shape.
SetEnd( { 1000, 0 } );
521 shape.
SetEnd( { 1000, 1000 } );
545 segment.
SetEnd( { 100, 20 } );
552 arc.SetStart( { 10, 0 } );
553 arc.SetEnd( { 20, 30 } );
555 BOOST_CHECK( arc.GetLineEndingEndpoints( start,
end ) );
560 bezier.SetStart( { 0, 0 } );
561 bezier.SetBezierC1( { 20, 0 } );
562 bezier.SetBezierC2( { 80, 100 } );
563 bezier.SetEnd( { 100, 100 } );
564 bezier.RebuildBezierToSegmentsPointsList( 1 );
566 BOOST_CHECK( bezier.GetLineEndingEndpoints( start,
end ) );
575 poly.
Append( { 50, 10 } );
576 poly.
Append( { 100, 20 } );
577 polyShape.SetPolyShape( poly );
579 BOOST_CHECK( polyShape.GetLineEndingEndpoints( start,
end ) );
607 shape.
SetEnd( { 1000, 0 } );
614 BOOST_REQUIRE_EQUAL( shapes.size(), 1 );
616 BOX2I bbox = shapes[0]->BBox();
617 BOOST_CHECK( bbox.
GetLeft() <= 800 );
618 BOOST_CHECK( bbox.
GetRight() >= 1200 );
619 BOOST_CHECK( bbox.
GetTop() <= -200 );
630 shape.
SetEnd( { 1000, 0 } );
638 BOOST_REQUIRE_EQUAL( shapes.size(), 2 );
640 for(
SHAPE* shapePtr : shapes )
655 shape.
SetEnd( { 1000, 0 } );
663 BOOST_CHECK( bbox.
GetLeft() <= 800 );
664 BOOST_CHECK( bbox.
GetRight() >= 1200 );
665 BOOST_CHECK( bbox.
GetTop() <= -200 );
674 shape.
SetEnd( { 1000, 1000 } );
682 BOOST_CHECK( bbox.
GetLeft() <= 718 );
683 BOOST_CHECK( bbox.
GetRight() >= 1282 );
684 BOOST_CHECK( bbox.
GetTop() <= 718 );
693 shape.
SetEnd( { 1000, 0 } );
719 shape.
SetEnd( { 1000, 0 } );
728 for(
SHAPE* shapePtr : shapes )
749 shape.
SetEnd( { 1000, 0 } );
757 BOOST_REQUIRE_EQUAL( shapes.size(), 1 );
772 shape.
SetEnd( { 1000, 0 } );
783 BOOST_CHECK( shapes.empty() );
793 shape.
SetEnd( { 1000, 0 } );
801 bool collides =
false;
803 for(
SHAPE* shapePtr : shapes )
805 if( shapePtr->Collide( probe.
GetSeg(), 0 ) )
812 BOOST_CHECK( collides );
822 shape.
SetEnd( { 1000, 0 } );
835 BOOST_CHECK_GT( unshortenedBodyPlusEnding.
BBox().
GetRight(), 1000 );
836 BOOST_CHECK_LE( shortenedBodyPlusEnding.
BBox().
GetRight(), 1001 );
852 constexpr double radius = 1000.0;
853 constexpr double radToDeg = 180.0 /
M_PI;
858 BOOST_CHECK( arcAngle >
ANGLE_0 );
874 constexpr double radius = 1000.0;
875 constexpr double radToDeg = 180.0 /
M_PI;
880 BOOST_CHECK( arcAngle <
ANGLE_0 );
909 shape.
SetEnd( { 1000, 0 } );
927 shape.
SetEnd( { 1000, 0 } );
949 shape.
SetEnd( { 1000, 0 } );
967 shape.
SetEnd( { 1000, 0 } );
977 BOOST_REQUIRE_GE( points.size(), 2 );
989 shape.
SetEnd( { 1000, 0 } );
1028 shape.
SetEnd( { 100000, 0 } );
1040 BOOST_REQUIRE_EQUAL( shapes.size(), 1 );
1044 BOOST_REQUIRE_GE(
chain->SegmentCount(), 2 );
1046 double chainLength = 0.0;
1048 for(
int ii = 0; ii <
chain->SegmentCount(); ++ii )
1054 std::vector<SEG> pieces;
1059 pieces.emplace_back( a, b );
1062 std::vector<double> runs;
1065 for(
size_t ii = 0; ii < pieces.size(); )
1071 while( jj < pieces.size() && pieces[jj].A ==
end )
1078 runs.push_back( length );
1083 BOOST_REQUIRE_MESSAGE( runs.size() > 5,
"expected many dashes, got " << runs.size() <<
" run(s)" );
1089 double expected = chainLength * dash / ( dash + gap );
1092 "dashes should cover " <<
expected <<
" IU of the " << chainLength
1093 <<
" IU shortened body, they cover " << drawn );
1111 VECTOR2D penultimate( 1000, 1000 );
1130 VECTOR2D penultimate( 1000, 1000 );
1171 std::vector<VECTOR2I> pts;
1174 BOOST_REQUIRE_EQUAL( pts.size(), 3 );
1179 BOOST_REQUIRE_EQUAL( pts.size(), 3 );
1186 BOOST_REQUIRE_EQUAL( pts.size(), 3 );
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
constexpr coord_type GetLeft() const
constexpr coord_type GetRight() const
constexpr coord_type GetTop() const
constexpr coord_type GetBottom() const
"Standard" polygon editing behavior for EDA_SHAPE polygons.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
EDA_SHAPE_MOCK(SHAPE_T aShapeType)
static bool ShortenSegmentForEndings(VECTOR2I &aStart, VECTOR2I &aEnd, const LINE_ENDING &aStartEnding, const LINE_ENDING &aEndEnding, int aLineWidth)
Shorten a segment body for line endings.
EDA_ANGLE GetArcAngle() const
virtual void SetEnd(const VECTOR2I &aEnd)
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false, bool includeFill=false) const
Convert the shape to a closed polygon.
int GetEllipseMinorRadius() const
const VECTOR2I & GetEllipseCenter() const
bool GetLineEndingsBoundingBox(BOX2I &aBBox, int aLineWidth) const
void SetCenter(const VECTOR2I &aCenter)
VECTOR2I getCenter() const
std::vector< SHAPE * > MakeEffectiveShapesWithLineEndings(int aLineWidth) const
Make effective geometry for the shape body shortened for line endings plus the line-ending geometry i...
void SetEndEndingLength(int aLength)
void SetStartEndingStyle(LINE_ENDING_STYLE aStyle)
EDA_ANGLE GetEllipseEndAngle() const
void SetEndEndingWidth(int aWidth)
int GetEllipseMajorRadius() const
std::vector< VECTOR2I > GetPolyPoints() const
Duplicate the polygon outlines into a flat list of VECTOR2I points.
void TransformWithLineEndingsToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the shape body shortened for line endings plus line-ending geometry to polygons.
void TransformLineEndingsToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, int aLineWidth) const
Append only the line-ending geometry associated with this shape to a polygon set.
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
bool ShortenPolyForEndings(VECTOR2D &aFirst, VECTOR2D &aLast, const VECTOR2D &aSecond, const VECTOR2D &aPenultimate, int aLineWidth) const
SHAPE_POLY_SET & GetPolyShape()
void GetEndingTangents(EDA_ANGLE &aStartTangent, EDA_ANGLE &aEndTangent, int aLineWidth=0) const
Compute outward-facing tangent angles at the start and end of the shape.
EDA_ANGLE GetEllipseRotation() const
void SetEndEndingStyle(LINE_ENDING_STYLE aStyle)
virtual void SetEllipseEndAngle(const EDA_ANGLE &aA)
std::vector< SHAPE * > MakeEffectiveShapesForStroking(int aLineWidth=-1) const
Make a set of SHAPE objects to hand to STROKE_PARAMS::Stroke().
virtual void SetBezierC2(const VECTOR2I &aPt)
bool GetShortenedBodyPolyPoints(const SHAPE_LINE_CHAIN &aOutline, int aOutlineIdx, std::vector< VECTOR2I > &aPoints, int aLineWidth) const
Copy an outline and apply line-ending body shortening when applicable.
virtual void SetBezierC1(const VECTOR2I &aPt)
bool GetLineEndingEndpoints(VECTOR2I &aStartPoint, VECTOR2I &aEndPoint) const
Return the source endpoints used to place line endings.
virtual void SetEllipseRotation(const EDA_ANGLE &aA)
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
virtual void SetEllipseCenter(const VECTOR2I &aPt)
void SetStartEndingLength(int aLength)
void SetEndEndingStrokeWidth(int aWidth)
virtual void SetEllipseMinorRadius(int aR)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
virtual void SetEllipseMajorRadius(int aR)
virtual void SetShape(SHAPE_T aShape)
std::vector< SHAPE * > MakeLineEndingEffectiveShapes(int aLineWidth) const
Make the line-ending geometry associated with this shape.
void SetStartEndingWidth(int aWidth)
EDA_ANGLE GetEllipseStartAngle() const
bool EndsSwapped() const
Have the start and end points been swapped since they were set?
virtual void SetEllipseStartAngle(const EDA_ANGLE &aA)
virtual void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
std::optional< BEZIER< double > > ShortenedBezierCurve(int aLineWidth) const
Return the cubic Bezier curve shortened for line endings.
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
virtual int GetWidth() const
bool ShortenArcForEndings(EDA_ANGLE &aStartAngle, EDA_ANGLE &aArcAngle, double aRadius, int aLineWidth) const
Shorten an arc body for line endings.
std::vector< VECTOR2D > ShortenedBezierPolyline(int aLineWidth) const
Return the flattened Bezier polyline after line-ending shortening.
virtual void SetWidth(int aWidth)
virtual void SetPolyShape(const SHAPE_POLY_SET &aShape)
virtual void SetStart(const VECTOR2I &aStart)
VECTOR2I GetArcMid() const
EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
unsigned int PointsSize() const
Return number of stored EDIT_POINTs.
A color representation with 4 components: red, green, blue, alpha.
static const COLOR4D BLACK
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
double GetGapLength(int aLineWidth) const
double GetDashLength(int aLineWidth) const
An abstract base class for deriving all objects that can be added to a VIEW.
Decorative shape (arrowhead, circle, square) at the start or end of a graphic line,...
static int DefaultAccuracyForPCB()
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
const SEG & GetSeg() const
VECTOR2I GetEnd() const override
VECTOR2I GetStart() const override
int GetWidth() const override
An abstract shape on 2D plane.
static void Stroke(const SHAPE *aShape, LINE_STYLE aLineStyle, int aWidth, const KIGFX::RENDER_SETTINGS *aRenderSettings, const std::function< void(const VECTOR2I &a, const VECTOR2I &b)> &aStroker)
const KIGFX::COLOR4D & GetGridColor() override
Return current grid color settings.
KIGFX::COLOR4D GetColor(const KIGFX::VIEW_ITEM *aItem, int aLayer) const override
Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer using curr...
void SetBackgroundColor(const KIGFX::COLOR4D &aColor) override
Set the background color.
const KIGFX::COLOR4D & GetBackgroundColor() const override
Return current background color settings.
const KIGFX::COLOR4D & GetCursorColor() override
Return current cursor color settings.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
static constexpr EDA_ANGLE ANGLE_0
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
void EditArcEndpointKeepCenter(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor, const EDA_IU_SCALE &aIuScale)
Move an arc endpoint around the existing center, pulling the opposite endpoint along to keep the radi...
void EditArcMidKeepCenter(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor, const EDA_IU_SCALE &aIuScale)
Move the mid point of an arc while keeping the center, rotating the endpoints onto the new radius.
bool IsWithinWrapped(T aValue, T aNominal, T aWrap, T aError)
Check if a value is within a tolerance of a nominal value, wrapping to a given val.
bool IsWithin(T aValue, T aNominal, T aError)
Check if a value is within a tolerance of a nominal value.
bool IsVecWithinTol(const VEC &aVec, const VEC &aExp, typename VEC::coord_type aTol)
Check that both x and y of a vector are within expected error.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
bool m_ExpectedStartEndSwapped
VECTOR2I m_ExpectedEndBeforeSwap
bool m_ExpectedStartEndSwapped
VECTOR2I m_ExpectedCenter
double m_ExpectedAngleAfterSwapDeg
VECTOR2I m_ExpectedEndAfterSwap
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static void deleteShapes(std::vector< SHAPE * > &aShapes)
static void checkAngleClose(const EDA_ANGLE &aActual, double aExpectedDegrees, double aTolerance=1e-6)
static void checkAngleInRange(const EDA_ANGLE &aActual, double aMinDegrees, double aMaxDegrees)
static void checkVectorClose(const VECTOR2D &aActual, const VECTOR2D &aExpected, double aTolerance=1e-6)
static const std::vector< SET_ARC_GEOMETRY_CASE > set_arc_geometry_cases
BOOST_AUTO_TEST_CASE(SetAngleAndEnd)
static void checkVectorEqual(const VECTOR2I &aActual, const VECTOR2I &aExpected)
static const std::vector< SET_ANGLE_END_CASE > set_angle_end_cases
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
SHAPE_ARC arc2(c.m_arc2.GenerateArc())
const SHAPE_LINE_CHAIN chain
BOOST_CHECK_PREDICATE(ArePolylineEndPointsNearCircle,(chain)(c.m_geom.m_center_point)(radius)(accuracy+epsilon))
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D