45 std::optional<int> aTolerance = std::nullopt )
47 const double firstDist = ( aFirst - aPoint ).EuclideanNorm();
48 const double lastDist = ( aLast - aPoint ).EuclideanNorm();
49 const bool useFirst = firstDist <= lastDist;
50 const double dist = useFirst ? firstDist : lastDist;
52 if( aTolerance && dist > *aTolerance )
55 return useFirst ? &aFirst : &aLast;
63 const bool atStart = aPoint == start;
65 if( !atStart && aPoint !=
end )
86 if( ( turn > 0.0 ) == atStart )
107static std::optional<ARC_TANGENT_SEED>
polylineSeedAt( std::span<const VECTOR2I> aVertices,
bool aClosed,
108 const VECTOR2I& aPoint,
int aTolerance )
110 const size_t count = aVertices.size();
120 const VECTOR2I& inner =
end == &aVertices.front() ? aVertices[1] : aVertices[count - 2];
129 const size_t edges = aClosed ? count : count - 1;
130 std::optional<SEG> best;
131 double bestDist = aTolerance;
133 for(
size_t i = 0; i < edges; ++i )
135 const SEG edge( aVertices[i], aVertices[( i + 1 ) % count] );
136 const double dist = edge.
Distance( aPoint );
138 if( dist <= bestDist )
157 const std::array<VECTOR2I, 2> ends{ aSegment.
A, aSegment.
B };
181 std::vector<VECTOR2I> poly;
186 converter.
GetPoly( poly, std::max( 1, aTolerance / 10 ) );
188 std::optional<ARC_TANGENT_SEED> seed =
polylineSeedAt( poly,
false, aPoint, aTolerance );
191 if( seed && !seed->m_directionIsAxis )
193 const bool atStart = seed->m_start == aShape.
GetStart();
199 for(
const VECTOR2I* control : { &firstCtrl, &secondCtrl, &opposite } )
203 seed->m_direction = *dir;
225 if( ( nearest - aPoint ).EuclideanNorm() > aTolerance )
238 std::optional<ARC_TANGENT_SEED> best;
239 double bestDist = 0.0;
242 auto considerContour =
245 std::optional<ARC_TANGENT_SEED> seed =
246 polylineSeedAt( aChain.CPoints(), aChain.IsClosed(), aPoint, aTolerance );
251 double dist = ( seed->m_start - aPoint ).EuclideanNorm();
253 if( !best || dist < bestDist )
260 for(
int outline = 0; outline < poly.
OutlineCount(); ++outline )
262 considerContour( poly.
COutline( outline ) );
264 for(
int hole = 0; hole < poly.
HoleCount( outline ); ++hole )
265 considerContour( poly.
CHole( outline, hole ) );
271 default:
return std::nullopt;
static const VECTOR2I * nearestEnd(const VECTOR2I &aFirst, const VECTOR2I &aLast, const VECTOR2I &aPoint, std::optional< int > aTolerance=std::nullopt)
static std::optional< VECTOR2D > normalized(const VECTOR2D &aVec)
static std::optional< VECTOR2D > tangentAtEndpoint(const EDA_SHAPE &aShape, const VECTOR2I &aPoint)
static std::optional< ARC_TANGENT_SEED > polylineSeedAt(std::span< const VECTOR2I > aVertices, bool aClosed, const VECTOR2I &aPoint, int aTolerance)
std::optional< ARC_TANGENT_SEED > ArcTangentSeedNear(const EDA_SHAPE &aShape, const VECTOR2I &aNear)
Seed the next tangent arc from whichever endpoint of aShape lies nearest aNear.
std::optional< ARC_TANGENT_SEED > ArcTangentSeedAt(const SEG &aSegment, const VECTOR2I &aPoint, int aTolerance)
Tangent seed for a point on or near a segment, arc or Bezier shape.
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr bool Contains(const Vec &aPoint) const
const VECTOR2I & GetBezierC2() const
VECTOR2I getCenter() const
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
const VECTOR2I & GetBezierC1() const
VECTOR2I GetArcMid() const
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
VECTOR2I NearestPoint(const VECTOR2I &aP) const
const VECTOR2I & GetCenter() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Represent a set of closed polygons.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Start point and departure direction that ARC_DRAW_MODE::TANGENT needs to begin an arc.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D