51 const std::function<
void(
const VECTOR2I& a,
54 double strokes[6] = { 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 )
150 double theta = atan2(
end.y - start.
y,
end.x - start.
x );
152 for(
size_t i = 0; i < 10000; ++i )
156 VECTOR2D next( start.
x + strokes[ i % wrapAround ] * cos( theta ),
157 start.
y + strokes[ i % wrapAround ] * sin( theta ) );
165 else if( i % 2 == 0 )
179 double C = 2.0 *
M_PI * r;
186 if( arcEndAngle == startAngle )
189 if( startAngle > arcEndAngle )
197 wxASSERT( startAngle < arcEndAngle );
201 for(
size_t i = 0; i < 10000 && startAngle < arcEndAngle; ++i )
204 EDA_ANGLE endAngle = std::min( startAngle + theta, arcEndAngle );
209 && i % wrapAround == 0 )
212 for(
EDA_ANGLE currentAngle = startAngle; currentAngle < endAngle;
213 currentAngle += angleIncrement )
219 EDA_ANGLE nextAngle = currentAngle + angleIncrement;
221 if( nextAngle > endAngle )
223 nextAngle = endAngle;
243 startAngle = endAngle;
257 double cosRot = rotation.
Cos();
258 double sinRot = rotation.
Sin();
263 if( endAngle == startAngle )
266 if( startAngle > endAngle )
274 auto evalRad = [&](
double thetaRad ) ->
VECTOR2D
276 double x = a * std::cos( thetaRad );
277 double y = b * std::sin( thetaRad );
283 double x = a * theta.Cos();
284 double y = b * theta.Sin();
291 const double startRad = startAngle.
AsRadians();
292 const double endRad = endAngle.
AsRadians();
293 const int LUT_SIZE = 1024;
294 std::vector<double> arcLens( LUT_SIZE + 1 );
297 VECTOR2D prev = evalRad( startRad );
299 for(
int j = 1; j <= LUT_SIZE; ++j )
301 double t = startRad + ( endRad - startRad ) * j / LUT_SIZE;
303 arcLens[j] = arcLens[j - 1] + ( curr - prev ).EuclideanNorm();
307 const double totalLen = arcLens[LUT_SIZE];
309 auto angleAtLen = [&](
double s ) ->
double
317 auto it = std::upper_bound( arcLens.begin(), arcLens.end(), s );
318 int idx = std::distance( arcLens.begin(), it ) - 1;
320 double seg = arcLens[idx + 1] - arcLens[idx];
321 double frac = ( seg > 0 ) ? ( s - arcLens[idx] ) / seg : 0.0;
323 double t0 = startRad + ( endRad - startRad ) * idx / LUT_SIZE;
324 double t1 = startRad + ( endRad - startRad ) * ( idx + 1 ) / LUT_SIZE;
326 return t0 + frac * ( t1 - t0 );
330 double currentLen = 0.0;
332 for(
size_t i = 0; i < 10000 && currentLen < totalLen; ++i )
334 double targetLen = std::min( currentLen + strokes[i % wrapAround], totalLen );
341 for(
EDA_ANGLE c = elemStart; c < elemEnd; c += angleIncrement )
343 EDA_ANGLE n = std::min( c + angleIncrement, elemEnd );
344 aStroker( evalAngle( c ), evalAngle( n ) );
348 currentLen = targetLen;