53 const std::function<
void(
const VECTOR2I& a,
const VECTOR2I& b )>& aStroker )
55 double strokes[6] = { aWidth * 1.0, aWidth * 1.0, aWidth * 1.0, aWidth * 1.0, aWidth * 1.0, aWidth * 1.0 };
90 switch( aShape->
Type() )
95 std::set<size_t> arcsHandled;
101 size_t arcIndex = outline.
ArcIndex( ii );
103 if( !arcsHandled.contains( arcIndex ) )
105 arcsHandled.insert( arcIndex );
118 for(
int jj = 0; jj < (int) outline.
ArcCount(); ++jj )
145 double patternLength = 0.0;
147 for(
int ii = 0; ii < wrapAround; ++ii )
148 patternLength += strokes[ii];
151 if( patternLength <= 0.0 )
155 double remaining = strokes[0];
157 for(
int ii = 0; ii <
chain->SegmentCount(); ++ii )
163 if( segLength == 0.0 )
172 while( walked < segLength )
174 double length = std::min( remaining, segLength - walked );
177 if( element % 2 == 0 )
184 if( remaining <= 0.0 )
187 remaining = strokes[element % wrapAround];
204 double theta = atan2(
end.y - start.
y,
end.x - start.
x );
206 for(
size_t i = 0; i < 10000; ++i )
210 VECTOR2D next( start.
x + strokes[ i % wrapAround ] * cos( theta ),
211 start.
y + strokes[ i % wrapAround ] * sin( theta ) );
219 else if( i % 2 == 0 )
233 double C = 2.0 *
M_PI * r;
240 if( arcEndAngle == startAngle )
243 if( startAngle > arcEndAngle )
251 wxASSERT( startAngle < arcEndAngle );
255 for(
size_t i = 0; i < 10000 && startAngle < arcEndAngle; ++i )
258 EDA_ANGLE endAngle = std::min( startAngle + theta, arcEndAngle );
263 && i % wrapAround == 0 )
266 for(
EDA_ANGLE currentAngle = startAngle; currentAngle < endAngle;
267 currentAngle += angleIncrement )
273 EDA_ANGLE nextAngle = currentAngle + angleIncrement;
275 if( nextAngle > endAngle )
277 nextAngle = endAngle;
297 startAngle = endAngle;
311 double cosRot = rotation.
Cos();
312 double sinRot = rotation.
Sin();
317 if( endAngle == startAngle )
320 if( startAngle > endAngle )
328 auto evalRad = [&](
double thetaRad ) ->
VECTOR2D
330 double x = a * std::cos( thetaRad );
331 double y = b * std::sin( thetaRad );
337 double x = a * theta.Cos();
338 double y = b * theta.Sin();
345 const double startRad = startAngle.
AsRadians();
346 const double endRad = endAngle.
AsRadians();
347 const int LUT_SIZE = 1024;
348 std::vector<double> arcLens( LUT_SIZE + 1 );
351 VECTOR2D prev = evalRad( startRad );
353 for(
int j = 1; j <= LUT_SIZE; ++j )
355 double t = startRad + ( endRad - startRad ) * j / LUT_SIZE;
357 arcLens[j] = arcLens[j - 1] + ( curr - prev ).EuclideanNorm();
361 const double totalLen = arcLens[LUT_SIZE];
363 auto angleAtLen = [&](
double s ) ->
double
371 auto it = std::upper_bound( arcLens.begin(), arcLens.end(), s );
372 int idx = std::distance( arcLens.begin(), it ) - 1;
374 double seg = arcLens[idx + 1] - arcLens[idx];
375 double frac = ( seg > 0 ) ? ( s - arcLens[idx] ) / seg : 0.0;
377 double t0 = startRad + ( endRad - startRad ) * idx / LUT_SIZE;
378 double t1 = startRad + ( endRad - startRad ) * ( idx + 1 ) / LUT_SIZE;
380 return t0 + frac * ( t1 - t0 );
384 double currentLen = 0.0;
386 for(
size_t i = 0; i < 10000 && currentLen < totalLen; ++i )
388 double targetLen = std::min( currentLen + strokes[i % wrapAround], totalLen );
395 for(
EDA_ANGLE c = elemStart; c < elemEnd; c += angleIncrement )
397 EDA_ANGLE n = std::min( c + angleIncrement, elemEnd );
398 aStroker( evalAngle( c ), evalAngle( n ) );
402 currentLen = targetLen;