Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
90a6daa7
Commit
90a6daa7
authored
Aug 01, 2012
by
jean-pierre charras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup math_for_graphic code
parent
dfdd2cfd
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
123 additions
and
942 deletions
+123
-942
zones_test_and_combine_areas.cpp
pcbnew/zones_test_and_combine_areas.cpp
+6
-8
PolyLine.cpp
polygon/PolyLine.cpp
+3
-7
math_for_graphics.cpp
polygon/math_for_graphics.cpp
+87
-921
math_for_graphics.h
polygon/math_for_graphics.h
+27
-6
No files found.
pcbnew/zones_test_and_combine_areas.cpp
View file @
90a6daa7
...
...
@@ -387,8 +387,8 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
yf2
=
poly2
->
GetY
(
is2
);
}
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
STRAIGHT
,
xi2
,
yi2
,
xf2
,
yf2
,
STRAIGHT
);
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
xi2
,
yi2
,
xf2
,
yf2
);
if
(
n_int
)
return
true
;
}
...
...
@@ -498,8 +498,8 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_
yf2
=
poly2
->
GetY
(
is2
);
}
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
STRAIGHT
,
xi2
,
yi2
,
xf2
,
yf2
,
STRAIGHT
);
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
xi2
,
yi2
,
xf2
,
yf2
);
if
(
n_int
)
{
bInt
=
true
;
...
...
@@ -844,10 +844,8 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
int
x
,
y
;
int
d
=
GetClearanceBetweenSegments
(
bx1
,
by1
,
bx2
,
by2
,
STRAIGHT
,
0
,
ax1
,
ay1
,
ax2
,
ay2
,
STRAIGHT
,
0
,
zone2zoneClearance
,
&
x
,
&
y
);
...
...
@@ -987,9 +985,9 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
}
int
x
,
y
;
// variables containing the intersecting point coordinates
int
d
=
GetClearanceBetweenSegments
(
bx1
,
by1
,
bx2
,
by2
,
STRAIGHT
,
int
d
=
GetClearanceBetweenSegments
(
bx1
,
by1
,
bx2
,
by2
,
0
,
ax1
,
ay1
,
ax2
,
ay2
,
STRAIGHT
,
ax1
,
ay1
,
ax2
,
ay2
,
0
,
zone_clearance
,
&
x
,
&
y
);
...
...
polygon/PolyLine.cpp
View file @
90a6daa7
...
...
@@ -1112,7 +1112,6 @@ void CPolyLine::Hatch()
m_CornersList
[
ic
].
x
,
m_CornersList
[
ic
].
y
,
m_CornersList
[
i_start_contour
].
x
,
m_CornersList
[
i_start_contour
].
y
,
STRAIGHT
,
&
x
,
&
y
,
&
x2
,
&
y2
);
i_start_contour
=
ic
+
1
;
}
...
...
@@ -1121,7 +1120,6 @@ void CPolyLine::Hatch()
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
m_CornersList
[
ic
].
x
,
m_CornersList
[
ic
].
y
,
m_CornersList
[
ic
+
1
].
x
,
m_CornersList
[
ic
+
1
].
y
,
STRAIGHT
,
&
x
,
&
y
,
&
x2
,
&
y2
);
}
...
...
@@ -1387,9 +1385,9 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth )
by2
=
GetY
(
ic2
+
1
);
}
int
d
=
GetClearanceBetweenSegments
(
bx1
,
by1
,
bx2
,
by2
,
STRAIGHT
,
0
,
int
d
=
GetClearanceBetweenSegments
(
bx1
,
by1
,
bx2
,
by2
,
0
,
aStart
.
x
,
aStart
.
y
,
aEnd
.
x
,
aEnd
.
y
,
STRAIGHT
,
aWidth
,
aWidth
,
1
,
// min clearance, should be > 0
NULL
,
NULL
);
...
...
@@ -1689,9 +1687,7 @@ bool CPolyLine::IsPolygonSelfIntersecting()
int
x2f
=
GetX
(
is2_next
);
int
y2f
=
GetY
(
is2_next
);
int
ret
=
FindSegmentIntersections
(
x1i
,
y1i
,
x1f
,
y1f
,
STRAIGHT
,
x2i
,
y2i
,
x2f
,
y2f
,
STRAIGHT
);
x2i
,
y2i
,
x2f
,
y2f
);
if
(
ret
)
{
// intersection between non-adjacent sides
...
...
polygon/math_for_graphics.cpp
View file @
90a6daa7
...
...
@@ -11,42 +11,13 @@
#include <PolyLine.h>
#include <math_for_graphics.h>
#define NM_PER_MIL 25400
typedef
struct
PointTag
{
double
X
,
Y
;
}
PointT
;
typedef
struct
EllipseTag
{
PointT
Center
;
/* ellipse center */
double
xrad
,
yrad
;
// radii on x and y
double
theta1
,
theta2
;
// start and end angle for arc
}
EllipseKH
;
static
bool
InRange
(
double
x
,
double
xi
,
double
xf
);
double
Distance
(
double
x1
,
double
y1
,
double
x2
,
double
y2
)
{
double
dx
=
x1
-
x2
;
double
dy
=
y1
-
y2
;
double
d
=
sqrt
(
dx
*
dx
+
dy
*
dy
);
return
d
;
return
hypot
(
x1
-
x2
,
y1
-
y2
);
}
static
bool
Quadratic
(
double
a
,
double
b
,
double
c
,
double
*
x1
,
double
*
x2
);
static
bool
FindLineEllipseIntersections
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x1
,
double
*
x2
);
static
bool
FindVerticalLineEllipseIntersections
(
double
a
,
double
b
,
double
x
,
double
*
y1
,
double
*
y2
);
static
int
GetArcIntersections
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
double
*
x1
=
NULL
,
double
*
y1
=
NULL
,
double
*
x2
=
NULL
,
double
*
y2
=
NULL
);
static
bool
InRange
(
double
x
,
double
xi
,
double
xf
);
enum
m_SideStyle
{
STRAIGHT
,
ARC_CW
,
ARC_CCW
};
// side styles
/**
* Function TestLineHit
* test for hit on line segment i.e. a point within a given distance from segment
...
...
@@ -109,271 +80,33 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
}
// set EllipseKH struct to describe the ellipse for an arc
//
int
MakeEllipseFromArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
EllipseKH
*
el
)
{
// arc (quadrant of ellipse)
// convert to clockwise arc
int
xxi
,
xxf
,
yyi
,
yyf
;
if
(
style
==
ARC_CCW
)
{
xxi
=
xf
;
xxf
=
xi
;
yyi
=
yf
;
yyf
=
yi
;
}
else
{
xxi
=
xi
;
xxf
=
xf
;
yyi
=
yi
;
yyf
=
yf
;
}
// find center and radii of ellipse
double
xo
=
0
,
yo
=
0
;
if
(
xxf
>
xxi
&&
yyf
>
yyi
)
{
xo
=
xxf
;
yo
=
yyi
;
el
->
theta1
=
M_PI
;
el
->
theta2
=
M_PI
/
2.0
;
}
else
if
(
xxf
<
xxi
&&
yyf
>
yyi
)
{
xo
=
xxi
;
yo
=
yyf
;
el
->
theta1
=
-
M_PI
/
2.0
;
el
->
theta2
=
-
M_PI
;
}
else
if
(
xxf
<
xxi
&&
yyf
<
yyi
)
{
xo
=
xxf
;
yo
=
yyi
;
el
->
theta1
=
0.0
;
el
->
theta2
=
-
M_PI
/
2.0
;
}
else
if
(
xxf
>
xxi
&&
yyf
<
yyi
)
{
xo
=
xxi
;
yo
=
yyf
;
el
->
theta1
=
M_PI
/
2.0
;
el
->
theta2
=
0.0
;
}
el
->
Center
.
X
=
xo
;
el
->
Center
.
Y
=
yo
;
el
->
xrad
=
abs
(
xf
-
xi
);
el
->
yrad
=
abs
(
yf
-
yi
);
#if 0
el->Phi = 0.0;
el->MaxRad = el->xrad;
el->MinRad = el->yrad;
if( el->MaxRad < el->MinRad )
{
el->MaxRad = el->yrad;
el->MinRad = el->xrad;
el->Phi = M_PI / 2.0;
}
#endif
return
0
;
}
// find intersections between line segment (xi,yi) to (xf,yf)
// and line segment (xi2,yi2) to (xf2,yf2)
// the line segments may be arcs (i.e. quadrant of an ellipse) or straight
// returns number of intersections found (max of 2)
// returns coords of intersections in arrays x[2], y[2]
//
int
FindSegmentIntersections
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
int
xi2
,
int
yi2
,
int
xf2
,
int
yf2
,
int
style2
,
double
x
[],
double
y
[]
)
/* Function FindSegmentIntersections
* find intersections between line segment (xi,yi) to (xf,yf)
* and line segment (xi2,yi2) to (xf2,yf2)
* returns true if intersection found
*/
bool
FindSegmentIntersections
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xi2
,
int
yi2
,
int
xf2
,
int
yf2
)
{
double
xr
[
12
],
yr
[
12
];
int
iret
=
0
;
if
(
max
(
xi
,
xf
)
<
min
(
xi2
,
xf2
)
||
min
(
xi
,
xf
)
>
max
(
xi2
,
xf2
)
||
max
(
yi
,
yf
)
<
min
(
yi2
,
yf2
)
||
min
(
yi
,
yf
)
>
max
(
yi2
,
yf2
)
)
return
0
;
if
(
style
!=
STRAIGHT
&&
style2
!=
STRAIGHT
)
{
// two identical arcs intersect
if
(
style
==
style2
&&
xi
==
xi2
&&
yi
==
yi2
&&
xf
==
xf2
&&
yf
==
yf2
)
{
if
(
x
&&
y
)
{
x
[
0
]
=
xi
;
y
[
0
]
=
yi
;
}
return
1
;
}
else
if
(
style
!=
style2
&&
xi
==
xf2
&&
yi
==
yf2
&&
xf
==
xi2
&&
yf
==
yi2
)
{
if
(
x
&&
y
)
{
x
[
0
]
=
xi
;
y
[
0
]
=
yi
;
}
return
1
;
}
}
if
(
style
==
STRAIGHT
&&
style2
==
STRAIGHT
)
{
// both straight-line segments
int
x
,
y
;
bool
bYes
=
TestForIntersectionOfStraightLineSegments
(
xi
,
yi
,
xf
,
yf
,
xi2
,
yi2
,
xf2
,
yf2
,
&
x
,
&
y
);
if
(
!
bYes
)
return
0
;
xr
[
0
]
=
x
;
yr
[
0
]
=
y
;
iret
=
1
;
}
else
if
(
style
==
STRAIGHT
)
{
// first segment is straight, second segment is an arc
int
ret
;
double
x1r
,
y1r
,
x2r
,
y2r
;
if
(
xf
==
xi
)
{
// vertical first segment
double
a
=
xi
;
double
b
=
DBL_MAX
/
2.0
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
else
{
double
b
=
(
double
)
(
yf
-
yi
)
/
(
double
)
(
xf
-
xi
);
double
a
=
yf
-
b
*
xf
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
if
(
ret
==
0
)
return
0
;
if
(
InRange
(
x1r
,
xi
,
xf
)
&&
InRange
(
y1r
,
yi
,
yf
)
)
{
xr
[
iret
]
=
x1r
;
yr
[
iret
]
=
y1r
;
iret
++
;
}
if
(
ret
==
2
)
{
if
(
InRange
(
x2r
,
xi
,
xf
)
&&
InRange
(
y2r
,
yi
,
yf
)
)
{
xr
[
iret
]
=
x2r
;
yr
[
iret
]
=
y2r
;
iret
++
;
}
}
}
else
if
(
style2
==
STRAIGHT
)
{
// first segment is an arc, second segment is straight
int
ret
;
double
x1r
,
y1r
,
x2r
,
y2r
;
if
(
xf2
==
xi2
)
{
// vertical second segment
double
a
=
xi2
;
double
b
=
DBL_MAX
/
2.0
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi
,
yi
,
xf
,
yf
,
style
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
else
{
double
b
=
(
double
)
(
yf2
-
yi2
)
/
(
double
)
(
xf2
-
xi2
);
double
a
=
yf2
-
b
*
xf2
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi
,
yi
,
xf
,
yf
,
style
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
if
(
ret
==
0
)
return
0
;
if
(
InRange
(
x1r
,
xi2
,
xf2
)
&&
InRange
(
y1r
,
yi2
,
yf2
)
)
{
xr
[
iret
]
=
x1r
;
yr
[
iret
]
=
y1r
;
iret
++
;
}
if
(
ret
==
2
)
{
if
(
InRange
(
x2r
,
xi2
,
xf2
)
&&
InRange
(
y2r
,
yi2
,
yf2
)
)
{
xr
[
iret
]
=
x2r
;
yr
[
iret
]
=
y2r
;
iret
++
;
}
}
}
else
{
// both segments are arcs
EllipseKH
el1
;
EllipseKH
el2
;
MakeEllipseFromArc
(
xi
,
yi
,
xf
,
yf
,
style
,
&
el1
);
MakeEllipseFromArc
(
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
&
el2
);
int
n
;
if
(
el1
.
xrad
+
el1
.
yrad
>
el2
.
xrad
+
el2
.
yrad
)
n
=
GetArcIntersections
(
&
el1
,
&
el2
);
else
n
=
GetArcIntersections
(
&
el2
,
&
el1
);
iret
=
n
;
}
if
(
x
&&
y
)
{
for
(
int
i
=
0
;
i
<
iret
;
i
++
)
{
x
[
i
]
=
xr
[
i
];
y
[
i
]
=
yr
[
i
];
}
}
return
false
;
return
iret
;
return
TestForIntersectionOfStraightLineSegments
(
xi
,
yi
,
xf
,
yf
,
xi2
,
yi2
,
xf2
,
yf2
);
}
// find intersection between line y = a + bx and line segment (xi,yi) to (xf,yf)
// if b > DBL_MAX/10, assume vertical line at x = a
// the line segment may be an arc (i.e. quadrant of an ellipse)
// return 0 if no intersection
// returns 1 or 2 if intersections found
// sets coords of intersections in *x1, *y1, *x2, *y2
// if no intersection, returns min distance in dist
//
int
FindLineSegmentIntersection
(
double
a
,
double
b
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
/* Function FindLineSegmentIntersection
* find intersection between line y = a + bx and line segment (xi,yi) to (xf,yf)
* if b > DBL_MAX/10, assume vertical line at x = a
* return false if no intersection or true if intersect
* return coords of intersections in *x1, *y1, *x2, *y2
* if no intersection, returns min distance in dist
*/
bool
FindLineSegmentIntersection
(
double
a
,
double
b
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
,
double
*
dist
)
{
...
...
@@ -383,10 +116,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
if
(
b
>
DBL_MAX
/
10.0
)
bVert
=
true
;
if
(
xf
!=
xi
)
{
// non-vertical segment, get intersection
if
(
style
==
STRAIGHT
||
yf
==
yi
)
if
(
xf
!=
xi
)
// non-vertical segment, get intersection
{
// horizontal or oblique straight segment
// put into form y = c + dx;
...
...
@@ -407,7 +137,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
if
(
dist
)
*
dist
=
min
(
abs
(
a
-
xi
),
abs
(
a
-
xf
)
);
return
0
;
return
false
;
}
}
...
...
@@ -419,7 +149,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
*
dist
=
GetPointToLineDistance
(
a
,
b
,
xi
,
xf
);
}
return
0
;
// lines parallel
return
false
;
// lines parallel
}
// calculate intersection
...
...
@@ -431,140 +161,21 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
{
// horizontal line
if
(
(
xx
>=
xi
&&
xx
>
xf
)
||
(
xx
<=
xi
&&
xx
<
xf
)
)
return
0
;
return
false
;
}
else
{
// oblique line
if
(
(
xx
>=
xi
&&
xx
>
xf
)
||
(
xx
<=
xi
&&
xx
<
xf
)
||
(
yy
>
yi
&&
yy
>
yf
)
||
(
yy
<
yi
&&
yy
<
yf
)
)
return
0
;
}
}
else
if
(
style
==
ARC_CW
||
style
==
ARC_CCW
)
{
// arc (quadrant of ellipse)
// convert to clockwise arc
int
xxi
,
xxf
,
yyi
,
yyf
;
if
(
style
==
ARC_CCW
)
{
xxi
=
xf
;
xxf
=
xi
;
yyi
=
yf
;
yyf
=
yi
;
}
else
{
xxi
=
xi
;
xxf
=
xf
;
yyi
=
yi
;
yyf
=
yf
;
}
// find center and radii of ellipse
double
xo
=
xxf
,
yo
=
yyi
,
rx
,
ry
;
// Init made to avoid C compil warnings
if
(
xxf
>
xxi
&&
yyf
>
yyi
)
{
xo
=
xxf
;
yo
=
yyi
;
}
else
if
(
xxf
<
xxi
&&
yyf
>
yyi
)
{
xo
=
xxi
;
yo
=
yyf
;
}
else
if
(
xxf
<
xxi
&&
yyf
<
yyi
)
{
xo
=
xxf
;
yo
=
yyi
;
}
else
if
(
xxf
>
xxi
&&
yyf
<
yyi
)
{
xo
=
xxi
;
yo
=
yyf
;
}
rx
=
fabs
(
(
double
)
(
xxi
-
xxf
)
);
ry
=
fabs
(
(
double
)
(
yyi
-
yyf
)
);
bool
test
;
double
xx1
,
xx2
,
yy1
,
yy2
,
aa
;
if
(
bVert
)
{
// shift vertical line to coordinate system of ellipse
aa
=
a
-
xo
;
test
=
FindVerticalLineEllipseIntersections
(
rx
,
ry
,
aa
,
&
yy1
,
&
yy2
);
if
(
!
test
)
return
0
;
// shift back to PCB coordinates
yy1
+=
yo
;
yy2
+=
yo
;
xx1
=
a
;
xx2
=
a
;
}
else
{
// shift line to coordinate system of ellipse
aa
=
a
+
b
*
xo
-
yo
;
test
=
FindLineEllipseIntersections
(
rx
,
ry
,
aa
,
b
,
&
xx1
,
&
xx2
);
if
(
!
test
)
return
0
;
// shift back to PCB coordinates
yy1
=
aa
+
b
*
xx1
;
xx1
+=
xo
;
yy1
+=
yo
;
yy2
=
aa
+
b
*
xx2
;
xx2
+=
xo
;
yy2
+=
yo
;
}
int
npts
=
0
;
if
(
(
xxf
>
xxi
&&
xx1
<
xxf
&&
xx1
>
xxi
)
||
(
xxf
<
xxi
&&
xx1
<
xxi
&&
xx1
>
xxf
)
)
{
if
(
(
yyf
>
yyi
&&
yy1
<
yyf
&&
yy1
>
yyi
)
||
(
yyf
<
yyi
&&
yy1
<
yyi
&&
yy1
>
yyf
)
)
{
*
x1
=
xx1
;
*
y1
=
yy1
;
npts
=
1
;
}
}
if
(
(
xxf
>
xxi
&&
xx2
<
xxf
&&
xx2
>
xxi
)
||
(
xxf
<
xxi
&&
xx2
<
xxi
&&
xx2
>
xxf
)
)
{
if
(
(
yyf
>
yyi
&&
yy2
<
yyf
&&
yy2
>
yyi
)
||
(
yyf
<
yyi
&&
yy2
<
yyi
&&
yy2
>
yyf
)
)
{
if
(
npts
==
0
)
{
*
x1
=
xx2
;
*
y1
=
yy2
;
npts
=
1
;
}
else
{
*
x2
=
xx2
;
*
y2
=
yy2
;
npts
=
2
;
}
}
return
false
;
}
return
npts
;
}
else
wxASSERT
(
0
);
}
else
{
// vertical line segment
if
(
bVert
)
return
0
;
return
false
;
xx
=
xi
;
yy
=
a
+
b
*
xx
;
...
...
@@ -575,7 +186,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
*
x1
=
xx
;
*
y1
=
yy
;
return
1
;
return
true
;
}
...
...
@@ -645,7 +256,7 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
a
=
(
double
)
y2i
-
b
*
x2i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
...
...
@@ -673,7 +284,7 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
a
=
(
double
)
y2i
-
b
*
x2i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
...
...
@@ -701,7 +312,7 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
a
=
(
double
)
y1i
-
b
*
x1i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
...
...
@@ -729,7 +340,7 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
a
=
(
double
)
y1i
-
b
*
x1i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
...
...
@@ -759,17 +370,8 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
a
=
(
double
)
y1i
-
b
*
x1i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
// both segments oblique
if
(
test
)
...
...
@@ -836,62 +438,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
}
/*solves the Quadratic equation = a*x*x + b*x + c
/* Function GetClearanceBetweenSegments
* Get clearance between 2 segments
* Returns coordinates of the closest point between these 2 segments in x, y
* If clearance > max_cl, just returns max_cl+1 and doesn't return x,y
*/
bool
Quadratic
(
double
a
,
double
b
,
double
c
,
double
*
x1
,
double
*
x2
)
{
double
root
=
b
*
b
-
4.0
*
a
*
c
;
if
(
root
<
0.0
)
return
false
;
root
=
sqrt
(
root
);
*
x1
=
(
-
b
+
root
)
/
(
2.0
*
a
);
*
x2
=
(
-
b
-
root
)
/
(
2.0
*
a
);
return
true
;
}
// finds intersections of vertical line at x
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// returns true if solution exist, with solutions in y1 and y2
// else returns false
//
bool
FindVerticalLineEllipseIntersections
(
double
a
,
double
b
,
double
x
,
double
*
y1
,
double
*
y2
)
{
double
y_sqr
=
(
1.0
-
(
x
*
x
)
/
(
a
*
a
)
)
*
b
*
b
;
if
(
y_sqr
<
0.0
)
return
false
;
*
y1
=
sqrt
(
y_sqr
);
*
y2
=
-*
y1
;
return
true
;
}
// finds intersections of straight line y = c + dx
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// returns true if solution exist, with solutions in x1 and x2
// else returns false
//
bool
FindLineEllipseIntersections
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x1
,
double
*
x2
)
{
// quadratic terms
double
A
=
d
*
d
+
b
*
b
/
(
a
*
a
);
double
B
=
2.0
*
c
*
d
;
double
C
=
c
*
c
-
b
*
b
;
return
Quadratic
(
A
,
B
,
C
,
x1
,
x2
);
}
// Get clearance between 2 segments
// Returns point in segment closest to other segment in x, y
// in clearance > max_cl, just returns max_cl+1 and doesn't return x,y
//
int
GetClearanceBetweenSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
style1
,
int
w1
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
style2
,
int
w2
,
int
GetClearanceBetweenSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
w1
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
w2
,
int
max_cl
,
int
*
x
,
int
*
y
)
{
// check clearance between bounding rectangles
...
...
@@ -909,14 +462,11 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
if
(
min
(
y2i
,
y2f
)
-
max
(
y1i
,
y1f
)
>
min_dist
)
return
max_cl
+
1
;
if
(
style1
==
STRAIGHT
&&
style1
==
STRAIGHT
)
{
// both segments are straight lines
int
xx
,
yy
;
double
dd
;
double
dist
;
TestForIntersectionOfStraightLineSegments
(
x1i
,
y1i
,
x1f
,
y1f
,
x2i
,
y2i
,
x2f
,
y2f
,
&
xx
,
&
yy
,
&
dd
);
int
d
=
(
int
)
dd
-
(
(
w1
+
w2
)
/
2
);
x2i
,
y2i
,
x2f
,
y2f
,
&
xx
,
&
yy
,
&
dist
);
int
d
=
(
int
)
dist
-
(
(
w1
+
w2
)
/
2
);
if
(
d
<
0
)
d
=
0
;
...
...
@@ -927,187 +477,14 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
*
y
=
yy
;
return
d
;
}
// not both straight-line segments
// see if segments intersect
double
xr
[
2
];
double
yr
[
2
];
int
count
=
FindSegmentIntersections
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
xr
,
yr
);
if
(
count
)
{
if
(
x
)
*
x
=
(
int
)
xr
[
0
];
if
(
y
)
*
y
=
(
int
)
yr
[
0
];
return
0
;
}
// at least one segment is an arc
EllipseKH
el1
;
EllipseKH
el2
;
bool
bArcs
;
int
xi
=
0
,
yi
=
0
,
xf
=
0
,
yf
=
0
;
if
(
style2
==
STRAIGHT
)
{
// style1 = arc, style2 = straight
MakeEllipseFromArc
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
&
el1
);
xi
=
x2i
;
yi
=
y2i
;
xf
=
x2f
;
yf
=
y2f
;
bArcs
=
false
;
}
else
if
(
style1
==
STRAIGHT
)
{
// style2 = arc, style1 = straight
xi
=
x1i
;
yi
=
y1i
;
xf
=
x1f
;
yf
=
y1f
;
MakeEllipseFromArc
(
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
&
el1
);
bArcs
=
false
;
}
else
{
// style1 = arc, style2 = arc
MakeEllipseFromArc
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
&
el1
);
MakeEllipseFromArc
(
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
&
el2
);
bArcs
=
true
;
}
const
int
NSTEPS
=
32
;
if
(
el1
.
theta2
>
el1
.
theta1
)
{
wxASSERT
(
0
);
}
if
(
bArcs
&&
el2
.
theta2
>
el2
.
theta1
)
{
wxASSERT
(
0
);
}
// test multiple points in both segments
double
th1
;
double
th2
;
double
len2
;
if
(
bArcs
)
{
th1
=
el2
.
theta1
;
th2
=
el2
.
theta2
;
len2
=
max
(
el2
.
xrad
,
el2
.
yrad
);
}
else
{
th1
=
1.0
;
th2
=
0.0
;
len2
=
abs
(
xf
-
xi
)
+
abs
(
yf
-
yi
);
}
double
s_start
=
el1
.
theta1
;
double
s_end
=
el1
.
theta2
;
double
s_start2
=
th1
;
double
s_end2
=
th2
;
double
dmin
=
DBL_MAX
;
double
xmin
=
0
,
ymin
=
0
,
smin
=
0
,
smin2
=
0
;
// Init made to avoid C compil warnings
int
nsteps
=
NSTEPS
;
int
nsteps2
=
NSTEPS
;
double
step
=
(
s_start
-
s_end
)
/
(
nsteps
-
1
);
double
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
while
(
(
step
*
max
(
el1
.
xrad
,
el1
.
yrad
)
)
>
0.1
*
NM_PER_MIL
&&
(
step2
*
len2
)
>
0.1
*
NM_PER_MIL
)
{
step
=
(
s_start
-
s_end
)
/
(
nsteps
-
1
);
for
(
int
i
=
0
;
i
<
nsteps
;
i
++
)
{
double
s
;
if
(
i
<
nsteps
-
1
)
s
=
s_start
-
i
*
step
;
else
s
=
s_end
;
double
x
=
el1
.
Center
.
X
+
el1
.
xrad
*
cos
(
s
);
double
y
=
el1
.
Center
.
Y
+
el1
.
yrad
*
sin
(
s
);
// if not an arc, use s2 as fractional distance along line
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
for
(
int
i2
=
0
;
i2
<
nsteps2
;
i2
++
)
{
double
s2
;
if
(
i2
<
nsteps2
-
1
)
s2
=
s_start2
-
i2
*
step2
;
else
s2
=
s_end2
;
double
x2
,
y2
;
if
(
!
bArcs
)
{
x2
=
xi
+
(
xf
-
xi
)
*
s2
;
y2
=
yi
+
(
yf
-
yi
)
*
s2
;
}
else
{
x2
=
el2
.
Center
.
X
+
el2
.
xrad
*
cos
(
s2
);
y2
=
el2
.
Center
.
Y
+
el2
.
yrad
*
sin
(
s2
);
}
double
d
=
Distance
(
x
,
y
,
x2
,
y2
);
if
(
d
<
dmin
)
{
dmin
=
d
;
xmin
=
x
;
ymin
=
y
;
smin
=
s
;
smin2
=
s2
;
}
}
}
if
(
step
>
step2
)
{
s_start
=
min
(
el1
.
theta1
,
smin
+
step
);
s_end
=
max
(
el1
.
theta2
,
smin
-
step
);
step
=
(
s_start
-
s_end
)
/
nsteps
;
}
else
{
s_start2
=
min
(
th1
,
smin2
+
step2
);
s_end2
=
max
(
th2
,
smin2
-
step2
);
step2
=
(
s_start2
-
s_end2
)
/
nsteps2
;
}
}
if
(
x
)
*
x
=
(
int
)
xmin
;
if
(
y
)
*
y
=
(
int
)
ymin
;
return
max
(
0
,
(
int
)
dmin
-
w1
/
2
-
w2
/
2
);
// allow for widths
}
// Get min. distance from (x,y) to line y = a + bx
// if b > DBL_MAX/10, assume vertical line at x = a
// returns closest point on line in xp, yp
//
/* Function GetPointToLineDistance
* Get min. distance from (x,y) to line y = a + bx
* if b > DBL_MAX/10, assume vertical line at x = a
* returns closest point on line in xpp, ypp
*/
double
GetPointToLineDistance
(
double
a
,
double
b
,
int
x
,
int
y
,
double
*
xpp
,
double
*
ypp
)
{
if
(
b
>
DBL_MAX
/
10
)
...
...
@@ -1141,9 +518,6 @@ double GetPointToLineDistance( double a, double b, int x, int y, double* xpp, do
}
/***********************************************************************************/
double
GetPointToLineSegmentDistance
(
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
)
/***********************************************************************************/
/**
* Function GetPointToLineSegmentDistance
* Get distance between line segment and point
...
...
@@ -1152,6 +526,7 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
* @param xf,yf End point of the line segment
* @return the distance
*/
double
GetPointToLineSegmentDistance
(
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
)
{
// test for vertical or horizontal segment
if
(
xf
==
xi
)
...
...
@@ -1195,7 +570,6 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
// test for value within range
//
bool
InRange
(
double
x
,
double
xi
,
double
xf
)
{
if
(
xf
>
xi
)
...
...
@@ -1211,211 +585,3 @@ bool InRange( double x, double xi, double xf )
return
false
;
}
// this finds approximate solutions
// note: this works best if el2 is smaller than el1
//
int
GetArcIntersections
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
)
{
if
(
el1
->
theta2
>
el1
->
theta1
)
{
wxASSERT
(
0
);
}
if
(
el2
->
theta2
>
el2
->
theta1
)
{
wxASSERT
(
0
);
}
const
int
NSTEPS
=
32
;
double
xret
[
2
],
yret
[
2
];
double
xscale
=
1.0
/
el1
->
xrad
;
double
yscale
=
1.0
/
el1
->
yrad
;
// now transform params of second ellipse into reference frame
// with origin at center if first ellipse,
// scaled so the first ellipse is a circle of radius = 1.0
double
xo
=
(
el2
->
Center
.
X
-
el1
->
Center
.
X
)
*
xscale
;
double
yo
=
(
el2
->
Center
.
Y
-
el1
->
Center
.
Y
)
*
yscale
;
double
xr
=
el2
->
xrad
*
xscale
;
double
yr
=
el2
->
yrad
*
yscale
;
// now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta)
double
step
=
M_PI
/
(
(
NSTEPS
-
1
)
*
2.0
);
double
d_prev
=
0
;
double
th_interp
;
double
th1
;
int
n
=
0
;
for
(
int
i
=
0
;
i
<
NSTEPS
;
i
++
)
{
double
theta
;
if
(
i
<
NSTEPS
-
1
)
theta
=
el2
->
theta1
-
i
*
step
;
else
theta
=
el2
->
theta2
;
double
x
=
xo
+
xr
*
cos
(
theta
);
double
y
=
yo
+
yr
*
sin
(
theta
);
double
d
=
1.0
-
sqrt
(
x
*
x
+
y
*
y
);
if
(
i
>
0
)
{
bool
bInt
=
false
;
if
(
d
>=
0.0
&&
d_prev
<=
0.0
)
{
th_interp
=
theta
+
(
step
*
(
-
d_prev
)
)
/
(
d
-
d_prev
);
bInt
=
true
;
}
else
if
(
d
<=
0.0
&&
d_prev
>=
0.0
)
{
th_interp
=
theta
+
(
step
*
d_prev
)
/
(
d_prev
-
d
);
bInt
=
true
;
}
if
(
bInt
)
{
x
=
xo
+
xr
*
cos
(
th_interp
);
y
=
yo
+
yr
*
sin
(
th_interp
);
th1
=
atan2
(
y
,
x
);
if
(
th1
<=
el1
->
theta1
&&
th1
>=
el1
->
theta2
)
{
xret
[
n
]
=
x
*
el1
->
xrad
+
el1
->
Center
.
X
;
yret
[
n
]
=
y
*
el1
->
yrad
+
el1
->
Center
.
Y
;
n
++
;
if
(
n
>
2
)
{
wxASSERT
(
0
);
}
}
}
}
d_prev
=
d
;
}
if
(
x1
)
*
x1
=
xret
[
0
];
if
(
y1
)
*
y1
=
yret
[
0
];
if
(
x2
)
*
x2
=
xret
[
1
];
if
(
y2
)
*
y2
=
yret
[
1
];
return
n
;
}
// this finds approximate solution
//
// double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
double
GetArcClearance
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
double
*
x1
,
double
*
y1
)
{
const
int
NSTEPS
=
32
;
if
(
el1
->
theta2
>
el1
->
theta1
)
{
wxASSERT
(
0
);
}
if
(
el2
->
theta2
>
el2
->
theta1
)
{
wxASSERT
(
0
);
}
// test multiple positions in both arcs, moving clockwise (ie. decreasing theta)
double
th_start
=
el1
->
theta1
;
double
th_end
=
el1
->
theta2
;
double
th_start2
=
el2
->
theta1
;
double
th_end2
=
el2
->
theta2
;
double
dmin
=
DBL_MAX
;
double
xmin
=
0
,
ymin
=
0
,
thmin
=
0
,
thmin2
=
0
;
int
nsteps
=
NSTEPS
;
int
nsteps2
=
NSTEPS
;
double
step
=
(
th_start
-
th_end
)
/
(
nsteps
-
1
);
double
step2
=
(
th_start2
-
th_end2
)
/
(
nsteps2
-
1
);
while
(
(
step
*
max
(
el1
->
xrad
,
el1
->
yrad
)
)
>
1.0
*
NM_PER_MIL
&&
(
step2
*
max
(
el2
->
xrad
,
el2
->
yrad
)
)
>
1.0
*
NM_PER_MIL
)
{
step
=
(
th_start
-
th_end
)
/
(
nsteps
-
1
);
for
(
int
i
=
0
;
i
<
nsteps
;
i
++
)
{
double
theta
;
if
(
i
<
nsteps
-
1
)
theta
=
th_start
-
i
*
step
;
else
theta
=
th_end
;
double
x
=
el1
->
Center
.
X
+
el1
->
xrad
*
cos
(
theta
);
double
y
=
el1
->
Center
.
Y
+
el1
->
yrad
*
sin
(
theta
);
step2
=
(
th_start2
-
th_end2
)
/
(
nsteps2
-
1
);
for
(
int
i2
=
0
;
i2
<
nsteps2
;
i2
++
)
{
double
theta2
;
if
(
i2
<
nsteps2
-
1
)
theta2
=
th_start2
-
i2
*
step2
;
else
theta2
=
th_end2
;
double
x2
=
el2
->
Center
.
X
+
el2
->
xrad
*
cos
(
theta2
);
double
y2
=
el2
->
Center
.
Y
+
el2
->
yrad
*
sin
(
theta2
);
double
d
=
Distance
(
x
,
y
,
x2
,
y2
);
if
(
d
<
dmin
)
{
dmin
=
d
;
xmin
=
x
;
ymin
=
y
;
thmin
=
theta
;
thmin2
=
theta2
;
}
}
}
if
(
step
>
step2
)
{
th_start
=
min
(
el1
->
theta1
,
thmin
+
step
);
th_end
=
max
(
el1
->
theta2
,
thmin
-
step
);
step
=
(
th_start
-
th_end
)
/
nsteps
;
}
else
{
th_start2
=
min
(
el2
->
theta1
,
thmin2
+
step2
);
th_end2
=
max
(
el2
->
theta2
,
thmin2
-
step2
);
step2
=
(
th_start2
-
th_end2
)
/
nsteps2
;
}
}
if
(
x1
)
*
x1
=
xmin
;
if
(
y1
)
*
y1
=
ymin
;
return
dmin
;
}
polygon/math_for_graphics.h
View file @
90a6daa7
...
...
@@ -10,12 +10,23 @@
*/
bool
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
);
int
FindLineSegmentIntersection
(
double
a
,
double
b
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
/* Function FindLineSegmentIntersection
* find intersection between line y = a + bx and line segment (xi,yi) to (xf,yf)
* if b > DBL_MAX/10, assume vertical line at x = a
* return false if no intersection or true if intersect
* return coords of intersections in *x1, *y1, *x2, *y2
* if no intersection, returns min distance in dist
*/
bool
FindLineSegmentIntersection
(
double
a
,
double
b
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
,
double
*
dist
=
NULL
);
int
FindSegmentIntersections
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
int
xi2
,
int
yi2
,
int
xf2
,
int
yf2
,
int
style2
,
double
x
[]
=
NULL
,
double
y
[]
=
NULL
);
/* Function FindSegmentIntersections
* find intersections between line segment (xi,yi) to (xf,yf)
* and line segment (xi2,yi2) to (xf2,yf2)
* returns true if intersection found
*/
bool
FindSegmentIntersections
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xi2
,
int
yi2
,
int
xf2
,
int
yf2
);
/**
* Function TestForIntersectionOfStraightLineSegments
...
...
@@ -34,8 +45,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
*
x
=
NULL
,
int
*
y
=
NULL
,
double
*
dist
=
NULL
);
int
GetClearanceBetweenSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
style1
,
int
w1
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
style2
,
int
w2
,
/* Function GetClearanceBetweenSegments
* Get clearance between 2 segments
* Returns coordinates of the closest point between these 2 segments in x, y
* If clearance > max_cl, just returns max_cl+1 and doesn't return x,y
*/
int
GetClearanceBetweenSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
w1
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
w2
,
int
max_cl
,
int
*
x
,
int
*
y
);
/**
...
...
@@ -47,6 +63,11 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
*/
double
GetPointToLineSegmentDistance
(
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
);
/* Function GetPointToLineDistance
* Get min. distance from (x,y) to line y = a + bx
* if b > DBL_MAX/10, assume vertical line at x = a
* returns closest point on line in xpp, ypp
*/
double
GetPointToLineDistance
(
double
a
,
double
b
,
int
x
,
int
y
,
double
*
xp
=
NULL
,
double
*
yp
=
NULL
);
double
Distance
(
double
x1
,
double
y1
,
double
x2
,
double
y2
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment