105 double dx12 = double( p2.m_x ) - double( p1.m_x );
106 double dy12 = double( p2.m_y ) - double( p1.m_y );
108 double dx1p = double( p.m_x ) - double( p1.m_x );
109 double dy1p = double( p.m_y ) - double( p1.m_y );
112 double length = dx12 * dx12 + dy12 * dy12;
114 double projection = dx12 * dx1p + dy12 * dy1p;
116 if( projection <= 0 || length == 0 )
121 else if( projection >= length )
141 projection /= length;
142 dx1p -= projection * dx12;
143 dy1p -= projection * dy12;
144 return dx1p * dx1p + dy1p * dy1p;
148 A2DARTBASEDLLEXP
bool InArc(
double angle,
double start,
double end,
bool clockwise )
160 if ( mr < 0 ) mr += 2.0 * M_PI;
161 if ( er < 0 ) er += 2.0 * M_PI;
162 if ( mr > 2.0 * M_PI ) mr -= 2.0 * M_PI;
163 if ( er > 2.0 * M_PI ) er -= 2.0 * M_PI;
183 static void gds_quadratic_spline(
a2dVertexList* org,
double a1,
double b1,
double a2,
double b2,
184 double a3,
double b3,
double a4,
double b4,
double aber );
185 static void gds_clear_stack();
186 static int gds_spline_pop(
double* x1,
double* y1,
double* x2,
double* y2,
double* x3,
187 double* y3,
double* x4,
double* y4 );
188 static void gds_spline_push(
double x1,
double y1,
double x2,
double y2,
double x3,
double y3,
189 double x4,
double y4 );
199 #ifdef CLASS_MEM_MANAGEMENT
200 a2dMemManager a2dLineSegment::sm_memManager( wxT(
"a2dLineSegment memory manager" ) );
201 #endif //CLASS_MEM_MANAGEMENT
212 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
226 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
237 m_pntCnt = other.m_pntCnt;
240 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
245 a2dLineSegment::~a2dLineSegment()
247 wxASSERT_MSG( m_refcount == 0, wxT(
"deleting a2dLineSegment while referenced" ) );
258 return sqrt( pow( prev.
m_x -
m_x, 2 ) + pow( prev.
m_y -
m_y, 2 ) );
269 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
271 void a2dLineSegment::DumpOwners()
273 wxLogDebug( _T(
"Owner list (%d) for (a2dLineSegment*)0x%p" ), m_refcount,
this );
278 switch( crnt->m_ownertype )
281 wxLogDebug( _T(
"SmrtPtr @ 0x%p in unknown %p" ), crnt, crnt->m_owner );
284 wxLogDebug( _T(
"SmrtPtr @ 0x%p in (%s*)0x%p offs=0x%x" ), crnt, ( ( wxObject* )crnt->m_owner )->GetClassInfo()->GetClassName(), crnt->m_owner, (
char* )crnt - (
char* )crnt->m_owner );
287 wxLogDebug( _T(
"SmrtPtr @ 0x%p in (wxSmrtPtrNode<a2dLineSegment>*)0x%p offs=0x%x" ), crnt, crnt->m_owner, (
char* )crnt - (
char* )crnt->m_owner );
292 wxLogDebug( _T(
"SmrtPtr @ 0x%p in unknown" ), crnt );
315 double radius = sqrt( pow( prev.
m_x - xc, 2 ) + pow( prev.
m_y - yc, 2 ) );
317 double endrad = atan2( prev.
m_y - yc, prev.
m_x - xc ) +
wxDegToRad( angle );
319 m_x = xc + radius * cos( endrad );
320 m_y = yc + radius * sin( endrad );
322 double midrad = atan2( prev.
m_y - yc, prev.
m_x - xc ) +
wxDegToRad( angle / 2.0 );
324 m_x2 = xc + radius * cos( midrad );
325 m_y2 = yc + radius * sin( midrad );
333 double radius = sqrt( pow( prev.
m_x - xc, 2 ) + pow( prev.
m_y - yc, 2 ) );
335 double endrad = atan2(
m_y - yc,
m_x - xc );
337 m_x = xc + radius * cos( endrad );
338 m_y = yc + radius * sin( endrad );
340 double midrad = atan2( y2 - yc, x2 - xc );
342 m_x2 = xc + radius * cos( midrad );
343 m_y2 = yc + radius * sin( midrad );
371 m_x2 = middleOrProj.m_x;
372 m_y2 = middleOrProj.m_y;
377 double len, radius, center_x, center_y, beginrad, midrad, endrad, phit;
379 if (
CalcR( prev, radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
384 len = sqrt( pow( prev.
m_x -
m_x, 2 ) + pow( prev.
m_y -
m_y, 2 ) );
391 double start = atan2( prev.
m_y - center_y, prev.
m_x - center_x );
392 double end = atan2(
m_y - center_y,
m_x - center_x );
394 double b = ( prev.
m_x -
m_x );
395 double a = ( prev.
m_y -
m_y );
396 double l = sqrt( a * a + b * b );
399 m_x2 = center_x - radius * b;
400 m_y2 = center_y - radius * a;
402 double mid = atan2(
m_y2 - center_y,
m_x2 - center_x );
404 if (
InArc( mid, start, end, clockwise ) )
407 m_x2 = center_x + radius * b;
408 m_y2 = center_y + radius * a;
414 radius, center_x, center_y, beginrad, midrad, endrad, phit );
419 double ax, ay, bx, by, cx, cy;
420 double ax2, ay2, bx2, by2, cx2, cy2;
422 bool straight =
false;
424 ax = prev.
m_x; ay = prev.
m_y; ax2 = pow( ax, 2 ); ay2 = pow( ay, 2 );
425 bx =
m_x2; by =
m_y2; bx2 = pow( bx, 2 ); by2 = pow( by, 2 );
426 cx =
m_x; cy =
m_y; cx2 = pow( cx, 2 ); cy2 = pow( cy, 2 );
428 if ( ax == cx && ay == cy )
431 return ( bx + ax ) / 2.0;
435 d = 2 * ( ay * cx + by * ax - by * cx - ay * bx - cy * ax + cy * bx );
443 return ( by * ax2 - cy * ax2 - by2 * ay + cy2 * ay + bx2 * cy + ay2 * by
444 + cx2 * ay - cy2 * by - cx2 * by - bx2 * ay + by2 * cy - ay2 * cy
451 double ax, ay, bx, by, cx, cy;
452 double ax2, ay2, bx2, by2, cx2, cy2;
454 bool straight =
false;
456 ax = prev.
m_x; ay = prev.
m_y; ax2 = pow( ax, 2 ); ay2 = pow( ay, 2 );
457 bx =
m_x2; by =
m_y2; bx2 = pow( bx, 2 ); by2 = pow( by, 2 );
458 cx =
m_x; cy =
m_y; cx2 = pow( cx, 2 ); cy2 = pow( cy, 2 );
460 if ( ax == cx && ay == cy )
463 return ( by + ay ) / 2.0;
467 d = 2 * ( ay * cx + by * ax - by * cx - ay * bx - cy * ax + cy * bx );
475 return ( ax2 * cx + ay2 * cx + bx2 * ax - bx2 * cx + by2 * ax - by2 * cx
476 - ax2 * bx - ay2 * bx - cx2 * ax + cx2 * bx - cy2 * ax + cy2 * bx
483 double ax, ay, bx, by, cx, cy;
484 double ax2, ay2, bx2, by2, cx2, cy2;
486 bool straight =
false;
488 ax = prev.
m_x; ay = prev.
m_y; ax2 = pow( ax, 2 ); ay2 = pow( ay, 2 );
489 bx =
m_x2; by =
m_y2; bx2 = pow( bx, 2 ); by2 = pow( by, 2 );
490 cx =
m_x; cy =
m_y; cx2 = pow( cx, 2 ); cy2 = pow( cy, 2 );
492 if ( ax == cx && ay == cy )
495 return a2dPoint2D( ( bx + ax ) / 2.0, ( by + ay ) / 2.0 );
499 d = 2 * ( ay * cx + by * ax - by * cx - ay * bx - cy * ax + cy * bx );
507 double x = ( by * ax2 - cy * ax2 - by2 * ay + cy2 * ay + bx2 * cy + ay2 * by
508 + cx2 * ay - cy2 * by - cx2 * by - bx2 * ay + by2 * cy - ay2 * cy
511 double y = ( ax2 * cx + ay2 * cx + bx2 * ax - bx2 * cx + by2 * ax - by2 * cx
512 - ax2 * bx - ay2 * bx - cx2 * ax + cx2 * bx - cy2 * ax + cy2 * bx
521 double radius, centerx, centery, start, mid, end, phit;
523 if ( !
CalcR( prev, radius, centerx, centery, start, mid, end, phit ) )
538 lworld.
TransformPoint( centerx + radius * cos ( start ), centery + radius * sin ( start ), x, y );
541 lworld.
TransformPoint( centerx + radius * cos ( end ), centery + radius * sin ( end ), x, y );
545 if (
InArc( alphax, start, end, phit < 0 ) )
547 lworld.
TransformPoint( centerx + radius * cos ( alphax ), centery + radius * sin ( alphax ), x, y );
551 if (
InArc( alphax, start, end, phit < 0 ) )
553 lworld.
TransformPoint( centerx + radius * cos ( alphax ), centery + radius * sin ( alphax ), x, y );
557 if (
InArc( alphax, start, end, phit < 0 ) )
559 lworld.
TransformPoint( centerx + radius * cos ( alphax ), centery + radius * sin ( alphax ), x, y );
562 if (
InArc( alphay, start, end, phit < 0 ) )
564 lworld.
TransformPoint( centerx + radius * cos ( alphay ), centery + radius * sin ( alphay ), x, y );
568 if (
InArc( alphay, start, end, phit < 0 ) )
570 lworld.
TransformPoint( centerx + radius * cos ( alphay ), centery + radius * sin ( alphay ), x, y );
574 if (
InArc( alphay, start, end, phit < 0 ) )
576 lworld.
TransformPoint( centerx + radius * cos ( alphay ), centery + radius * sin ( alphay ), x, y );
583 bbox.
Expand( centerx + radius * cos ( start ), centery + radius * sin ( start ) );
585 bbox.
Expand( centerx + radius * cos ( end ), centery + radius * sin ( end ) );
588 if (
InArc(
wxPI, start, end, phit < 0 ) )
589 bbox.
Expand( centerx - radius, centery );
590 if (
InArc( 1.5 *
wxPI, start, end, phit < 0 ) )
591 bbox.
Expand( centerx, centery - radius );
592 if (
InArc( 0, start, end, phit < 0 ) )
593 bbox.
Expand( centerx + radius, 0 );
594 if (
InArc(
wxPI / 2, start, end, phit < 0 ) )
595 bbox.
Expand( centerx, centery + radius );
615 for( a2dVertexList::const_iterator iter = other.begin(); iter != other.end(); ++iter )
625 void a2dVertexArray::RemoveAt(
size_t index )
628 for( a2dVertexArray::iterator iter = begin(); iter != end(); ++iter )
639 void a2dVertexArray::Insert(
a2dLineSegment* segment,
size_t index )
642 for( a2dVertexArray::iterator iter = begin(); iter != end(); ++iter )
646 insert( iter, segment );
656 for( a2dVertexArray::const_iterator iter = other.begin(); iter != other.end(); ++iter )
668 for( a2dVertexList::const_iterator iter = other.begin(); iter != other.end(); ++iter )
679 return Item( size() );
680 return Item( index - 1 );
685 if ( index == size() )
687 return Item( index + 1 );
693 for ( i = 0; i < size(); i++ )
695 if ( Item( i )->GetArc() )
705 for ( i = 1; i < size(); i++ )
707 len = len + Item( i )->
Length( *( Item( i - 1 ) ) );
735 if ( Item( n )->GetArc() )
740 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
743 prev = Item( ( n - 1 ) % size() );
745 if ( cseg->
CalcR( *prev, radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
746 cseg->
CalcMidPoint( *prev, center_x, center_y, radius, phit < 0 );
752 prev = Item( n - 1 );
753 if ( cseg->
CalcR( *prev, radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
754 cseg->
CalcMidPoint( *prev, center_x, center_y, radius, phit < 0 );
761 next = Item( ( n + 1 ) % size() );
764 if ( n < size() - 1 )
765 next = Item( n + 1 );
770 if ( next->GetArc() )
774 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
776 if ( cseg->
CalcR( *( Item( n ) ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
777 cseg->
CalcMidPoint( *( Item( n ) ), center_x, center_y, radius, phit < 0 );
789 double miny = workOn->Item( 0 )->
m_y;
799 for ( i = 0; i < size(); i++ )
801 seg = workOn->Item( i );
802 if ( seg->
m_y < miny )
808 for (
int i = 0; i < workOn->size(); i++ )
810 double x = workOn->Item( i )->
m_x;
811 double y = workOn->Item( i )->
m_y - miny;
812 seg = Item( i + 1 != workOn->size() ? i + 1 : 0 );
813 area += ( seg->
m_y - miny ) * x;
814 area -= seg->
m_x * y;
820 return fabs( area / 2.0 );
831 for ( i = 0; i < size(); i++ )
853 for ( i = 0; i < size(); i++ )
857 bbox.
Expand( seg->GetBbox( *( Item( i ? i - 1 : 0 ) ), lworld ) );
872 a2dVertexArray::iterator iterp = end();
873 a2dVertexArray::iterator iter = begin();
874 while ( iter != end() )
881 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
883 if ( cseg->
CalcR( *( *iterp ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
886 unsigned int segments;
887 if ( aberation == 0 )
888 Aberration( radius / 200, phit, radius , dphi, segments );
891 Aberration( aberation, phit, radius , dphi, segments );
893 double theta = beginrad;
896 for ( step = 0; step < segments + 1; step++ )
898 xw = center_x + radius * cos ( theta );
899 yw = center_y + radius * sin ( theta );
902 iter = insert( iter, segn );
904 theta = theta + dphi;
910 iter = insert( iter, segn );
917 iter = erase( iter );
934 for ( i = 0; i < size(); i++ )
946 vpathsegments->
Add( segn );
949 else if ( i == size() - 1 )
953 vpathsegments->
Add( arcseg );
958 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
960 if ( cseg->
CalcR( *( Item( i ? i - 1 : 0 ) ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
963 unsigned int segments;
964 Aberration( radius / 200, phit, radius , dphi, segments );
967 double theta = beginrad;
970 for ( step = 0; step < segments + 1; step++ )
972 xw = center_x + radius * cos ( theta );
973 yw = center_y + radius * sin ( theta );
975 vpathsegments->
Add( lineseg );
976 theta = theta + dphi;
982 vpathsegments->
Add( segn );
991 else if ( i == size() - 1 )
995 vpathsegments->
Add( lineseg );
998 return vpathsegments;
1010 unsigned int insertAt = converted->size();
1011 a2dVertexArray::iterator insertHere = end();
1012 unsigned int segments = size();
1016 if ( segments == 1 )
1021 case a2dPATH_END_SQAURE:
1026 case a2dPATH_END_ROUND:
1031 case a2dPATH_END_SQAURE_EXT:
1047 a2dLine line1( _first, _middle );
1049 offsetpointleft = _first;
1050 offsetpointright = _first;
1056 case a2dPATH_END_SQAURE:
1058 converted->push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
1059 insertHere = converted->insert( insertHere,
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
1062 case a2dPATH_END_ROUND:
1064 a2dLine lineoffset( offsetpointright, offsetpointleft );
1068 offsetpointfirst = _first;
1070 converted->push_back(
new a2dArcSegment( offsetpointleft.m_x, offsetpointleft.m_y,
1071 offsetpointfirst.m_x, offsetpointfirst.m_y ) );
1072 insertHere = converted->insert( insertHere,
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
1075 case a2dPATH_END_SQAURE_EXT:
1077 a2dLine lineoffset( offsetpointright, offsetpointleft );
1082 converted->push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
1083 insertHere = converted->insert( insertHere,
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
1094 for ( i = 1; i < segments - 1; i++ )
1100 a2dLine line1( _first, _middle );
1103 a2dLine line2( _middle, _end );
1107 OUTPRODUCT _outproduct;
1108 _outproduct = line1.
OutProduct( line2, 1e-9 );
1110 switch ( _outproduct )
1128 offsetpointleft = _middle;
1129 offsetpointright = _middle;
1135 wxFAIL_MSG( wxT(
"wrong line code" ) );
1139 converted->push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
1140 insertHere = converted->insert( insertHere,
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
1143 seg = Item( i - 1 );
1149 a2dLine line1( _first, _end );
1151 offsetpointleft = _end;
1152 offsetpointright = _end;
1158 case a2dPATH_END_SQAURE:
1160 converted->push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
1161 insertHere = converted->insert( insertHere,
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
1164 case a2dPATH_END_ROUND:
1166 a2dLine lineoffset( offsetpointleft, offsetpointright );
1170 offsetpointend = _end;
1172 converted->push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
1173 converted->push_back(
new a2dArcSegment( offsetpointright.m_x, offsetpointright.m_y,
1174 offsetpointend.m_x, offsetpointend.m_y ) );
1175 insertHere = converted->insert( insertHere,
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
1178 case a2dPATH_END_SQAURE_EXT:
1180 a2dLine lineoffset( offsetpointright, offsetpointleft );
1185 converted->push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
1186 insertHere = converted->insert( insertHere,
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
1200 for ( i = 0; i < size(); i++ )
1202 h.push_back( Item( i )->Clone() );
1208 unsigned int n = h.size();
1211 a2dVertexList::iterator iter = h.begin();
1212 for ( i = 0; i < n; i++ )
1214 spoints->push_back( ( *iter ) );
1215 iter = h.erase( iter );
1225 for ( i = 0; i < size(); i++ )
1227 h.push_back( Item( i )->Clone() );
1231 h.ConvertIntoSplinedPolyline( Aber );
1233 unsigned int n = h.size();
1236 a2dVertexList::iterator iter = h.begin();
1237 for ( i = 0; i < n; i++ )
1239 spoints->push_back( ( *iter )->Clone() );
1240 iter = h.erase( iter );
1256 wxASSERT( margin >= 0 );
1260 double minDistSqrVertex = margin * margin;
1261 double minDistSqrStroke = margin * margin;
1262 bool vertexhit =
false;
1263 int intersection_count = 0;
1268 for ( i = 0; i < size(); i++ )
1271 p1 = Item( i )->GetPoint();
1272 if ( i == size() - 1 )
1273 p2 = Item( 0 )->GetPoint();
1275 p2 = Item( i + 1 )->GetPoint();
1288 if( p1.m_x < p2.m_x )
1301 if( ptest.m_x < xmin - margin || ptest.m_x > xmax + margin )
1307 if( p1.m_y < p2.m_y )
1320 if( ptest.m_y < ymin - margin )
1325 if( ptest.m_x >= xmin && ptest.m_x < xmax && p1.m_x != p2.m_x )
1327 intersection_count += direction;
1330 else if( ptest.m_y <= ymax + margin )
1352 if( distSqr < minDistSqrVertex )
1354 minDistSqrVertex = distSqr;
1357 rslt.m_stroke2 = a2dHit::stroke2_vertex;
1365 pm =
a2dPoint2D( 0.5 * ( p1.m_x + p2.m_x ), 0.5 * ( p1.m_y + p2.m_y ) );
1367 if( distSqr < minDistSqrVertex )
1369 minDistSqrVertex = distSqr;
1372 if( p1.m_x == p2.m_x )
1373 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
1374 else if( p1.m_y == p2.m_y )
1375 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
1377 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
1389 if( distSqr < minDistSqrStroke )
1391 minDistSqrStroke = distSqr;
1396 if( p1.m_x == p2.m_x )
1397 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
1398 else if( p1.m_y == p2.m_y )
1399 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
1401 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
1413 if( ptest.m_x >= xmin && ptest.m_x < xmax && p1.m_x != p2.m_x )
1415 if( p1.m_y == p2.m_y )
1417 if( ptest.m_y <= p1.m_y )
1418 intersection_count += direction;
1422 double y = ( ptest.m_x - p1.m_x ) * ( p2.m_y - p1.m_y ) / ( p2.m_x - p1.m_x ) + p1.m_y;
1423 if( ptest.m_y <= y )
1424 intersection_count += direction;
1432 if( intersection_count )
1433 rslt.m_stroke1 = a2dHit::stroke1_inside;
1435 rslt.m_stroke1 = a2dHit::stroke1_outside;
1438 rslt.
m_distance = ( sqrt( wxMin( minDistSqrVertex, minDistSqrStroke ) ) / margin );
1440 rslt.
m_distance = ( sqrt( minDistSqrStroke ) / margin );
1444 if( intersection_count )
1455 wxASSERT( margin >= 0 );
1459 double minDistSqrVertex = margin * margin;
1460 double minDistSqrStroke = margin * margin;
1461 bool vertexhit =
false;
1462 bool lastpoint =
false;
1467 for ( i = 0; i < size(); i++ )
1470 p1 = Item( i )->GetPoint();
1471 if( i < size() - 1 )
1472 p2 = Item( i + 1 )->GetPoint();
1485 if( p1.m_x < p2.m_x )
1496 if( ptest.m_x < xmin - margin || ptest.m_x > xmax + margin )
1502 if( p1.m_y < p2.m_y )
1513 if( ptest.m_y < ymin - margin || ptest.m_y > ymax + margin )
1536 if( distSqr < minDistSqrVertex )
1538 minDistSqrVertex = distSqr;
1541 rslt.m_stroke2 = a2dHit::stroke2_vertex;
1552 pm =
a2dPoint2D( 0.5 * ( p1.m_x + p2.m_x ), 0.5 * ( p1.m_y + p2.m_y ) );
1554 if( distSqr < minDistSqrVertex )
1556 minDistSqrVertex = distSqr;
1559 if( p1.m_x == p2.m_x )
1560 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
1561 else if( p1.m_y == p2.m_y )
1562 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
1564 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
1576 if( distSqr < minDistSqrStroke )
1578 minDistSqrStroke = distSqr;
1583 if( p1.m_x == p2.m_x )
1584 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
1585 else if( p1.m_y == p2.m_y )
1586 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
1588 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
1595 rslt.m_stroke1 = a2dHit::stroke1_outside;
1597 rslt.
m_distance = ( sqrt( wxMin( minDistSqrVertex, minDistSqrStroke ) ) / margin );
1599 rslt.
m_distance = ( sqrt( minDistSqrStroke ) / margin );
1611 for ( i = 0; i < size(); i++ )
1614 if ( !seg->GetArc() && segprev && seg->GetPoint() == segprev->GetPoint() )
1624 if ( polygon && !seg->GetArc() && segprev && seg->GetPoint() == segprev->GetPoint() )
1626 RemoveAt( size() - 1 );
1639 for ( i = 0; i < size(); i++ )
1642 if ( !seg->GetArc() && segprev &&
1643 ( seg->GetPoint() == segprev->GetPoint() ||
ClclDistSqrPntPnt( seg->GetPoint(), segprev->GetPoint() ) <= smallest ) )
1646 redunDant->push_back( seg->
Clone() );
1651 if ( polygon && !seg->GetArc() && segprev &&
1652 ( seg->GetPoint() == segprev->GetPoint() ||
ClclDistSqrPntPnt( seg->GetPoint(), segprev->GetPoint() ) <= smallest ) )
1654 redunDant->push_back( seg->
Clone() );
1656 if ( redunDant->empty() )
1669 a2dVertexList::a2dVertexList()
1684 for( a2dVertexArray::const_iterator iter = other.begin(); iter != other.end(); ++iter )
1691 a2dVertexList::~a2dVertexList()
1693 wxASSERT_MSG( m_refcount == 0, wxT(
"deleting a2dLineSegment while referenced" ) );
1701 for( a2dVertexList::const_iterator iter = other.begin(); iter != other.end(); ++iter )
1713 for( a2dVertexArray::const_iterator iter = other.begin(); iter != other.end(); ++iter )
1723 if ( iter == begin() )
1730 if ( iter == --end() )
1737 if ( iter == begin() )
1744 if ( iter == --end() )
1751 a2dVertexList::iterator iterr = begin();
1752 while( iterr != iter )
1763 for( a2dVertexList::const_iterator iter = begin(); iter != end(); ++iter )
1766 if ( seg->GetArc() )
1776 a2dVertexList::iterator iterp = begin();
1777 a2dVertexList::iterator iter = iterp;
1779 while ( iter != end() )
1781 len = len + ( *iter )->Length( *( *iterp ) );
1791 for( a2dVertexList::const_iterator iter = begin(); iter != end(); ++iter )
1793 if( *iter ==
object )
1803 a2dVertexList::iterator iter;
1804 for( iter = begin(); iter != end(); ++iter )
1808 insert( iter, segin );
1813 if( iter == end() && i == index )
1814 insert( iter, segin );
1815 wxASSERT_MSG( i <= size() , wxT(
"index higher than list size" ) );
1836 a2dVertexList::iterator iter = begin();
1837 a2dVertexList::iterator prev = end();
1840 while ( iter != end() )
1848 if ( seg->GetArc() )
1851 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
1852 if ( prev != end() )
1854 if ( cseg->
CalcR( *( *prev ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
1855 cseg->
CalcMidPoint( *( *prev ), center_x, center_y, radius, phit < 0 );
1859 a2dVertexList::iterator next = iter;
1861 if ( next == end() && polygon )
1864 if ( next != end() && ( *next )->GetArc() )
1867 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
1869 if ( cseg->
CalcR( *( *iter ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
1870 cseg->
CalcMidPoint( *( *iter ), center_x, center_y, radius, phit < 0 );
1883 a2dVertexList::iterator iter = begin();
1884 a2dVertexList::iterator prev = end();
1888 while ( iter != end() )
1896 if ( seg->GetArc() )
1899 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
1900 if ( prev != end() )
1902 if ( cseg->
CalcR( *( *prev ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
1903 cseg->
CalcMidPoint( *( *prev ), center_x, center_y, radius, phit < 0 );
1907 a2dVertexList::iterator next = iter;
1909 if ( next == end() && polygon )
1912 if ( next != end() && ( *next )->GetArc() )
1915 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
1917 if ( cseg->
CalcR( *( *iter ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
1918 cseg->
CalcMidPoint( *( *iter ), center_x, center_y, radius, phit < 0 );
1935 for( a2dVertexList::iterator iter = begin(); iter != end(); ++iter )
1938 if ( seg->GetArc() )
1953 a2dVertexList::iterator iterp = end();
1954 a2dVertexList::iterator iter = begin();
1955 while ( iter != end() )
1958 if ( seg->GetArc() )
1962 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
1964 if ( cseg->
CalcR( *( *iterp ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
1967 unsigned int segments;
1968 if ( aberation == 0 )
1969 Aberration( radius / 200, phit, radius , dphi, segments );
1972 Aberration( aberation, phit, radius , dphi, segments );
1974 double theta = beginrad;
1977 for ( step = 0; step < segments + 1; step++ )
1979 xw = center_x + radius * cos ( theta );
1980 yw = center_y + radius * sin ( theta );
1983 iter = insert( iter, segn );
1985 theta = theta + dphi;
1991 iter = insert( iter, segn );
1998 iter = erase( iter );
2011 dphi = dphi * M_PI / 180.0;
2016 a2dVertexList::iterator iterp = end();
2017 a2dVertexList::iterator iter = begin();
2018 while ( iter != end() )
2021 if ( seg->GetArc() )
2025 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
2026 if ( cseg->
CalcR( *( *iterp ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
2028 unsigned int segments;
2029 segments = (
unsigned int ) ( ceil( phit / dphi ) < minseg ? minseg : ceil( phit / dphi ) );
2031 dphi = phit / ( segments );
2032 if ( midrad > endrad ) dphi = -dphi;
2034 double theta = beginrad;
2037 for ( step = 0; step < segments + 1; step++ )
2039 xw = center_x + radius * cos ( theta );
2040 yw = center_y + radius * sin ( theta );
2043 iter = insert( iterp, segn );
2045 theta = theta + dphi;
2051 iter = insert( iterp, segn );
2058 iter = erase( iter );
2074 a2dVertexList::iterator iterp = end();
2075 a2dVertexList::iterator iter = begin();
2076 while ( iter != end() )
2079 if ( seg->GetArc() )
2085 a2dVertexList::iterator iternext = iter;
2087 if ( iter == begin() )
2090 vpathsegments->
Add( segn );
2093 else if ( iternext == end() )
2097 vpathsegments->
Add( arcseg );
2102 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
2104 if ( cseg->
CalcR( *( *iterp ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
2107 unsigned int segments;
2108 Aberration( radius / 200, phit, radius , dphi, segments );
2111 double theta = beginrad;
2114 for ( step = 0; step < segments + 1; step++ )
2116 xw = center_x + radius * cos ( theta );
2117 yw = center_y + radius * sin ( theta );
2119 vpathsegments->
Add( lineseg );
2120 theta = theta + dphi;
2126 vpathsegments->
Add( segn );
2133 a2dVertexList::iterator iternext = iter;
2135 if ( iter == begin() )
2137 else if ( iternext == end() )
2141 vpathsegments->
Add( lineseg );
2147 return vpathsegments;
2159 double miny = ( *workOn->begin() )->m_y;
2167 a2dVertexList::const_iterator iter;
2168 for( iter = workOn->begin(); iter != workOn->end(); ++iter )
2171 if ( seg->
m_y < miny )
2177 iter = workOn->begin();
2178 for (
int i = 0; i <= workOn->size(); i++ )
2180 double x = ( *iter )->m_x;
2181 double y = ( *iter )->m_y - miny;
2183 area += ( ( *iter )->m_y - miny ) * x;
2184 area -= ( *iter )->m_x * y;
2190 return fabs( area / 2.0 );
2195 return (
bool )(
CalcArea() < 0.0 );
2203 middlepoint = n / 2;
2206 begin_p.m_x = ( *iter )->m_x;
2207 begin_p.m_y = ( *iter )->m_y;
2213 for ( i = 1; i < middlepoint - 1; i++ )
2214 iter = erase( iter );
2216 middle_p.m_x = ( *iter )->m_x;
2217 middle_p.m_y = ( *iter )->m_y;
2219 for ( i = middlepoint; i < n; i++ )
2220 iter = erase( iter );
2222 if ( ( *iter )->m_x == begin_p.m_x && ( *iter )->m_y == begin_p.m_y )
2224 double dx = center_x - begin_p.m_x;
2225 double dy = center_y - begin_p.m_y;
2231 insert( iter, aseg );
2236 insert( iter, aseg );
2239 iter = erase( iter );
2242 bool a2dVertexList::CheckForOneCircle(
a2dPoint2D& middle,
double& radius )
2244 a2dVertexList::iterator iter = begin();
2246 if ( size() == 1 && seg->GetArc() )
2249 double x = ( *iter )->m_x;
2250 double y = ( *iter )->m_y;
2253 middle.m_y = cseg->
GetOy( *seg );
2254 radius = sqrt( pow( x - middle.m_x, 2.0 ) + pow( y - middle.m_y, 2.0 ) );
2257 if ( x == seg->
m_x && y == seg->
m_y )
2294 void a2dVertexList::ConvertPolygonToArc(
double aber,
double Rmin,
double Rmax )
2296 int n, minimum_points;
2313 if ( size() > minimum_points )
2323 a2dVertexList::iterator iter = begin();
2324 for (
int count = 0; count < size(); count++ )
2326 n =
TestArc( iter, aber, Rmin, Rmax, center_p );
2328 if ( n < size() && n > minimum_points )
2330 for (
int t = 1; t < n; t++ ) iter++;
2339 else if ( n > minimum_points )
2343 double dx = center_p.m_x - ( *iter )->m_x;
2344 double dy = center_p.m_y - ( *iter )->m_y;
2365 if ( !back()->GetArc() )
2371 int n, minimum_points;
2379 a2dVertexList::iterator iter = begin();
2380 if ( size() > minimum_points )
2386 while( iter != end() )
2392 n =
TestArc( iter, aber, Rmin, Rmax, center_p );
2393 if ( n > minimum_points )
2394 InsertArc( iter, n, center_p.m_x, center_p.m_y );
2398 if ( iter != end() ) iter++;
2399 if ( iter != end() ) iter++;
2400 if ( iter != end() ) iter++;
2405 #define KLEIN 1.0e-30
2406 #define GROOT 1.0e30
2407 #define PHI_MARGE 0.3 //must be lager than 0, 0.3 -> 30% (graden)
2408 #define SEG_MARGE 0.3 //must be lager than 0, 0.3 -> 30%
2412 a2dPoint2D begin_p, middle_p, test_p, end_p, center_p ;
2414 a2dVertexList::iterator middle = iter;
2415 a2dVertexList::iterator test = iter;
2416 a2dVertexList::iterator endc = iter;
2418 double error1, error2, Radius, Radius_old;
2419 double x_between, y_between, dx, dy, x_prev, y_prev;
2420 double inp, phi, phi_old, phi_fac, a, b, lseg, lseg_old, seg_fac;
2423 int i, j, ii, minimum_points;
2434 phi_fac = 1 + PHI_MARGE;
2435 seg_fac = 1 + SEG_MARGE;
2450 begin_p.m_x = ( *iter )->m_x;
2451 begin_p.m_y = ( *iter )->m_y;
2453 for ( ii = 1; ii <= minimum_points; ii++ )
2456 if ( !( *endc )->GetArc() )
2472 end_p.m_x = ( *endc )->m_x;
2473 end_p.m_y = ( *endc )->m_y;
2475 middle_p.m_x = ( *middle )->m_x;
2476 middle_p.m_y = ( *middle )->m_y;
2478 Radius_old = Radius;
2479 center_p_old = center_p;
2483 if ( !( ( fabs( end_p.m_x - begin_p.m_x ) <
a2dACCUR ) && ( fabs( end_p.m_y - begin_p.m_y ) <
a2dACCUR ) ) )
2484 CalcR( begin_p.m_x, begin_p.m_y, middle_p.m_x, middle_p.m_y, end_p.m_x, end_p.m_y,
2491 test_p.m_x = ( *test )->m_x;
2492 test_p.m_y = ( *test )->m_y;
2498 x_prev = test_p.m_x;
2499 y_prev = test_p.m_y;
2503 test_p.m_x = ( *test )->m_x;
2504 test_p.m_y = ( *test )->m_y;
2506 dx = center_p.m_x - test_p.m_x;
2507 dy = center_p.m_y - test_p.m_y;
2509 error1 = fabs( Radius - sqrt( pow( dx, 2 ) + pow( dy, 2 ) ) );
2511 x_between = ( test_p.m_x + x_prev ) / 2.0;
2512 y_between = ( test_p.m_y + y_prev ) / 2.0;
2514 dx = center_p.m_x - x_between;
2515 dy = center_p.m_y - y_between;
2517 error2 = fabs( Radius - sqrt( pow( dx, 2 ) + pow( dy, 2 ) ) );
2519 inp = ( center_p.m_x - x_prev ) * ( test_p.m_y - center_p.m_y ) -
2520 ( center_p.m_y - y_prev ) * ( test_p.m_x - center_p.m_x );
2522 a = sqrt( pow( ( center_p.m_x - x_prev ), 2 ) + pow( ( center_p.m_y - y_prev ), 2 ) );
2523 b = sqrt( pow( ( center_p.m_x - test_p.m_x ), 2 ) + pow( ( center_p.m_y - test_p.m_y ), 2 ) );
2527 t_inp = inp / ( a * b );
2531 else if ( t_inp < -1.0 )
2534 phi = 180.0 * asin( t_inp ) / M_PI;
2538 lseg = sqrt( pow( ( test_p.m_x - x_prev ), 2 ) + pow( ( test_p.m_y - y_prev ), 2 ) );
2546 if ( error1 > aber ||
2548 fabs( phi ) > fabs( phi_old )*phi_fac ||
2549 fabs( phi ) < fabs( phi_old ) / phi_fac ||
2550 phi * phi_old < 0.0 ||
2551 lseg > lseg_old * seg_fac ||
2552 lseg < lseg_old / seg_fac )
2554 if ( Radius_old > Rmin && Radius_old < Rmax )
2565 if ( ( *endc )->GetArc() )
2570 while( endc != end() );
2572 if ( Radius > Rmin && Radius < Rmax )
2574 center_p_old = center_p;
2593 for( a2dVertexList::iterator iter = begin(); iter != end(); ++iter )
2596 if ( seg->GetArc() && segprev )
2597 bbox.
Expand( seg->GetBbox( *segprev, lworld ) );
2603 segprev = ( *iter );
2614 converted->
Contour( distance, pathtype, asPolygon );
2620 bool rounded =
true;
2631 unsigned int size = this->size();
2632 a2dVertexList::iterator iter = begin();
2634 a2dVertexList::iterator prev = iter;
2643 case a2dPATH_END_SQAURE:
2648 case a2dPATH_END_ROUND:
2653 case a2dPATH_END_SQAURE_EXT:
2672 a2dLine line1( _first, _middle );
2674 offsetpointleft = _first;
2675 offsetpointright = _first;
2681 case a2dPATH_END_SQAURE:
2683 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2684 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2687 case a2dPATH_END_ROUND:
2689 a2dLine lineoffset( offsetpointright, offsetpointleft );
2693 offsetpointfirst = _first;
2695 push_back(
new a2dArcSegment( offsetpointleft.m_x, offsetpointleft.m_y,
2696 offsetpointfirst.m_x, offsetpointfirst.m_y ) );
2697 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2700 case a2dPATH_END_SQAURE_EXT:
2702 a2dLine lineoffset( offsetpointright, offsetpointleft );
2707 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2708 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2723 a2dLine line1( _first, _middle );
2729 a2dLine line2( _middle, _end );
2733 OUTPRODUCT _outproduct;
2734 _outproduct = line1.
OutProduct( line2, 1e-9 );
2736 switch ( _outproduct )
2745 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2746 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2752 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2762 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2763 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2768 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2776 offsetpointleft = _middle;
2777 offsetpointright = _middle;
2780 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2781 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2785 wxFAIL_MSG( wxT(
"wrong line code" ) );
2798 a2dLine line2( _first, _end );
2800 offsetpointleft = _end;
2801 offsetpointright = _end;
2805 prev = erase( prev );
2806 prev = erase( prev );
2810 case a2dPATH_END_SQAURE:
2812 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2813 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2816 case a2dPATH_END_ROUND:
2818 a2dLine lineoffset( offsetpointleft, offsetpointright );
2822 offsetpointend = _end;
2824 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2825 push_back(
new a2dArcSegment( offsetpointright.m_x, offsetpointright.m_y,
2826 offsetpointend.m_x, offsetpointend.m_y ) );
2827 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2830 case a2dPATH_END_SQAURE_EXT:
2832 a2dLine lineoffset( offsetpointright, offsetpointleft );
2837 push_back(
new a2dLineSegment( offsetpointleft.m_x, offsetpointleft.m_y ) );
2838 push_front(
new a2dLineSegment( offsetpointright.m_x, offsetpointright.m_y ) );
2864 h->ConvertIntoSplinedPolyline( Aber );
2875 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
2876 double x1, y1, x2, y2;
2881 a2dVertexList::iterator iter = --end();
2882 x1 = ( *iter )->m_x;
2883 y1 = ( *iter )->m_y;
2886 x2 = ( *iter )->m_x;
2887 y2 = ( *iter )->m_y;
2892 cx1 = ( x1 + x2 ) / 2.0;
2893 cy1 = ( y1 + y2 ) / 2.0;
2894 cx2 = ( cx1 + x2 ) / 2.0;
2895 cy2 = ( cy1 + y2 ) / 2.0;
2897 iter = erase( iter );
2899 x1 = ( *iter )->m_x;
2900 y1 = ( *iter )->m_y;
2905 unsigned int count = size();
2910 x2 = ( *iter )->m_x;
2911 y2 = ( *iter )->m_y;
2912 cx4 = ( x1 + x2 ) / 2.0;
2913 cy4 = ( y1 + y2 ) / 2.0;
2914 cx3 = ( x1 + cx4 ) / 2.0;
2915 cy3 = ( y1 + cy4 ) / 2.0;
2917 gds_quadratic_spline(
this, cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4, Aber );
2921 cx2 = ( cx1 + x2 ) / 2.0;
2922 cy2 = ( cy1 + y2 ) / 2.0;
2923 iter = erase( iter );
2932 void a2dVertexList::ConvertIntoSplinedPolyline(
double Aber )
2934 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
2935 double x1, y1, x2, y2;
2941 a2dVertexList::iterator iter = begin();
2943 x1 = ( *iter )->m_x;
2944 y1 = ( *iter )->m_y;
2946 iter = erase( iter );
2948 x2 = ( *iter )->m_x;
2949 y2 = ( *iter )->m_y;
2950 cx1 = ( x1 + x2 ) / 2.0;
2951 cy1 = ( y1 + y2 ) / 2.0;
2952 cx2 = ( cx1 + x2 ) / 2.0;
2953 cy2 = ( cy1 + y2 ) / 2.0;
2958 iter = erase( iter );
2961 unsigned int count = size();
2966 x2 = ( *iter )->m_x;
2967 y2 = ( *iter )->m_y;
2968 cx4 = ( x1 + x2 ) / 2.0;
2969 cy4 = ( y1 + y2 ) / 2.0;
2970 cx3 = ( x1 + cx4 ) / 2.0;
2971 cy3 = ( y1 + cy4 ) / 2.0;
2973 gds_quadratic_spline(
this, cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4, Aber );
2977 cx2 = ( cx1 + x2 ) / 2.0;
2978 cy2 = ( cy1 + y2 ) / 2.0;
2979 iter = erase( iter );
2995 a2dVertexList::iterator iter = begin();
2996 while( iter != end() )
2999 if ( !seg->GetArc() && segprev && seg->GetPoint() == segprev->GetPoint() )
3001 iter = erase( iter );
3012 if ( polygon && !seg->GetArc() && segprev && seg->GetPoint() == segprev->GetPoint() )
3014 iter = erase( iter );
3022 smallest = smallest * smallest;
3026 a2dVertexList::iterator iter = begin();
3027 while( iter != end() )
3030 if ( !seg->GetArc() && segprev &&
3031 ( seg->GetPoint() == segprev->GetPoint() ||
ClclDistSqrPntPnt( seg->GetPoint(), segprev->GetPoint() ) <= smallest ) )
3032 redunDant->push_back( seg->
Clone() );
3038 if ( polygon && !seg->GetArc() && segprev &&
3039 ( seg->GetPoint() == segprev->GetPoint() ||
ClclDistSqrPntPnt( seg->GetPoint(), segprev->GetPoint() ) <= smallest ) )
3040 redunDant->push_back( seg->
Clone() );
3042 if ( redunDant->empty() )
3052 wxASSERT( margin >= 0 );
3056 double minDistSqrVertex = margin * margin;
3057 double minDistSqrStroke = margin * margin;
3058 bool vertexhit =
false;
3059 int intersection_count = 0;
3063 for( a2dVertexList::iterator iter = begin(); iter != end(); ++iter, i++ )
3066 p1 = seg->GetPoint();
3067 if ( iter == --end() )
3069 p2 = front()->GetPoint();
3074 p2 = ( *iter )->GetPoint();
3089 if( p1.m_x < p2.m_x )
3102 if( ptest.m_x < xmin - margin || ptest.m_x > xmax + margin )
3108 if( p1.m_y < p2.m_y )
3121 if( ptest.m_y < ymin - margin )
3126 if( ptest.m_x >= xmin && ptest.m_x < xmax && p1.m_x != p2.m_x )
3128 intersection_count += direction;
3131 else if( ptest.m_y <= ymax + margin )
3153 if( distSqr < minDistSqrVertex )
3155 minDistSqrVertex = distSqr;
3158 rslt.m_stroke2 = a2dHit::stroke2_vertex;
3166 pm =
a2dPoint2D( 0.5 * ( p1.m_x + p2.m_x ), 0.5 * ( p1.m_y + p2.m_y ) );
3168 if( distSqr < minDistSqrVertex )
3170 minDistSqrVertex = distSqr;
3173 if( p1.m_x == p2.m_x )
3174 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
3175 else if( p1.m_y == p2.m_y )
3176 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
3178 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
3190 if( distSqr < minDistSqrStroke )
3192 minDistSqrStroke = distSqr;
3197 if( p1.m_x == p2.m_x )
3198 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
3199 else if( p1.m_y == p2.m_y )
3200 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
3202 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
3211 if( ptest.m_x >= xmin && ptest.m_x < xmax && p1.m_x != p2.m_x )
3213 if( p1.m_y == p2.m_y )
3215 if( ptest.m_y <= p1.m_y )
3216 intersection_count += direction;
3220 double y = ( ptest.m_x - p1.m_x ) * ( p2.m_y - p1.m_y ) / ( p2.m_x - p1.m_x ) + p1.m_y;
3221 if( ptest.m_y <= y )
3222 intersection_count += direction;
3230 if( intersection_count )
3231 rslt.m_stroke1 = a2dHit::stroke1_inside;
3233 rslt.m_stroke1 = a2dHit::stroke1_outside;
3236 rslt.
m_distance = ( sqrt( wxMin( minDistSqrVertex, minDistSqrStroke ) ) / margin );
3238 rslt.
m_distance = ( sqrt( minDistSqrStroke ) / margin );
3242 if( intersection_count )
3253 wxASSERT( margin >= 0 );
3257 double minDistSqrVertex = margin * margin;
3258 double minDistSqrStroke = margin * margin;
3259 bool vertexhit =
false;
3260 bool lastpoint =
false;
3264 for( a2dVertexList::iterator iter = begin(); iter != end(); ++iter, i++ )
3267 p1 = seg->GetPoint();
3269 if( iter != --end() )
3272 p2 = ( *iter )->GetPoint();
3287 if( p1.m_x < p2.m_x )
3298 if( ptest.m_x < xmin - margin || ptest.m_x > xmax + margin )
3304 if( p1.m_y < p2.m_y )
3315 if( ptest.m_y < ymin - margin || ptest.m_y > ymax + margin )
3338 if( distSqr < minDistSqrVertex )
3340 minDistSqrVertex = distSqr;
3343 rslt.m_stroke2 = a2dHit::stroke2_vertex;
3354 pm =
a2dPoint2D( 0.5 * ( p1.m_x + p2.m_x ), 0.5 * ( p1.m_y + p2.m_y ) );
3356 if( distSqr < minDistSqrVertex )
3358 minDistSqrVertex = distSqr;
3361 if( p1.m_x == p2.m_x )
3362 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
3363 else if( p1.m_y == p2.m_y )
3364 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
3366 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
3378 if( distSqr < minDistSqrStroke )
3380 minDistSqrStroke = distSqr;
3385 if( p1.m_x == p2.m_x )
3386 rslt.m_stroke2 = a2dHit::stroke2_edgevert;
3387 else if( p1.m_y == p2.m_y )
3388 rslt.m_stroke2 = a2dHit::stroke2_edgehor;
3390 rslt.m_stroke2 = a2dHit::stroke2_edgeother;
3397 rslt.m_stroke1 = a2dHit::stroke1_outside;
3399 rslt.
m_distance = ( sqrt( wxMin( minDistSqrVertex, minDistSqrStroke ) ) / margin );
3401 rslt.
m_distance = ( sqrt( minDistSqrStroke ) / margin );
3409 double phi, dphi, dx, dy;
3412 double ang1, ang2, phit;
3414 dx = begin.m_x - center.m_x;
3415 dy = begin.m_y - center.m_y;
3416 ang1 = atan2( dy, dx );
3417 if ( ang1 < 0 ) ang1 += 2.0 * M_PI;
3418 dx = end.m_x - center.m_x;
3419 dy = end.m_y - center.m_y;
3420 ang2 = atan2( dy, dx );
3421 if ( ang2 < 0 ) ang2 += 2.0 * M_PI;
3427 phit = 2.0 * M_PI - ang2 + ang1;
3435 phit = -( 2.0 * M_PI - ang1 + ang2 );
3437 phit = -( ang2 - ang1 );
3441 dphi = 2 * acos( ( radius - aber ) / radius );
3445 Segments = ( int )ceil( phit / dphi );
3447 Segments = ( int )ceil( -phit / dphi );
3449 if ( Segments <= 1 )
3454 dphi = phit / ( Segments );
3456 dx = begin.m_x - center.m_x;
3457 dy = begin.m_y - center.m_y;
3458 phi = atan2( dy, dx );
3461 for ( i = 0; i <= Segments; i++ )
3464 push_front(
new a2dLineSegment( center.m_x + radius * cos( phi ), center.m_y + radius * sin( phi ) ) );
3466 push_back(
new a2dLineSegment( center.m_x + radius * cos( phi ), center.m_y + radius * sin( phi ) ) );
3473 double distance = 0;
3493 a2dLine offs_currentline( offs_begin, offs_end );
3500 a2dLine offs_nextline( offs_bgn_next, offs_end_next );
3504 offs_currentline.
Intersect( offs_nextline, medial_axes_point );
3506 double result_offs = sqrt( pow( currentline.
GetEndPoint().m_x - medial_axes_point.m_x, 2 ) +
3507 pow( currentline.
GetEndPoint().m_y - medial_axes_point.m_y, 2 ) );
3510 if ( result_offs < fabs( roundFactor * factor ) )
3528 const int VPATHSPLINE_STEP = 20;
3551 wxASSERT_MSG( m_refcount == 0, wxT(
"deleting a2dVpathSegment while referenced" ) );
3562 return sqrt( pow( prev->m_x1 -
m_x1, 2 ) + pow( prev->m_y1 -
m_y1, 2 ) );
3585 switch ( prev->GetType() )
3625 double xwl = prev->m_x1;
3626 double ywl = prev->m_y1;
3629 for ( step = 1; step <= VPATHSPLINE_STEP; step++ )
3632 len = len + sqrt( pow( xwl - xt, 2 ) + pow( ywl - yt, 2 ) );
3633 t = t + 1 / ( double )VPATHSPLINE_STEP;
3643 xt = prev->m_x1 * pow( 1 - t, 2 ) +
m_x2 * ( 1 - t ) * t * 2 +
m_x1 * pow( t, 2 );
3644 yt = prev->m_y1 * pow( 1 - t, 2 ) +
m_y2 * ( 1 - t ) * t * 2 +
m_y1 * pow( t, 2 );
3670 switch ( prev->GetType() )
3715 double xwl = prev->m_x1;
3716 double ywl = prev->m_y1;
3719 for ( step = 1; step <= VPATHSPLINE_STEP; step++ )
3722 len = len + sqrt( pow( xwl - xt, 2 ) + pow( ywl - yt, 2 ) );
3723 t = t + 1 / ( double )VPATHSPLINE_STEP;
3733 xt = prev->m_x1 * pow( 1 - t, 3 ) +
m_x2 * pow( 1 - t, 2 ) * t * 3 +
m_x3 * ( 1 - t ) * t * t * 3 +
m_x1 * pow( t, 3 );
3734 yt = prev->m_y1 * pow( 1 - t, 3 ) +
m_y2 * pow( 1 - t, 2 ) * t * 3 +
m_y3 * ( 1 - t ) * t * t * 3 +
m_y1 * pow( t, 3 );
3757 double radius = sqrt( pow( prev->m_x1 - xc, 2 ) + pow( prev->m_y1 - yc, 2 ) );
3759 double endrad = atan2( prev->m_y1 - yc, prev->m_x1 - xc ) +
wxDegToRad( angle );
3761 m_x1 = xc + radius * cos( endrad );
3762 m_y1 = yc + radius * sin( endrad );
3764 double midrad = atan2( prev->m_y1 - yc, prev->m_x1 - xc ) +
wxDegToRad( angle / 2.0 );
3766 m_x2 = xc + radius * cos( midrad );
3767 m_y2 = yc + radius * sin( midrad );
3778 double radius = sqrt( pow( prev->m_x1 - xc, 2 ) + pow( prev->m_y1 - yc, 2 ) );
3780 double endrad = atan2(
m_y1 - yc,
m_x1 - xc );
3782 m_x1 = xc + radius * cos( endrad );
3783 m_y1 = yc + radius * sin( endrad );
3785 double midrad = atan2( y2 - yc, x2 - xc );
3787 m_x2 = xc + radius * cos( midrad );
3788 m_y2 = yc + radius * sin( midrad );
3808 double len, radius, center_x, center_y, beginrad, midrad, endrad, phit;
3810 if (
CalcR( prev, radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
3812 len = fabs( phit * radius );
3815 len = sqrt( pow( prev->m_x1 -
m_x1, 2 ) + pow( prev->m_y1 -
m_y1, 2 ) );
3823 radius, center_x, center_y, beginrad, midrad, endrad, phit );
3831 a2dVpath::a2dVpath()
3834 a2dVpath::a2dVpath(
a2dVertexArray& vertexArray,
bool moveToFirst,
bool closeLast )
3836 Add( vertexArray, moveToFirst, closeLast );
3839 a2dVpath::a2dVpath(
a2dVertexList& vertexList,
bool moveToFirst,
bool closeLast )
3841 Add( vertexList, moveToFirst, closeLast );
3851 for ( i = 0; i < other.size(); i++ )
3863 for ( i = 0; i < vertexArray.size(); i++ )
3867 if ( i == vertexArray.size() - 1 && closeLast )
3869 if ( seg->GetArc() )
3885 for( a2dVertexList::iterator iter = vertexList.begin(); iter != vertexList.end(); ++iter )
3889 if ( *iter == vertexList.back() && closeLast )
3891 if ( seg->GetArc() )
3930 back().Get(), x1, y1, cmd );
3938 x1, y1, x2, y2, x3, y3, cmd );
3946 back().Get(), x1, y1, x3, y3, cmd );
3954 x1, y1, x2, y2, cmd );
3962 back().Get(), xc, yc, angle, cmd );
3966 void a2dVpath::ArcTo(
double xc,
double yc,
double x1,
double y1,
double x2,
double y2,
bool withStroke )
3970 back().Get(), xc, yc, x1, y1, x2, y2, cmd );
3988 for ( i = 1; i < size(); i++ )
3990 len = len + Item( i )->Length( Item( i - 1 ) );
3996 void a2dVpath::RemoveAt(
size_t index )
3999 for( a2dVpath::iterator iter = begin(); iter != end(); ++iter )
4013 for( a2dVpath::iterator iter = begin(); iter != end(); ++iter )
4017 insert( iter, segment );
4030 for ( i = 0; i < size(); i++ )
4033 switch ( seg->GetType() )
4055 for ( i = 0; i < size(); i++ )
4058 switch ( seg->GetType() )
4083 for ( i = 0; i < size(); i++ )
4086 switch ( seg->GetType() )
4116 cworld.
TransformPoint( seg->m_x1, seg->m_y1, seg->m_x1, seg->m_y1 );
4126 for ( i = 0; i < size(); i++ )
4129 switch ( seg->GetType() )
4156 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
4159 if ( cseg->
CalcR( Item( i ? i - 1 : 0 ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
4161 lworld.
TransformPoint( center_x + radius , center_y + radius, x, y );
4163 lworld.
TransformPoint( center_x + radius , center_y - radius, x, y );
4165 lworld.
TransformPoint( center_x - radius , center_y + radius, x, y );
4167 lworld.
TransformPoint( center_x - radius , center_y - radius, x, y );
4187 bool nostroke =
false;
4190 double tstep = 1 / ( double ) VPATHSPLINE_STEP;
4192 for ( i = 0; i < size(); i++ )
4195 switch ( seg->GetType() )
4203 double xwl = Item( i ? i - 1 : 0 )->m_x1;
4204 double ywl = Item( i ? i - 1 : 0 )->m_y1;
4209 for ( step = 0; step <= VPATHSPLINE_STEP; step++ )
4211 xw = xwl * pow( 1 - t, 3 ) + cseg->
m_x2 * pow( 1 - t, 2 ) * t * 3 + cseg->
m_x3 * ( 1 - t ) * t * t * 3 + cseg->
m_x1 * pow( t, 3 );
4212 yw = ywl * pow( 1 - t, 3 ) + cseg->
m_y2 * pow( 1 - t, 2 ) * t * 3 + cseg->
m_y3 * ( 1 - t ) * t * t * 3 + cseg->
m_y1 * pow( t, 3 );
4218 if ( step == VPATHSPLINE_STEP )
4221 Insert( segn, i++ );
4234 double xwl = Item( i ? i - 1 : 0 )->m_x1;
4235 double ywl = Item( i ? i - 1 : 0 )->m_y1;
4240 for ( step = 0; step <= VPATHSPLINE_STEP; step++ )
4242 xw = xwl * pow( 1 - t, 2 ) + cseg->
m_x2 * ( 1 - t ) * t * 2 + cseg->
m_x1 * pow( t, 2 );
4243 yw = ywl * pow( 1 - t, 2 ) + cseg->
m_y2 * ( 1 - t ) * t * 2 + cseg->
m_y1 * pow( t, 2 );
4249 if ( step == VPATHSPLINE_STEP )
4252 Insert( segn, i++ );
4265 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
4267 if ( cseg->
CalcR( Item( i ? i - 1 : 0 ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
4270 unsigned int segments;
4271 Aberration( radius / 200, phit, radius , dphi, segments );
4274 double theta = beginrad;
4277 for ( step = 0; step < segments + 1; step++ )
4279 xw = center_x + radius * cos ( theta );
4280 yw = center_y + radius * sin ( theta );
4286 if ( step == segments )
4289 Insert( segn, i++ );
4290 theta = theta + dphi;
4301 Insert( segn, i++ );
4316 bool nostroke =
false;
4318 double tstep = 1 / ( double ) VPATHSPLINE_STEP;
4321 for ( i = 0; i < size(); i++ )
4324 switch ( seg->GetType() )
4329 addTo.push_back( result );
4347 double xwl = Item( i ? i - 1 : 0 )->m_x1;
4348 double ywl = Item( i ? i - 1 : 0 )->m_y1;
4353 for ( step = 0; step <= VPATHSPLINE_STEP; step++ )
4355 xw = xwl * pow( 1 - t, 3 ) + cseg->
m_x2 * pow( 1 - t, 2 ) * t * 3 + cseg->
m_x3 * ( 1 - t ) * t * t * 3 + cseg->
m_x1 * pow( t, 3 );
4356 yw = ywl * pow( 1 - t, 3 ) + cseg->
m_y2 * pow( 1 - t, 2 ) * t * 3 + cseg->
m_y3 * ( 1 - t ) * t * t * 3 + cseg->
m_y1 * pow( t, 3 );
4369 double xwl = Item( i ? i - 1 : 0 )->m_x1;
4370 double ywl = Item( i ? i - 1 : 0 )->m_y1;
4375 for ( step = 0; step <= VPATHSPLINE_STEP; step++ )
4377 xw = xwl * pow( 1 - t, 2 ) + cseg->
m_x2 * ( 1 - t ) * t * 2 + cseg->
m_x1 * pow( t, 2 );
4378 yw = ywl * pow( 1 - t, 2 ) + cseg->
m_y2 * ( 1 - t ) * t * 2 + cseg->
m_y1 * pow( t, 2 );
4393 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
4395 if ( cseg->
CalcR( Item( i ? i - 1 : 0 ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
4398 unsigned int segments;
4399 Aberration( radius / 200, phit, radius , dphi, segments );
4402 double theta = beginrad;
4405 for ( step = 0; step < segments + 1; step++ )
4407 xw = center_x + radius * cos ( theta );
4408 yw = center_y + radius * sin ( theta );
4410 theta = theta + dphi;
4439 int subpartstart = 0;
4440 int subpartLength = 0;
4441 while ( i < size() )
4444 switch ( seg->GetType() )
4465 SingleContour( totalconverted, subpartstart, subpartLength, distance, pathtype );
4473 if ( subpartLength )
4476 SingleContour( totalconverted, subpartstart, subpartLength, distance, pathtype );
4479 *
this = totalconverted;
4483 void a2dVpath::SingleContour(
a2dVpath& converted,
unsigned int start,
unsigned int segments,
double distance,
a2dPATH_END_TYPE pathtype )
4492 unsigned int insertAt = converted.size();
4496 if ( segments == 1 )
4501 case a2dPATH_END_SQAURE:
4506 case a2dPATH_END_ROUND:
4511 converted.
Add( segn );
4514 case a2dPATH_END_SQAURE_EXT:
4529 _middle =
a2dPoint2D( segnext->m_x1, segnext->m_y1 );
4530 a2dLine line1( _first, _middle );
4531 line1.CalculateLineParameters();
4532 offsetpointleft = _first;
4533 offsetpointright = _first;
4534 line1.Virtual_Point( offsetpointleft, distance );
4535 line1.Virtual_Point( offsetpointright, -distance );
4539 case a2dPATH_END_SQAURE:
4545 case a2dPATH_END_ROUND:
4547 a2dLine lineoffset( offsetpointright, offsetpointleft );
4548 lineoffset.CalculateLineParameters();
4551 offsetpointfirst = _first;
4552 lineoffset.Virtual_Point( offsetpointfirst, distance );
4554 offsetpointfirst.m_x, offsetpointfirst.m_y,
4559 case a2dPATH_END_SQAURE_EXT:
4561 a2dLine lineoffset( offsetpointright, offsetpointleft );
4562 lineoffset.CalculateLineParameters();
4563 lineoffset.Virtual_Point( offsetpointleft, distance );
4564 lineoffset.Virtual_Point( offsetpointright, distance );
4578 for ( i = start + 1; i < start + segments - 1; i++ )
4583 _middle =
a2dPoint2D( segnext->m_x1, segnext->m_y1 );
4584 a2dLine line1( _first, _middle );
4586 _end =
a2dPoint2D( segend->m_x1, segend->m_y1 );
4587 a2dLine line2( _middle, _end );
4588 line1.CalculateLineParameters();
4589 line2.CalculateLineParameters();
4591 OUTPRODUCT _outproduct;
4592 _outproduct = line1.OutProduct( line2, 1e-9 );
4594 switch ( _outproduct )
4599 line1.OffsetContour( line2, distance, offsetpointleft );
4600 line1.OffsetContour( line2, -distance, offsetpointright );
4605 line1.OffsetContour( line2, distance, offsetpointleft );
4606 line1.OffsetContour( line2, -distance, offsetpointright );
4612 offsetpointleft = _middle;
4613 offsetpointright = _middle;
4614 line1.Virtual_Point( offsetpointleft, distance );
4615 line1.Virtual_Point( offsetpointright, -distance );
4619 wxFAIL_MSG( wxT(
"wrong line code" ) );
4627 seg = Item( i - 1 );
4633 _middle =
a2dPoint2D( segnext->m_x1, segnext->m_y1 );
4634 a2dLine line1( _first, _middle );
4636 _end =
a2dPoint2D( segend->m_x1, segend->m_y1 );
4637 a2dLine line2( _middle, _end );
4638 line1.CalculateLineParameters();
4639 line2.CalculateLineParameters();
4641 OUTPRODUCT _outproduct;
4642 _outproduct = line1.OutProduct( line2, 1e-9 );
4644 switch ( _outproduct )
4649 line1.OffsetContour( line2, distance, offsetpointleft );
4650 line1.OffsetContour( line2, -distance, offsetpointright );
4655 line1.OffsetContour( line2, distance, offsetpointleft );
4656 line1.OffsetContour( line2, -distance, offsetpointright );
4662 offsetpointleft = _middle;
4663 offsetpointright = _middle;
4664 line1.Virtual_Point( offsetpointleft, distance );
4665 line1.Virtual_Point( offsetpointright, -distance );
4669 wxFAIL_MSG( wxT(
"wrong line code" ) );
4677 segnext = Item( i - segments + 1 );
4685 _end =
a2dPoint2D( segnext->m_x1, segnext->m_y1 );
4686 a2dLine line1( _first, _end );
4687 line1.CalculateLineParameters();
4688 offsetpointleft = _end;
4689 offsetpointright = _end;
4690 line1.Virtual_Point( offsetpointleft, distance );
4691 line1.Virtual_Point( offsetpointright, -distance );
4695 case a2dPATH_END_SQAURE:
4701 case a2dPATH_END_ROUND:
4703 a2dLine lineoffset( offsetpointleft, offsetpointright );
4704 lineoffset.CalculateLineParameters();
4707 offsetpointend = _end;
4708 lineoffset.Virtual_Point( offsetpointend, distance );
4711 offsetpointend.m_x, offsetpointend.m_y,
4716 case a2dPATH_END_SQAURE_EXT:
4718 a2dLine lineoffset( offsetpointright, offsetpointleft );
4719 lineoffset.CalculateLineParameters();
4720 lineoffset.Virtual_Point( offsetpointleft, -distance );
4721 lineoffset.Virtual_Point( offsetpointright, -distance );
4750 #define half(z1, z2) ((z1+z2)/2.0)
4754 static void gds_quadratic_spline(
a2dVertexList* org,
double a1,
double b1,
double a2,
double b2,
double a3,
double b3,
double a4,
4755 double b4,
double Aber )
4757 register double xmid, ymid;
4758 double x1, y1, x2, y2, x3, y3, x4, y4;
4762 gds_spline_push( a1, b1, a2, b2, a3, b3, a4, b4 );
4764 while ( gds_spline_pop( &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4 ) )
4766 xmid = half( x2, x3 );
4767 ymid = half( y2, y3 );
4768 if ( fabs( x1 - xmid ) < Aber && fabs( y1 - ymid ) < Aber &&
4769 fabs( xmid - x4 ) < Aber && fabs( ymid - y4 ) < Aber )
4772 org->push_back( point );
4774 org->push_back( point );
4778 gds_spline_push( xmid, ymid, half( xmid, x3 ), half( ymid, y3 ),
4779 half( x3, x4 ), half( y3, y4 ), x4, y4 );
4780 gds_spline_push( x1, y1, half( x1, x2 ), half( y1, y2 ),
4781 half( x2, xmid ), half( y2, ymid ), xmid, ymid );
4786 bool CalcR(
double begin_x,
double begin_y,
double middle_x,
double middle_y,
double end_x,
double end_y,
4789 double center_x, center_y, beginrad, midrad, endrad, phit;
4790 bool ret =
CalcR( begin_x, begin_y, middle_x, middle_y, end_x, end_y,
4791 radius, center_x, center_y, beginrad, midrad, endrad, phit );
4792 center_p.m_x = center_x;
4793 center_p.m_y = center_y;
4797 bool CalcR(
double begin_x,
double begin_y,
double middle_x,
double middle_y,
double end_x,
double end_y,
4798 double& radius,
double& center_x,
double& center_y,
double& beginrad,
double& midrad,
double& endrad,
double& phit )
4800 double ax, ay, bx, by, cx, cy;
4801 double ax2, ay2, bx2, by2, cx2, cy2;
4803 bool straight =
false;
4805 ax = begin_x; ay = begin_y; ax2 = pow( ax, 2 ); ay2 = pow( ay, 2 );
4806 bx = middle_x; by = middle_y; bx2 = pow( bx, 2 ); by2 = pow( by, 2 );
4807 cx = end_x; cy = end_y; cx2 = pow( cx, 2 ); cy2 = pow( cy, 2 );
4812 center_x = ( bx + ax ) / 2.0;
4813 center_y = ( by + ay ) / 2.0;
4814 radius = sqrt( pow( bx - ax, 2 ) + pow( by - ay, 2 ) ) / 2.0;
4818 d = 2 * ( ay * cx + by * ax - by * cx - ay * bx - cy * ax + cy * bx );
4826 center_x = ( by * ax2 - cy * ax2 - by2 * ay + cy2 * ay + bx2 * cy + ay2 * by
4827 + cx2 * ay - cy2 * by - cx2 * by - bx2 * ay + by2 * cy - ay2 * cy
4830 center_y = ( ax2 * cx + ay2 * cx + bx2 * ax - bx2 * cx + by2 * ax - by2 * cx
4831 - ax2 * bx - ay2 * bx - cx2 * ax + cx2 * bx - cy2 * ax + cy2 * bx
4834 radius = sqrt( pow( ax - center_x, 2 ) + pow( ay - center_y, 2 ) );
4840 beginrad = atan2( begin_y - center_y, begin_x - center_x );
4841 midrad = atan2( middle_y - center_y, middle_x - center_x );
4842 endrad = atan2( end_y - center_y, end_x - center_x );
4850 mr = midrad - beginrad;
4851 er = endrad - beginrad;
4854 if ( mr <= 0 ) mr += 2.0 * M_PI;
4855 if ( er <= 0 ) er += 2.0 * M_PI;
4856 if ( mr >= 2.0 * M_PI ) mr -= 2.0 * M_PI;
4857 if ( er >= 2.0 * M_PI ) er -= 2.0 * M_PI;
4865 counterclock =
true;
4869 phit = -( 2.0 * M_PI - er );
4870 counterclock =
false;
4888 double x1, y1, x2, y2, x3, y3, x4, y4;
4892 #define SPLINE_STACK_DEPTH 20
4893 static Stack gds_spline_stack[SPLINE_STACK_DEPTH];
4894 static Stack* gds_stack_top;
4895 static int gds_stack_count;
4897 static void gds_clear_stack()
4899 gds_stack_top = gds_spline_stack;
4900 gds_stack_count = 0;
4903 static void gds_spline_push(
double x1,
double y1,
double x2,
double y2,
double x3,
double y3,
double x4,
double y4 )
4905 gds_stack_top->x1 = x1;
4906 gds_stack_top->y1 = y1;
4907 gds_stack_top->x2 = x2;
4908 gds_stack_top->y2 = y2;
4909 gds_stack_top->x3 = x3;
4910 gds_stack_top->y3 = y3;
4911 gds_stack_top->x4 = x4;
4912 gds_stack_top->y4 = y4;
4917 static int gds_spline_pop(
double* x1,
double* y1,
double* x2,
double* y2,
4918 double* x3,
double* y3,
double* x4,
double* y4 )
4920 if ( gds_stack_count == 0 )
4924 *x1 = gds_stack_top->x1;
4925 *y1 = gds_stack_top->y1;
4926 *x2 = gds_stack_top->x2;
4927 *y2 = gds_stack_top->y2;
4928 *x3 = gds_stack_top->x3;
4929 *y3 = gds_stack_top->y3;
4930 *x4 = gds_stack_top->x4;
4931 *y4 = gds_stack_top->y4;
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
virtual double Length(a2dVpathSegmentPtr prev)
calculate length
bool IsPolygon(bool allowArc=true)
test if closed polygon ( a2dPATHSEG_MOVETO, a2dPATHSEG_LINETO, a2dPATHSEG_ARCTO ) ...
virtual a2dVpathSegment * Clone()
create exact copy
a2dPATH_END_TYPE
defines the way a polyline with a contour width is ended.
unsigned int m_index
For edge/vertex hits the index of the edge / vertex.
virtual double Length(const a2dLineSegment &prev)
calculate length
virtual a2dVpathSegment * Clone()
create exact copy
void ConvertToLines()
Convert complex segments to line segments.
double Length() const
calculate length of path
void InsertArc(a2dVertexList::iterator &iter, int n, double center_x, double center_y)
a2dVpath * ConvertToVpath(bool arc, bool closed=false)
return converted vector Vpath, arc segments stay intact if arc is true
Simple Memory manager for some objects which often create and destroy to replace OS-system calls...
#define a2dACCUR
accuracy used to have some limit to calculation like hittesting
fundamental classes used by all other modules.
void ConvertToLines(double aberation=0)
Convert complex segments to line segments.
~a2dVpathArcSegment()
destructor
double Length()
calculate length of path, assuming continues path.
a2dVertexArray()
constructor
void Transform(const a2dAffineMatrix &world)
transform all segments with given matrix
a2dLineSegment(double x=0, double y=0)
constructor
static a2dHit stock_nohit
Stock object for no hit.
a2dHit HitTestPolyline(const a2dPoint2D &ptest, double margin)
extensive hittesting on vertex list seen as polyline.
static a2dHit stock_strokeinside
Stock object for an inner stroke hit on objects without vertices/edges (like circles) ...
void CBCurveTo(double x1, double y1, double x2, double y2, double x3, double y3, bool withStroke=true)
add a quadratic bezier segment to the path
double wxDegToRad(double deg)
conversion from degrees to radians
bool RemoveRedundant(bool polygon)
line segments ( not arcs ) with same point are removed
a2dBoundingBox GetBbox(const a2dAffineMatrix &lworld=a2dIDENTITY_MATRIX)
return a boundingbox of a transformed vertexarray
void Transform(const a2dAffineMatrix &world)
transform all segments with given matrix
a2dVertexArray * Contour(double distance, a2dPATH_END_TYPE pathtype)
create a contour around polygon/polyline
double m_y3
control point 2
bool IsIdentity(void) const
Is the matrix the identity matrix?
double m_x3
control point 2
double m_x2
x2 x of arc midpoint
a2dPoint2D GetEndPoint() const
Get the endpoint from a a2dLine.
double ClclDistSqrPntPnt(const a2dPoint2D &a, const a2dPoint2D &b)
Calculate the square distance between two points.
a2dVpathSegment(double x, double y, a2dPATHSEG type=a2dPATHSEG_LINETO, a2dPATHSEG_END close=a2dPATHSEG_END_OPEN)
constructor
double GetValue(int col, int row) const
get the value in the matrix at col,row
a2dPoint2D GetOrigin(const a2dLineSegment &prev) const
Get origin of arc.
a2dVpath & operator=(const a2dVpath &other)
operator =
a2dGlobal * a2dGlobals
global a2dCanvasGlobal to have easy access to global settings
void Close(bool withStroke=true)
Closing the path as a filled area.
double ClclDistSqrPntLine(const a2dPoint2D &p, const a2dPoint2D &p1, const a2dPoint2D &p2)
Calculate the square distance between a point and a line.
virtual double Length(a2dSmrtPtr< a2dVpathSegment > prev)
calculate length
void ArcTo(double x1, double y1, double x2, double y2, bool withStroke=true)
add an arc segment to the path
a2dVertexList * ConvertSplinedPolyline(double Aber) const
Spline conversion for polyline.
float m_distance
For margin hits, the distance from the stroke center in fractions of the margin.
Arc Segment in a2dVertexList.
a2dLine * CreatePerpendicularLineAt(const a2dPoint2D &a_point) const
create a line through a_point and which is pperpendicular to this
vertex array of line and arc segments.
a2dPATHSEG_END m_close
is the path closing here or not
double m_y2
control point 1
R_PointStatus PointOnLine(const a2dPoint2D &a_Point, double &Distance, double Marge) const
For an infinite a2dLine.
not specific or part of outer contour
void ConvertPolylineToArc(double aber, double Rmin, double Rmax)
void OffsetContour_rounded(const a2dLine ¤tline, const a2dLine &nextline, double factor, bool addAtFront)
create a contour segements at a distance, using two segment
a2dPATHSEG m_type
easy way to test type of segment
vertex list of line and arc segments.
void TransformPoint(double x, double y, double &tx, double &ty) const
Transform a point.
Id based property system with its base a2dPropertyId.
a2dBoundingBox GetBbox(const a2dAffineMatrix &lworld=a2dIDENTITY_MATRIX)
return a boundingbox of a transformed vertexarray
virtual double Length(const a2dLineSegment &prev)
calculate length
general vertexlist and array and vector path functions and classes.
a2dVertexList * ConvertSplinedPolygon(double Aber) const
Spline conversion for polygon.
void Transform(const a2dAffineMatrix &world)
transform all segments with given matrix
~a2dVpathCBCurveSegment()
destructor
a2dVertexArray * ConvertSplinedPolyline(double Aber) const
Spline conversion for polyline.
a2dPATHSEG
how do we move to the point of the segment
~a2dVpathQBCurveSegment()
destructor
a2dVpath * ConvertToVpath(bool arc, bool closed=false)
return converted vector Vpath, arc segments stay intact if arc is true
OUTPRODUCT OutProduct(const a2dLine &two, double accur) const
outproduct of two wxLines
classes for initializing the artbase modules, and set paths to be used for fonts etc.
bool HasArcs() const
return true if there are a2dArcSegment segments.
bool CalcR(const a2dLineSegment &prev, double &radius, double ¢er_x, double ¢er_y, double &beginrad, double &midrad, double &endrad, double &phit) const
Calculation of center for the Arc.
double m_y2
second control point
void Expand(const a2dPoint2D &, const a2dPoint2D &)
expand boundingbox width two points
void Virtual_Point(a2dPoint2D &a_point, double distance) const
calculate point Perpendicula at distance from the line, through given point
bool m_bin
Marker for walking over the segments.
void SetPointAdjustArcs(unsigned int n, double x, double y, bool polygon)
sets a point of a segment and adjusts arc it midpoints.
void AddPoint(const a2dPoint2D &point, bool atEnd=true)
add point to end or begin
a2dBoundingBox GetBbox(const a2dLineSegment &prev, const a2dAffineMatrix &lworld=a2dIDENTITY_MATRIX) const
Get bounding box of arc.
bool IsTranslate(void) const
Is the matrix only a translation?
void Insert(unsigned int index, a2dLineSegmentPtr segin)
insert before segment with index given
The point is in the fill area.
Normal straight line segment in a2dVpath.
a2dSegType m_segtype
type of segment
a2dVpathQBCurveSegment(double x1, double y1, double x2, double y2, a2dPATHSEG type=a2dPATHSEG_QBCURVETO, a2dPATHSEG_END close=a2dPATHSEG_END_OPEN)
constructor
a2dVertexList::iterator GetPreviousAround(a2dVertexList::iterator iter)
get the previous segment as a polygon ( –end() is no previous )
Normal straight line segment in a2dVertexList and a2dVertexArray.
int TestArc(a2dVertexList::iterator &iter, double aber, double Rmin, double Rmax, a2dPoint2D ¢er_p_old)
a row of point (minimum 4 ) will be tested to see if its an arc.
bool CalcR(a2dVpathSegmentPtr prev, double &radius, double ¢er_x, double ¢er_y, double &beginrad, double &midrad, double &endrad, double &phit)
Calculation of center for the Arc.
a2dVertexArray * ConvertSplinedPolygon(double Aber) const
Spline conversion for polygon.
void CalculateLineParameters()
Calculate the parameters if invalid.
a2dVpathArcSegment(double x1, double y1, double x2, double y2, a2dPATHSEG type=a2dPATHSEG_ARCTO, a2dPATHSEG_END close=a2dPATHSEG_END_OPEN)
create arc segment
a2dVertexList * GetRedundant(bool polygon, double smallest=0)
line segments ( not arcs ) with same point are returned
void Add(a2dVpathSegment *seg)
add a segment
a2dVertexArray & operator=(const a2dVertexArray &other)
operator =
a2dVertexList::iterator GetNextAround(a2dVertexList::iterator iter)
get the next segment as a polygon ( begin() is no next )
a2dHit HitTestPolyline(const a2dPoint2D &ptest, double margin)
extensive hittesting on vertex list seen as polyline.
virtual double Length(a2dVpathSegmentPtr prev)
calculate length
static double GetRoundFactor()
void QBCurveTo(double x1, double y1, double x2, double y2, bool withStroke=true)
add a quadratic bezier segment to the path
virtual double Length(a2dVpathSegmentPtr prev)
calculate length
double m_x2
control point 1
bool RemoveRedundant(bool polygon)
line segments ( not arcs ) with same point are removed
A 2x3 affine matrix class for 2D transformations.
void PositionAt(a2dVpathSegmentPtr prev, double t, double &xt, double &yt)
calculate position at t, used for length
a2dVertexList * ConvertToContour(double distance, a2dPATH_END_TYPE pathtype, bool asPolygon=false)
create a contour around polygon/polyline
double GetOy(const a2dLineSegment &prev) const
Get origin Y of arc.
virtual a2dVpathSegment * Clone()
create exact copy
virtual ~a2dVpathSegment()
destructor
double m_y2
y2 y of arc midpoint
int IndexOf(a2dLineSegment *object) const
Find the index of a specific object.
void ConvertIntoSplinedPolygon(double Aber)
virtual a2dLineSegment * Clone()
create exact copy
double GetOx(const a2dLineSegment &prev) const
Get origin X of arc.
double m_x
x endpoint of line
struct for how a single object on one layer was hit
~a2dVertexArray()
destructor
~a2dArcSegment()
destructor
a2dPoint2D ProjectedPoint(const a2dPoint2D &p) const
return point after projecting p to this line.
double m_y
y endpoint of line
void Aberration(double aber, double angle, double radius, double &dphi, unsigned int &segments)
calculate number of segments in an arc such that a certain accuracy is maintained ...
static a2dHit stock_strokeoutside
Stock object for an outer stroke hit on objects without vertices/edges (like circles) ...
a2dHit HitTestPolygon(const a2dPoint2D &ptest, double margin)
extensive hittesting on vertex list seen as polygon.
double m_y1
y endpoint of line
bool InArc(double angle, double start, double end, bool clockwise)
void MoveTo(double x, double y)
add a MoveTo command to the path
virtual a2dLineSegment * Clone()
create exact copy
bool HasArcs() const
return true if there are a2dArcSegment segments.
void SetPointAdjustArcs(unsigned int n, double x, double y, bool polygon)
sets a point of a segment and adjusts arc it midpoints.
a2dVertexList * GetRedundant(bool polygon, double smallest=0)
line segments ( not arcs ) with same point are returned
a2dPoint2D GetBeginPoint() const
Get the beginpoint from a a2dLine.
a2dVpathCBCurveSegment(double x1, double y1, double x2, double y2, double x3, double y3, a2dPATHSEG type=a2dPATHSEG_CBCURVETO, a2dPATHSEG_END close=a2dPATHSEG_END_OPEN)
constructor
void AddPoint(const a2dPoint2D &point, bool atEnd=true)
add point to end or begin
void LineTo(double x, double y, bool withStroke=true)
add a LineTo command to the path
a2dHit HitTestPolygon(const a2dPoint2D &ptest, double margin)
extensive hittesting on vertex list seen as polygon.
bool IsPolyline(bool allowArc=true)
test if polyline ( a2dPATHSEG_MOVETO, a2dPATHSEG_LINETO, a2dPATHSEG_ARCTO )
a2dPATHSEG_END
end of a segment type
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
a2dBoundingBox GetBbox(const a2dAffineMatrix &lworld=a2dIDENTITY_MATRIX)
return a boundingbox of a transformed a2dVpath
void OffsetContour(const a2dLine &nextline, double factor, a2dPoint2D &offsetpoint) const
Calculate point for a contour at a given distance.
void Contour(double distance, a2dPATH_END_TYPE pathtype)
create an offset contour at distance
virtual a2dVpathSegment * Clone()
create exact copy
The object is not hit. This should not happen, because the parent should include hit childs...
static a2dHit stock_fill
Stock object for a fill hit.
double Length()
calculate length of path
void PositionAt(a2dVpathSegmentPtr prev, double t, double &xt, double &yt)
calculate position at t, used for length
double m_x1
x endpoint of line
void ConvertToPolygon(a2dListOfa2dVertexList &addTo, bool arc=true)
bool CalcR(double begin_x, double begin_y, double middle_x, double middle_y, double end_x, double end_y, double &radius, a2dPoint2D ¢er_p)
Calculation of center for the Arc.
static double GetAberArcToPoly()
conversion from arc into lines in database units
The point is on the stroke or stroke margin.
void ConvertToLines(double aberation=0)
Convert complex segments to line segments.
double m_x2
second control point
void MakeBegin(a2dVertexList::iterator iter)
make the segmenet where iter point to the beginning of the list and shift the rest ...
bool DirectionIsClockWise()
void CreateArc(const a2dPoint2D ¢er, const a2dPoint2D &begin, const a2dPoint2D &end, double radius, bool clock, double aber, bool addAtFront)
create an arc and add it to the graph
basic 2 point line class for intersection and contouring routines.
a2dLineSegmentPtr GetPreviousAround(wxUint32 index) const
get the previous segment as a polygon ( GetLast() is no previous )
a2dLineSegmentPtr GetNextAround(wxUint32 index) const
get the next segment as a polygon ( GetFirst() is no next )
const double wxPI
defines PI
void SetMidPoint(const a2dLineSegment &prev, double xm, double ym)
set middle point of arc segment
void Contour(double distance, a2dPATH_END_TYPE pathtype, bool asPolygon=false)
create a contour around polygon/polyline
a2dArcSegment(double x1=0, double y1=0, double x2=0, double y2=0)
create arc segment
int Intersect(a2dLine &line, a2dPoint2D &bp, a2dPoint2D &ep, double Marge) const
Intersects two wxLines.
void CalcMidPoint(const a2dLineSegment &prev, double center_x, double center_y, double radius, bool clockwise)
calculate new mid point bsed on prev segment radius and center.