52 const std::function<
void(
const VECTOR2I& a,
const VECTOR2I& b )>& aStroker )
54 double strokes[6] = { aWidth * 1.0, aWidth * 1.0, aWidth * 1.0, aWidth * 1.0, aWidth * 1.0, aWidth * 1.0 };
89 switch( aShape->
Type() )
94 std::set<size_t> arcsHandled;
100 size_t arcIndex = outline.
ArcIndex( ii );
102 if( !arcsHandled.contains( arcIndex ) )
104 arcsHandled.insert( arcIndex );
117 for(
int jj = 0; jj < (int) outline.
ArcCount(); ++jj )
144 double patternLength = 0.0;
146 for(
int ii = 0; ii < wrapAround; ++ii )
147 patternLength += strokes[ii];
150 if( patternLength <= 0.0 )
154 double remaining = strokes[0];
156 for(
int ii = 0; ii <
chain->SegmentCount(); ++ii )
162 if( segLength == 0.0 )
171 while( walked < segLength )
173 double length = std::min( remaining, segLength - walked );
176 if( element % 2 == 0 )
183 if( remaining <= 0.0 )
186 remaining = strokes[element % wrapAround];
203 double theta = atan2(
end.y - start.
y,
end.x - start.
x );
205 for(
size_t i = 0; i < 10000; ++i )
209 VECTOR2D next( start.
x + strokes[ i % wrapAround ] * cos( theta ),
210 start.
y + strokes[ i % wrapAround ] * sin( theta ) );
218 else if( i % 2 == 0 )
232 double C = 2.0 *
M_PI * r;
239 if( arcEndAngle == startAngle )
242 if( startAngle > arcEndAngle )
250 wxASSERT( startAngle < arcEndAngle );
254 for(
size_t i = 0; i < 10000 && startAngle < arcEndAngle; ++i )
257 EDA_ANGLE endAngle = std::min( startAngle + theta, arcEndAngle );
262 && i % wrapAround == 0 )
265 for(
EDA_ANGLE currentAngle = startAngle; currentAngle < endAngle;
266 currentAngle += angleIncrement )
272 EDA_ANGLE nextAngle = currentAngle + angleIncrement;
274 if( nextAngle > endAngle )
276 nextAngle = endAngle;
296 startAngle = endAngle;
310 double cosRot = rotation.
Cos();
311 double sinRot = rotation.
Sin();
316 if( endAngle == startAngle )
319 if( startAngle > endAngle )
327 auto evalRad = [&](
double thetaRad ) ->
VECTOR2D
329 double x = a * std::cos( thetaRad );
330 double y = b * std::sin( thetaRad );
336 double x = a * theta.Cos();
337 double y = b * theta.Sin();
344 const double startRad = startAngle.
AsRadians();
345 const double endRad = endAngle.
AsRadians();
346 const int LUT_SIZE = 1024;
347 std::vector<double> arcLens( LUT_SIZE + 1 );
350 VECTOR2D prev = evalRad( startRad );
352 for(
int j = 1; j <= LUT_SIZE; ++j )
354 double t = startRad + ( endRad - startRad ) * j / LUT_SIZE;
356 arcLens[j] = arcLens[j - 1] + ( curr - prev ).EuclideanNorm();
360 const double totalLen = arcLens[LUT_SIZE];
362 auto angleAtLen = [&](
double s ) ->
double
370 auto it = std::upper_bound( arcLens.begin(), arcLens.end(), s );
371 int idx = std::distance( arcLens.begin(), it ) - 1;
373 double seg = arcLens[idx + 1] - arcLens[idx];
374 double frac = ( seg > 0 ) ? ( s - arcLens[idx] ) / seg : 0.0;
376 double t0 = startRad + ( endRad - startRad ) * idx / LUT_SIZE;
377 double t1 = startRad + ( endRad - startRad ) * ( idx + 1 ) / LUT_SIZE;
379 return t0 + frac * ( t1 - t0 );
383 double currentLen = 0.0;
385 for(
size_t i = 0; i < 10000 && currentLen < totalLen; ++i )
387 double targetLen = std::min( currentLen + strokes[i % wrapAround], totalLen );
394 for(
EDA_ANGLE c = elemStart; c < elemEnd; c += angleIncrement )
396 EDA_ANGLE n = std::min( c + angleIncrement, elemEnd );
397 aStroker( evalAngle( c ), evalAngle( n ) );
401 currentLen = targetLen;