36 if( cornersCount == 0 )
43 if( iterator.IsEndContour() )
48 for(
int i = 0; i < cornersCount - 1; ++i )
56 std::make_unique<POLYGON_EDGE_DRAG_POLICY>( aPoints.
Line( i ), aPoints ) );
96 for(
unsigned i = 0; i < aPoints.
LinesSize(); ++i )
100 std::make_unique<POLYGON_EDGE_DRAG_POLICY>( aPoints.
Line( i ), aPoints ) );
141 std::vector<EDA_ITEM*>& aUpdatedItems )
210 std::vector<EDA_ITEM*>& aUpdatedItems )
225 const double len = std::sqrt(
double( v.
x ) * v.
x +
double( v.
y ) * v.
y );
237 const double proj = -v.
x * rotation.
Sin() + v.
y * rotation.
Cos();
247 while( ( rawAngle - prevStart ).AsDegrees() > 180.0 )
249 while( ( prevStart - rawAngle ).AsDegrees() > 180.0 )
252 m_ellipse.SetEllipseStartAngle( rawAngle );
260 while( ( rawAngle - prevEnd ).AsDegrees() > 180.0 )
262 while( ( prevEnd - rawAngle ).AsDegrees() > 180.0 )
265 m_ellipse.SetEllipseEndAngle( rawAngle );
297 std::vector<EDA_ITEM*>& aUpdatedItems )
343 COMMIT& aCommit, std::vector<EDA_ITEM*>& aUpdatedItems )
379 bool arcValid =
true;
391 else if( aEnd != aArc.
GetEnd() )
413 if( (
v1.EuclideanNorm() == 0 ) || (
v2.EuclideanNorm() == 0 ) )
416 u1 =
v1 /
v1.EuclideanNorm();
417 u2 =
v3 - ( u1.
x *
v3.x + u1.
y *
v3.y ) * u1;
426 double det = u1.
x * u2.
y - u2.
x * u1.
y;
433 double tmpx =
v1.x * u2.
y -
v1.y * u2.
x;
434 double tmpy = -
v1.x * u1.
y +
v1.y * u1.
x;
439 tmpx =
v2.x * u2.
y -
v2.y * u2.
x;
440 tmpy = -
v2.x * u1.
y +
v2.y * u1.
x;
445 double R =
v1.EuclideanNorm();
446 bool transformCircle =
false;
483 transformCircle =
true;
488 double delta = ( R * R -
v2.x *
v2.x -
v2.y *
v2.y ) / ( 2 *
v2.x - 2 * R );
495 if( !std::isfinite(
delta ) )
501 tmpx =
v4.x * u1.
x +
v4.y * u2.
x;
502 tmpy =
v4.x * u1.
y +
v4.y * u2.
y;
527 const int c_snapEpsilon_sq = 4;
529 VECTOR2I m = ( aStart / 2 + aEnd / 2 );
530 VECTOR2I perp = ( aEnd - aStart ).Perpendicular().Resize( INT_MAX / 2 );
532 SEG legal( m - perp, m + perp );
534 const SEG testSegments[] = {
539 std::vector<VECTOR2I> points = { legal.
A, legal.
B };
541 for(
const SEG& seg : testSegments )
546 points.push_back( *vec );
555 SEG::ecoord d_sq = ( pt - aCenter ).SquaredEuclideanNorm();
557 if( d_sq < min_d_sq - c_snapEpsilon_sq )
604 if( p1.
x == 0 && p1.
y == 0 )
605 p1 = prev_p1 - aCenter;
607 if( p2.
x == 0 && p2.
y == 0 )
637 bool movingStart =
false;
684 double radius = ( aCursor - aCenter ).EuclideanNorm();
692 start = start + aCenter;
711 const int JUST_OFF = ( aStart - aEnd ).EuclideanNorm() / 100;
758 std::vector<EDA_ITEM*>& aUpdatedItems )
781 m_arc.SetArcGeometry(
m_arc.GetStart() + moveVector,
m_arc.GetArcMid() + moveVector,
782 m_arc.GetEnd() + moveVector );
883 const int handleLength = localOffset.
y +
KiROUND(
m_image.GetSize().y * 0.7 );
895 COMMIT& aCommit, std::vector<EDA_ITEM*>& aUpdatedItems )
909 m_image.SetTransformOriginOffset( xfrmOrigin - ( topLeft + botRight ) / 2 );
918 const double angle = std::atan2( -cursorVec.
y, cursorVec.
x );
938 oldCorner -= oldSize / 2;
942 newCorner = topRight;
943 oldCorner -=
VECTOR2I( -oldSize.
x, oldSize.
y ) / 2;
948 oldCorner -=
VECTOR2I( oldSize.
x, -oldSize.
y ) / 2;
952 newCorner = botRight;
953 oldCorner += oldSize / 2;
960 *newCorner -= xfrmOrigin;
961 oldCorner -= oldOrigin;
964 if(
sign( newCorner->x ) !=
sign( oldCorner.
x ) ||
sign( newCorner->y ) !=
sign( oldCorner.
y ) )
967 const double newLength = newCorner->EuclideanNorm();
970 double ratio = oldLength > 0 ? ( newLength / oldLength ) : 1.0;
973 const VECTOR2I newSize = oldSize * ratio;
974 const double newWidth = std::max( newSize.
x,
m_minSize );
975 const double newHeight = std::max( newSize.
y,
m_minSize );
976 ratio = std::min( newWidth / oldSize.
x, newHeight / oldSize.
y );
994 wxFAIL_MSG(
"Invalid arc edit mode" );
ARC_EDIT_MODE
Settings for arc editing.
@ KEEP_ENDPOINTS_OR_START_DIRECTION
Whe editing endpoints, the other end remains in place.
@ KEEP_CENTER_ENDS_ADJUST_ANGLE
When editing endpoints, only the angle is adjusted.
@ KEEP_CENTER_ADJUST_ANGLE_RADIUS
When editing endpoints, the angle and radius are adjusted.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Represent a set of changes (additions, deletions or modifications) of a data model (e....
EDA_ARC_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aArc, const ARC_EDIT_MODE &aArcEditMode, KIGFX::VIEW_CONTROLS &aViewContols, const EDA_IU_SCALE &aIuScale)
const ARC_EDIT_MODE & m_arcEditMode
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
KIGFX::VIEW_CONTROLS & m_viewControls
const EDA_IU_SCALE & m_iuScale
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
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_ANGLE parametricAngleOf(const VECTOR2I &aWorldPt) const
Inverse: the parametric angle of a world-space point relative to this ellipse.
VECTOR2I evaluateAt(const EDA_ANGLE &aTheta) const
World-space point on the ellipse at the given parametric angle.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
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.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
virtual void SetEnd(const VECTOR2I &aEnd)
virtual void SetCenter(const VECTOR2I &aCenter)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
virtual void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
virtual void SetStart(const VECTOR2I &aStart)
VECTOR2I GetArcMid() const
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.
void SetDragPolicy(std::unique_ptr< POLYGON_EDGE_DRAG_POLICY > aPolicy)
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.
void AddPoint(const EDIT_POINT &aPoint)
Add an EDIT_POINT.
void Clear()
Clear all stored EDIT_POINTs and EDIT_LINEs.
EDIT_POINT * Next(const EDIT_POINT &aPoint, bool aTraverseContours=true)
Return the point that is before the given point in the list.
EDIT_LINE & Line(unsigned int aIndex)
bool IsContourEnd(int aPointIdx) const
Check is a point with given index is a contour finish.
void AddIndicatorLine(EDIT_POINT &aOrigin, EDIT_POINT &aEnd)
Adds an EDIT_LINE that is shown as an indicator, rather than an editable line (no center point drag,...
void AddBreak()
Adds a break, indicating the end of a contour.
int GetContourStartIdx(int aPointIdx) const
Return index of the contour origin for a point with given index.
unsigned int LinesSize() const
Return number of stored EDIT_LINEs.
EDIT_POINT & Point(unsigned int aIndex)
void AddLine(const EDIT_LINE &aLine)
Adds an EDIT_LINE.
Represent a single point that can be used for modifying items.
virtual void SetPosition(const VECTOR2I &aPosition)
Set new coordinates for an EDIT_POINT.
virtual VECTOR2I GetPosition() const
Return coordinates of an EDIT_POINT.
Plain ellipse / elliptical-arc data.
VECTOR2< NumericType > GetPointAtAngle(EDA_ANGLE angle) const
Get the point on the ellipse at a given angle.
EDA_ANGLE GetAngleAtPoint(const VECTOR2< NumericType > &aPt) const
Get the parametric angle of a point on the ellipse.
VECTOR2< NumericType > Center
An interface for classes handling user events controlling the view behavior such as zooming,...
static bool isModified(const EDIT_POINT &aEditedPoint, const EDIT_POINT &aPoint)
Checks if two points are the same instance - which means the point is being edited.
static void UpdateOutlineFromPoints(SHAPE_POLY_SET &aOutline, const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints)
Update the polygon outline with the new positions of the edit points.
SHAPE_POLY_SET & m_polygon
static void UpdatePointsFromOutline(const SHAPE_POLY_SET &aOutline, EDIT_POINTS &aPoints)
Update the edit points with the current polygon outline.
void FinalizeItem(EDIT_POINTS &aPoints, COMMIT &aCommit) override
Finalize the edit operation.
static void BuildForPolyOutline(EDIT_POINTS &aPoints, const SHAPE_POLY_SET &aOutline)
Build the edit points for the given polygon outline.
static void RemoveNullSegmentsIfPolygonSurvives(SHAPE_POLY_SET &aOutline)
Remove the zero length segments left by an edit, unless that would strip the outline down to somethin...
REFERENCE_IMAGE & m_image
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
ecoord SquaredDistance(const SEG &aSeg) const
VECTOR2I::extended_type ecoord
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Represent a set of closed polygons.
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
int TotalVertices() const
Return total number of vertices stored in the set.
int RemoveNullSegments()
Look for null segments; ie, segments whose ends are exactly the same and deletes them.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
CONST_ITERATOR CIterateWithHoles(int aOutline) const
Define a general 2D-vector/point.
static constexpr extended_type ECOORD_MAX
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_360
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
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.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
static void editArcEndpointKeepCenterAndRadius(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
ARC_EDIT_MODE IncrementArcEditMode(ARC_EDIT_MODE aMode)
static void editArcCenterKeepEndpoints(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Move the arc center but keep endpoint locations.
static void editArcMidKeepEndpoints(EDA_SHAPE &aArc, const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCursor)
Move the mid point of the arc, while keeping the angle.
static void editArcEndpointKeepTangent(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor)
Move an end point of the arc, while keeping the tangent at the other endpoint.
#define CHECK_POINT_COUNT(aPoints, aExpected)
#define CHECK_POINT_COUNT_GE(aPoints, aExpected)
std::optional< VECTOR2I > OPT_VECTOR2I
VECTOR3I expected(15, 30, 45)
static double sweep(float aStart, float aEnd)
VECTOR2I GetRotated(const VECTOR2I &aVector, const EDA_ANGLE &aAngle)
Return a new VECTOR2I that is the result of rotating aVector by aAngle.
bool IsStraightArc(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
constexpr int sign(T val)
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D