84 double turn = std::atan2( (
double) aPoint.
y -
m_Circle.Center.y, (
double) aPoint.
x -
m_Circle.Center.x );
87 turn += 2.0 * std::numbers::pi;
89 return turn / ( 2.0 * std::numbers::pi );
105 return std::clamp(
Parameter( aPointer ), 0.0, 1.0 );
110 double aToParameter )
const
134 double sweep = aToParameter - aFromParameter;
139 double middle = ( aFromParameter + sweep / 2.0 ) * 2.0 * std::numbers::pi;
168 if( corners.size() != 4 )
176 std::vector<SEG> sides;
178 for(
size_t i = 0; i < corners.size(); i++ )
179 sides.emplace_back( corners[i], corners[( i + 1 ) % corners.size()] );
181 auto nearest = std::ranges::min_element( sides,
182 [&](
const SEG& aA,
const SEG& aB )
189 aCarrier.
m_Seg = *nearest;
194 for(
const SEG& side : sides )
196 if( &side != &*nearest )
233 const std::vector<const BOARD_ITEM*>& aBoundaries )
246 result.m_Refusal = refusal;
250 std::vector<TRIM_CUT> cuts;
251 bool touched =
false;
252 bool overlapped =
false;
263 if( !boundaryGeometry )
266 std::vector<VECTOR2I> intersections;
278 for(
const VECTOR2I& point : intersections )
282 double parameter = carrier.
Parameter( point );
288 auto duplicate = std::find_if( cuts.begin(), cuts.end(),
291 return GraphicEditCoincident( aCut.m_Point, point );
295 cuts.push_back( { parameter, point, item } );
307 if( carrier.
IsClosed() && cuts.size() < 2 )
333 auto next = std::ranges::find_if( cuts,
339 after =
next == cuts.end() ? &cuts.front() : &*
next;
340 before =
next == cuts.begin() ||
next == cuts.end() ? &cuts.back() : &*(
next - 1 );
346 if(
cut.m_Parameter < pointerParameter )
356 const double removedFromParameter = before ? before->
m_Parameter : 0.0;
357 const double removedToParameter = after ? after->
m_Parameter : 1.0;
359 result.m_Preview.push_back(
360 carrier.
Span( removedFrom, removedTo, removedFromParameter, removedToParameter ) );
365 result.m_Geometry.push_back(
366 carrier.
Span( removedTo, removedFrom, removedToParameter, removedFromParameter ) );
385 result.m_Geometry.push_back( kept );
std::optional< INTERSECTABLE_GEOM > BoardItemIntersectable(const BOARD_ITEM &aItem)
The kimath primitive a board item is made of.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Represent basic circle geometry with utility geometry functions.
int Radius
Public to make access simpler.
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
std::vector< VECTOR2I > GetRectCorners() const
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
ecoord SquaredDistance(const SEG &aSeg) const
EDA_ANGLE GetCentralAngle() const
Get the "central angle" of the arc - this is the angle at the point of the "pie slice".
const VECTOR2I & GetArcMid() const
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
const VECTOR2I & GetCenter() const
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
SHAPE_ARC GraphicEditArc(const PCB_SHAPE &aShape)
bool IsGraphicEditArcUsable(const SHAPE_ARC &aArc)
False for radii and sweeps the planners refuse. Check before planning an arc.
bool IsGraphicTrimSource(const PCB_SHAPE &aShape)
Trim also takes the closed shapes, which it opens up.
const PCB_SHAPE * GraphicEditBoundary(const BOARD_ITEM *aBoundary, const PCB_SHAPE &aSource)
A boundary usable against aSource. Null if it is the source, off-layer or unusable.
const PCB_SHAPE * GraphicEditSource(const BOARD_ITEM &aSource, bool(*aAccepts)(const PCB_SHAPE &), GRAPHIC_EDIT_RESULT &aResult)
The shape to edit, or null with the reason in aResult. aAccepts decides the kinds.
bool GraphicEditCoincident(const VECTOR2I &aA, const VECTOR2I &aB)
Points built by different routes land a rounding step apart.
GRAPHIC_EDIT_REFUSAL
Why a planner refused. Each one gets its own message.
constexpr int MAX_GRAPHIC_EDIT_ARC_RADIUS
Larger arcs overflow the boundary search box.
static GRAPHIC_EDIT_REFUSAL buildCarrier(const PCB_SHAPE &aSource, const VECTOR2I &aPointer, TRIM_CARRIER &aCarrier)
Fills aCarrier from aSource, or returns the reason it cannot.
static double arcParameter(const SHAPE_ARC &aSource, const VECTOR2I &aPoint)
static constexpr double PARAM_EPSILON
A fraction of the carrier's own length. Same meaning at every scale.
std::variant< LINE, HALF_LINE, SEG, CIRCLE, SHAPE_ARC, SHAPE_ELLIPSE, BOX2I > INTERSECTABLE_GEOM
A variant type that can hold any of the supported geometry types for intersection calculations.
GRAPHIC_EDIT_RESULT Plan(const BOARD_ITEM &aSource, const VECTOR2I &aPointer, const std::vector< const BOARD_ITEM * > &aBoundaries)
Plan removal of the part of aSource under aPointer.
double ParameterAlong(const SEG &aSeg, const VECTOR2I &aPoint)
Position of a point along a segment.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Utility functions for working with shapes.
SHAPE_T m_Shape
A result need not be the same kind as the source.
VECTOR2I m_Mid
Arcs only. Everything else leaves it default.
A visitor that visits INTERSECTABLE_GEOM variant objects with another (which is held as state: m_othe...
The one curve the pointer is trimming.
double Parameter(const VECTOR2I &aPoint) const
double PointerParameter(const VECTOR2I &aPointer) const
Where the pointer sits, brought onto the carrier.
std::vector< SEG > m_Untouched
GRAPHIC_EDIT_GEOMETRY Span(const VECTOR2I &aFrom, const VECTOR2I &aTo, double aFromParameter, double aToParameter) const
The piece of the carrier running forward from aFrom to aTo.
INTERSECTABLE_GEOM m_Geometry
const BOARD_ITEM * m_Boundary
wxString result
Test unit parsing edge cases and error handling.
VECTOR2< int32_t > VECTOR2I