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
72d4b235
Commit
72d4b235
authored
Apr 17, 2012
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uncrustify math_for_graphics, add copyright legacy_plugin.h
parent
597833b5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
563 additions
and
354 deletions
+563
-354
base_screen.cpp
common/base_screen.cpp
+2
-4
legacy_plugin.h
pcbnew/legacy_plugin.h
+4
-3
math_for_graphics.cpp
polygon/math_for_graphics.cpp
+557
-347
No files found.
common/base_screen.cpp
View file @
72d4b235
...
@@ -94,7 +94,7 @@ double BASE_SCREEN::GetScalingFactor() const
...
@@ -94,7 +94,7 @@ double BASE_SCREEN::GetScalingFactor() const
}
}
void
BASE_SCREEN
::
SetScalingFactor
(
double
aScale
)
void
BASE_SCREEN
::
SetScalingFactor
(
double
aScale
)
{
{
double
zoom
=
aScale
;
double
zoom
=
aScale
;
...
@@ -150,12 +150,10 @@ bool BASE_SCREEN::SetZoom( double coeff )
...
@@ -150,12 +150,10 @@ bool BASE_SCREEN::SetZoom( double coeff )
bool
BASE_SCREEN
::
SetNextZoom
()
bool
BASE_SCREEN
::
SetNextZoom
()
{
{
size_t
i
;
if
(
m_ZoomList
.
IsEmpty
()
||
m_Zoom
>=
m_ZoomList
.
Last
()
)
if
(
m_ZoomList
.
IsEmpty
()
||
m_Zoom
>=
m_ZoomList
.
Last
()
)
return
false
;
return
false
;
for
(
i
=
0
;
i
<
m_ZoomList
.
GetCount
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
m_ZoomList
.
GetCount
();
i
++
)
{
{
if
(
m_Zoom
<
m_ZoomList
[
i
]
)
if
(
m_Zoom
<
m_ZoomList
[
i
]
)
{
{
...
...
pcbnew/legacy_plugin.h
View file @
72d4b235
...
@@ -4,7 +4,8 @@
...
@@ -4,7 +4,8 @@
/*
/*
* This program source code file is part of KiCad, a free EDA CAD application.
* This program source code file is part of KiCad, a free EDA CAD application.
*
*
* Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
*
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* modify it under the terms of the GNU General Public License
...
@@ -59,8 +60,6 @@ struct FPL_CACHE;
...
@@ -59,8 +60,6 @@ struct FPL_CACHE;
*/
*/
class
LEGACY_PLUGIN
:
public
PLUGIN
class
LEGACY_PLUGIN
:
public
PLUGIN
{
{
friend
struct
FPL_CACHE
;
public
:
public
:
//-----<PLUGIN IMPLEMENTATION>----------------------------------------------
//-----<PLUGIN IMPLEMENTATION>----------------------------------------------
...
@@ -272,6 +271,8 @@ protected:
...
@@ -272,6 +271,8 @@ protected:
/// we only cache one footprint library for now, this determines which one.
/// we only cache one footprint library for now, this determines which one.
void
cacheLib
(
const
wxString
&
aLibraryPath
);
void
cacheLib
(
const
wxString
&
aLibraryPath
);
friend
struct
FPL_CACHE
;
};
};
#endif // LEGACY_PLUGIN_H_
#endif // LEGACY_PLUGIN_H_
polygon/math_for_graphics.cpp
View file @
72d4b235
...
@@ -29,14 +29,16 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
...
@@ -29,14 +29,16 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
if
(
xf
==
xi
)
if
(
xf
==
xi
)
{
{
// vertical segment
// vertical segment
dd
=
fabs
(
(
double
)(
x
-
xi
)
);
dd
=
fabs
(
(
double
)
(
x
-
xi
)
);
if
(
dd
<
dist
&&
(
(
yf
>
yi
&&
y
<
yf
&&
y
>
yi
)
||
(
yf
<
yi
&&
y
>
yf
&&
y
<
yi
)
)
)
if
(
dd
<
dist
&&
(
(
yf
>
yi
&&
y
<
yf
&&
y
>
yi
)
||
(
yf
<
yi
&&
y
>
yf
&&
y
<
yi
)
)
)
return
true
;
return
true
;
}
}
else
if
(
yf
==
yi
)
else
if
(
yf
==
yi
)
{
{
// horizontal segment
// horizontal segment
dd
=
fabs
(
(
double
)(
y
-
yi
)
);
dd
=
fabs
(
(
double
)
(
y
-
yi
)
);
if
(
dd
<
dist
&&
(
(
xf
>
xi
&&
x
<
xf
&&
x
>
xi
)
||
(
xf
<
xi
&&
x
>
xf
&&
x
<
xi
)
)
)
if
(
dd
<
dist
&&
(
(
xf
>
xi
&&
x
<
xf
&&
x
>
xi
)
||
(
xf
<
xi
&&
x
>
xf
&&
x
<
xi
)
)
)
return
true
;
return
true
;
}
}
...
@@ -44,17 +46,18 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
...
@@ -44,17 +46,18 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
{
{
// oblique segment
// oblique segment
// find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx
// find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx
double
b
=
(
double
)(
yf
-
yi
)
/
(
xf
-
xi
);
double
b
=
(
double
)
(
yf
-
yi
)
/
(
xf
-
xi
);
double
a
=
(
double
)
yi
-
b
*
xi
;
double
a
=
(
double
)
yi
-
b
*
xi
;
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
double
d
=
-
1.0
/
b
;
double
d
=
-
1.0
/
b
;
double
c
=
(
double
)
y
-
d
*
x
;
double
c
=
(
double
)
y
-
d
*
x
;
// find nearest point to (x,y) on line segment (xi,yi) to (xf,yf)
// find nearest point to (x,y) on line segment (xi,yi) to (xf,yf)
double
xp
=
(
a
-
c
)
/
(
d
-
b
);
double
xp
=
(
a
-
c
)
/
(
d
-
b
);
double
yp
=
a
+
b
*
xp
;
double
yp
=
a
+
b
*
xp
;
// find distance
// find distance
dd
=
sqrt
((
x
-
xp
)
*
(
x
-
xp
)
+
(
y
-
yp
)
*
(
y
-
yp
));
dd
=
sqrt
(
(
x
-
xp
)
*
(
x
-
xp
)
+
(
y
-
yp
)
*
(
y
-
yp
)
);
if
(
fabs
(
b
)
>
0.7
)
if
(
fabs
(
b
)
>
0.7
)
{
{
// line segment more vertical than horizontal
// line segment more vertical than horizontal
if
(
dd
<
dist
&&
(
(
yf
>
yi
&&
yp
<
yf
&&
yp
>
yi
)
||
(
yf
<
yi
&&
yp
>
yf
&&
yp
<
yi
)
)
)
if
(
dd
<
dist
&&
(
(
yf
>
yi
&&
yp
<
yf
&&
yp
>
yi
)
||
(
yf
<
yi
&&
yp
>
yf
&&
yp
<
yi
)
)
)
...
@@ -67,17 +70,19 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
...
@@ -67,17 +70,19 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
return
true
;
return
true
;
}
}
}
}
return
false
;
// no hit
return
false
;
// no hit
}
}
// set EllipseKH struct to describe the ellipse for an arc
// set EllipseKH struct to describe the ellipse for an arc
//
//
int
MakeEllipseFromArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
EllipseKH
*
el
)
int
MakeEllipseFromArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
EllipseKH
*
el
)
{
{
// arc (quadrant of ellipse)
// arc (quadrant of ellipse)
// convert to clockwise arc
// convert to clockwise arc
int
xxi
,
xxf
,
yyi
,
yyf
;
int
xxi
,
xxf
,
yyi
,
yyf
;
if
(
style
==
CPolyLine
::
ARC_CCW
)
if
(
style
==
CPolyLine
::
ARC_CCW
)
{
{
xxi
=
xf
;
xxi
=
xf
;
...
@@ -92,54 +97,60 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e
...
@@ -92,54 +97,60 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e
yyi
=
yi
;
yyi
=
yi
;
yyf
=
yf
;
yyf
=
yf
;
}
}
// find center and radii of ellipse
// find center and radii of ellipse
double
xo
=
0
,
yo
=
0
;
double
xo
=
0
,
yo
=
0
;
if
(
xxf
>
xxi
&&
yyf
>
yyi
)
if
(
xxf
>
xxi
&&
yyf
>
yyi
)
{
{
xo
=
xxf
;
xo
=
xxf
;
yo
=
yyi
;
yo
=
yyi
;
el
->
theta1
=
M_PI
;
el
->
theta1
=
M_PI
;
el
->
theta2
=
M_PI
/
2.0
;
el
->
theta2
=
M_PI
/
2.0
;
}
}
else
if
(
xxf
<
xxi
&&
yyf
>
yyi
)
else
if
(
xxf
<
xxi
&&
yyf
>
yyi
)
{
{
xo
=
xxi
;
xo
=
xxi
;
yo
=
yyf
;
yo
=
yyf
;
el
->
theta1
=
-
M_PI
/
2.0
;
el
->
theta1
=
-
M_PI
/
2.0
;
el
->
theta2
=
-
M_PI
;
el
->
theta2
=
-
M_PI
;
}
}
else
if
(
xxf
<
xxi
&&
yyf
<
yyi
)
else
if
(
xxf
<
xxi
&&
yyf
<
yyi
)
{
{
xo
=
xxf
;
xo
=
xxf
;
yo
=
yyi
;
yo
=
yyi
;
el
->
theta1
=
0.0
;
el
->
theta1
=
0.0
;
el
->
theta2
=
-
M_PI
/
2.0
;
el
->
theta2
=
-
M_PI
/
2.0
;
}
}
else
if
(
xxf
>
xxi
&&
yyf
<
yyi
)
else
if
(
xxf
>
xxi
&&
yyf
<
yyi
)
{
{
xo
=
xxi
;
xo
=
xxi
;
yo
=
yyf
;
yo
=
yyf
;
el
->
theta1
=
M_PI
/
2.0
;
el
->
theta1
=
M_PI
/
2.0
;
el
->
theta2
=
0.0
;
el
->
theta2
=
0.0
;
}
}
el
->
Center
.
X
=
xo
;
el
->
Center
.
Y
=
yo
;
el
->
Center
.
X
=
xo
;
el
->
xrad
=
abs
(
xf
-
xi
);
el
->
Center
.
Y
=
yo
;
el
->
yrad
=
abs
(
yf
-
yi
);
el
->
xrad
=
abs
(
xf
-
xi
);
el
->
yrad
=
abs
(
yf
-
yi
);
#if 0
#if 0
el->Phi = 0.0;
el->Phi = 0.0;
el->MaxRad = el->xrad;
el->MaxRad = el->xrad;
el->MinRad = el->yrad;
el->MinRad = el->yrad;
if( el->MaxRad < el->MinRad )
if( el->MaxRad < el->MinRad )
{
{
el->MaxRad = el->yrad;
el->MaxRad
= el->yrad;
el->MinRad = el->xrad;
el->MinRad
= el->xrad;
el->Phi
= M_PI/
2.0;
el->Phi
= M_PI /
2.0;
}
}
#endif
#endif
return
0
;
return
0
;
}
}
// find intersections between line segment (xi,yi) to (xf,yf)
// find intersections between line segment (xi,yi) to (xf,yf)
// and line segment (xi2,yi2) to (xf2,yf2)
// and line segment (xi2,yi2) to (xf2,yf2)
// the line segments may be arcs (i.e. quadrant of an ellipse) or straight
// the line segments may be arcs (i.e. quadrant of an ellipse) or straight
...
@@ -147,16 +158,16 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e
...
@@ -147,16 +158,16 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e
// returns coords of intersections in arrays x[2], y[2]
// returns coords of intersections in arrays x[2], y[2]
//
//
int
FindSegmentIntersections
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
int
FindSegmentIntersections
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
int
xi2
,
int
yi2
,
int
xf2
,
int
yf2
,
int
style2
,
int
xi2
,
int
yi2
,
int
xf2
,
int
yf2
,
int
style2
,
double
x
[],
double
y
[]
)
double
x
[],
double
y
[]
)
{
{
double
xr
[
12
],
yr
[
12
];
double
xr
[
12
],
yr
[
12
];
int
iret
=
0
;
int
iret
=
0
;
if
(
max
(
xi
,
xf
)
<
min
(
xi2
,
xf2
)
if
(
max
(
xi
,
xf
)
<
min
(
xi2
,
xf2
)
||
min
(
xi
,
xf
)
>
max
(
xi2
,
xf2
)
||
min
(
xi
,
xf
)
>
max
(
xi2
,
xf2
)
||
max
(
yi
,
yf
)
<
min
(
yi2
,
yf2
)
||
max
(
yi
,
yf
)
<
min
(
yi2
,
yf2
)
||
min
(
yi
,
yf
)
>
max
(
yi2
,
yf2
)
)
||
min
(
yi
,
yf
)
>
max
(
yi2
,
yf2
)
)
return
0
;
return
0
;
if
(
style
!=
CPolyLine
::
STRAIGHT
&&
style2
!=
CPolyLine
::
STRAIGHT
)
if
(
style
!=
CPolyLine
::
STRAIGHT
&&
style2
!=
CPolyLine
::
STRAIGHT
)
...
@@ -166,18 +177,20 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
...
@@ -166,18 +177,20 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
{
{
if
(
x
&&
y
)
if
(
x
&&
y
)
{
{
x
[
0
]
=
xi
;
x
[
0
]
=
xi
;
y
[
0
]
=
yi
;
y
[
0
]
=
yi
;
}
}
return
1
;
return
1
;
}
}
else
if
(
style
!=
style2
&&
xi
==
xf2
&&
yi
==
yf2
&&
xf
==
xi2
&&
yf
==
yi2
)
else
if
(
style
!=
style2
&&
xi
==
xf2
&&
yi
==
yf2
&&
xf
==
xi2
&&
yf
==
yi2
)
{
{
if
(
x
&&
y
)
if
(
x
&&
y
)
{
{
x
[
0
]
=
xi
;
x
[
0
]
=
xi
;
y
[
0
]
=
yi
;
y
[
0
]
=
yi
;
}
}
return
1
;
return
1
;
}
}
}
}
...
@@ -185,48 +198,63 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
...
@@ -185,48 +198,63 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
if
(
style
==
CPolyLine
::
STRAIGHT
&&
style2
==
CPolyLine
::
STRAIGHT
)
if
(
style
==
CPolyLine
::
STRAIGHT
&&
style2
==
CPolyLine
::
STRAIGHT
)
{
{
// both straight-line segments
// both straight-line segments
int
x
,
y
;
int
x
,
y
;
bool
bYes
=
TestForIntersectionOfStraightLineSegments
(
xi
,
yi
,
xf
,
yf
,
xi2
,
yi2
,
xf2
,
yf2
,
&
x
,
&
y
);
bool
bYes
=
TestForIntersectionOfStraightLineSegments
(
xi
,
yi
,
xf
,
yf
,
xi2
,
yi2
,
xf2
,
yf2
,
&
x
,
&
y
);
if
(
!
bYes
)
if
(
!
bYes
)
return
0
;
return
0
;
xr
[
0
]
=
x
;
yr
[
0
]
=
y
;
xr
[
0
]
=
x
;
iret
=
1
;
yr
[
0
]
=
y
;
iret
=
1
;
}
}
else
if
(
style
==
CPolyLine
::
STRAIGHT
)
else
if
(
style
==
CPolyLine
::
STRAIGHT
)
{
{
// first segment is straight, second segment is an arc
// first segment is straight, second segment is an arc
int
ret
;
int
ret
;
double
x1r
,
y1r
,
x2r
,
y2r
;
double
x1r
,
y1r
,
x2r
,
y2r
;
if
(
xf
==
xi
)
if
(
xf
==
xi
)
{
{
// vertical first segment
// vertical first segment
double
a
=
xi
;
double
a
=
xi
;
double
b
=
DBL_MAX
/
2.0
;
double
b
=
DBL_MAX
/
2.0
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
}
else
else
{
{
double
b
=
(
double
)(
yf
-
yi
)
/
(
double
)(
xf
-
xi
);
double
b
=
(
double
)
(
yf
-
yi
)
/
(
double
)
(
xf
-
xi
);
double
a
=
yf
-
b
*
xf
;
double
a
=
yf
-
b
*
xf
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
}
if
(
ret
==
0
)
if
(
ret
==
0
)
return
0
;
return
0
;
if
(
InRange
(
x1r
,
xi
,
xf
)
&&
InRange
(
y1r
,
yi
,
yf
)
)
if
(
InRange
(
x1r
,
xi
,
xf
)
&&
InRange
(
y1r
,
yi
,
yf
)
)
{
{
xr
[
iret
]
=
x1r
;
xr
[
iret
]
=
x1r
;
yr
[
iret
]
=
y1r
;
yr
[
iret
]
=
y1r
;
iret
++
;
iret
++
;
}
}
if
(
ret
==
2
)
if
(
ret
==
2
)
{
{
if
(
InRange
(
x2r
,
xi
,
xf
)
&&
InRange
(
y2r
,
yi
,
yf
)
)
if
(
InRange
(
x2r
,
xi
,
xf
)
&&
InRange
(
y2r
,
yi
,
yf
)
)
{
{
xr
[
iret
]
=
x2r
;
xr
[
iret
]
=
x2r
;
yr
[
iret
]
=
y2r
;
yr
[
iret
]
=
y2r
;
iret
++
;
iret
++
;
}
}
}
}
...
@@ -234,37 +262,41 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
...
@@ -234,37 +262,41 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
else
if
(
style2
==
CPolyLine
::
STRAIGHT
)
else
if
(
style2
==
CPolyLine
::
STRAIGHT
)
{
{
// first segment is an arc, second segment is straight
// first segment is an arc, second segment is straight
int
ret
;
int
ret
;
double
x1r
,
y1r
,
x2r
,
y2r
;
double
x1r
,
y1r
,
x2r
,
y2r
;
if
(
xf2
==
xi2
)
if
(
xf2
==
xi2
)
{
{
// vertical second segment
// vertical second segment
double
a
=
xi2
;
double
a
=
xi2
;
double
b
=
DBL_MAX
/
2.0
;
double
b
=
DBL_MAX
/
2.0
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi
,
yi
,
xf
,
yf
,
style
,
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi
,
yi
,
xf
,
yf
,
style
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
}
else
else
{
{
double
b
=
(
double
)(
yf2
-
yi2
)
/
(
double
)(
xf2
-
xi2
);
double
b
=
(
double
)
(
yf2
-
yi2
)
/
(
double
)
(
xf2
-
xi2
);
double
a
=
yf2
-
b
*
xf2
;
double
a
=
yf2
-
b
*
xf2
;
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi
,
yi
,
xf
,
yf
,
style
,
ret
=
FindLineSegmentIntersection
(
a
,
b
,
xi
,
yi
,
xf
,
yf
,
style
,
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
&
x1r
,
&
y1r
,
&
x2r
,
&
y2r
);
}
}
if
(
ret
==
0
)
if
(
ret
==
0
)
return
0
;
return
0
;
if
(
InRange
(
x1r
,
xi2
,
xf2
)
&&
InRange
(
y1r
,
yi2
,
yf2
)
)
if
(
InRange
(
x1r
,
xi2
,
xf2
)
&&
InRange
(
y1r
,
yi2
,
yf2
)
)
{
{
xr
[
iret
]
=
x1r
;
xr
[
iret
]
=
x1r
;
yr
[
iret
]
=
y1r
;
yr
[
iret
]
=
y1r
;
iret
++
;
iret
++
;
}
}
if
(
ret
==
2
)
if
(
ret
==
2
)
{
{
if
(
InRange
(
x2r
,
xi2
,
xf2
)
&&
InRange
(
y2r
,
yi2
,
yf2
)
)
if
(
InRange
(
x2r
,
xi2
,
xf2
)
&&
InRange
(
y2r
,
yi2
,
yf2
)
)
{
{
xr
[
iret
]
=
x2r
;
xr
[
iret
]
=
x2r
;
yr
[
iret
]
=
y2r
;
yr
[
iret
]
=
y2r
;
iret
++
;
iret
++
;
}
}
}
}
...
@@ -272,28 +304,33 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
...
@@ -272,28 +304,33 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
else
else
{
{
// both segments are arcs
// both segments are arcs
EllipseKH
el1
;
EllipseKH
el1
;
EllipseKH
el2
;
EllipseKH
el2
;
MakeEllipseFromArc
(
xi
,
yi
,
xf
,
yf
,
style
,
&
el1
);
MakeEllipseFromArc
(
xi
,
yi
,
xf
,
yf
,
style
,
&
el1
);
MakeEllipseFromArc
(
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
&
el2
);
MakeEllipseFromArc
(
xi2
,
yi2
,
xf2
,
yf2
,
style2
,
&
el2
);
int
n
;
int
n
;
if
(
el1
.
xrad
+
el1
.
yrad
>
el2
.
xrad
+
el2
.
yrad
)
if
(
el1
.
xrad
+
el1
.
yrad
>
el2
.
xrad
+
el2
.
yrad
)
n
=
GetArcIntersections
(
&
el1
,
&
el2
);
n
=
GetArcIntersections
(
&
el1
,
&
el2
);
else
else
n
=
GetArcIntersections
(
&
el2
,
&
el1
);
n
=
GetArcIntersections
(
&
el2
,
&
el1
);
iret
=
n
;
iret
=
n
;
}
}
if
(
x
&&
y
)
if
(
x
&&
y
)
{
{
for
(
int
i
=
0
;
i
<
iret
;
i
++
)
for
(
int
i
=
0
;
i
<
iret
;
i
++
)
{
{
x
[
i
]
=
xr
[
i
];
x
[
i
]
=
xr
[
i
];
y
[
i
]
=
yr
[
i
];
y
[
i
]
=
yr
[
i
];
}
}
}
}
return
iret
;
return
iret
;
}
}
// find intersection between line y = a + bx and line segment (xi,yi) to (xf,yf)
// 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
// if b > DBL_MAX/10, assume vertical line at x = a
// the line segment may be an arc (i.e. quadrant of an ellipse)
// the line segment may be an arc (i.e. quadrant of an ellipse)
...
@@ -303,12 +340,13 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
...
@@ -303,12 +340,13 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
// if no intersection, returns min distance in dist
// if no intersection, returns min distance in dist
//
//
int
FindLineSegmentIntersection
(
double
a
,
double
b
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
int
FindLineSegmentIntersection
(
double
a
,
double
b
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
,
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
,
double
*
dist
)
double
*
dist
)
{
{
double
xx
=
0
,
yy
=
0
;
//Init made to avoid C compil "uninitialized" warning
double
xx
=
0
,
yy
=
0
;
// Init made to avoid C compil "uninitialized" warning
bool
bVert
=
false
;
bool
bVert
=
false
;
if
(
b
>
DBL_MAX
/
10.0
)
if
(
b
>
DBL_MAX
/
10.0
)
bVert
=
true
;
bVert
=
true
;
if
(
xf
!=
xi
)
if
(
xf
!=
xi
)
...
@@ -318,36 +356,42 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
...
@@ -318,36 +356,42 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
{
{
// horizontal or oblique straight segment
// horizontal or oblique straight segment
// put into form y = c + dx;
// put into form y = c + dx;
double
d
=
(
double
)(
yf
-
yi
)
/
(
double
)(
xf
-
xi
);
double
d
=
(
double
)
(
yf
-
yi
)
/
(
double
)
(
xf
-
xi
);
double
c
=
yf
-
d
*
xf
;
double
c
=
yf
-
d
*
xf
;
if
(
bVert
)
if
(
bVert
)
{
{
// if vertical line, easy
// if vertical line, easy
if
(
InRange
(
a
,
xi
,
xf
)
)
if
(
InRange
(
a
,
xi
,
xf
)
)
{
{
*
x1
=
a
;
*
x1
=
a
;
*
y1
=
c
+
d
*
a
;
*
y1
=
c
+
d
*
a
;
return
1
;
return
1
;
}
}
else
else
{
{
if
(
dist
)
if
(
dist
)
*
dist
=
min
(
abs
(
a
-
xi
),
abs
(
a
-
xf
)
);
*
dist
=
min
(
abs
(
a
-
xi
),
abs
(
a
-
xf
)
);
return
0
;
return
0
;
}
}
}
}
if
(
fabs
(
b
-
d
)
<
1E-12
)
if
(
fabs
(
b
-
d
)
<
1E-12
)
{
{
// parallel lines
// parallel lines
if
(
dist
)
if
(
dist
)
{
{
*
dist
=
GetPointToLineDistance
(
a
,
b
,
xi
,
xf
);
*
dist
=
GetPointToLineDistance
(
a
,
b
,
xi
,
xf
);
}
}
return
0
;
// lines parallel
return
0
;
// lines parallel
}
}
// calculate intersection
// calculate intersection
xx
=
(
c
-
a
)
/
(
b
-
d
);
xx
=
(
c
-
a
)
/
(
b
-
d
);
yy
=
a
+
b
*
(
xx
);
yy
=
a
+
b
*
(
xx
);
// see if intersection is within the line segment
// see if intersection is within the line segment
if
(
yf
==
yi
)
if
(
yf
==
yi
)
{
{
...
@@ -368,6 +412,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
...
@@ -368,6 +412,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
// arc (quadrant of ellipse)
// arc (quadrant of ellipse)
// convert to clockwise arc
// convert to clockwise arc
int
xxi
,
xxf
,
yyi
,
yyf
;
int
xxi
,
xxf
,
yyi
,
yyf
;
if
(
style
==
CPolyLine
::
ARC_CCW
)
if
(
style
==
CPolyLine
::
ARC_CCW
)
{
{
xxi
=
xf
;
xxi
=
xf
;
...
@@ -382,39 +427,45 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
...
@@ -382,39 +427,45 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
yyi
=
yi
;
yyi
=
yi
;
yyf
=
yf
;
yyf
=
yf
;
}
}
// find center and radii of ellipse
// find center and radii of ellipse
double
xo
=
xxf
,
yo
=
yyi
,
rx
,
ry
;
// Init made to avoid C compil warnings
double
xo
=
xxf
,
yo
=
yyi
,
rx
,
ry
;
// Init made to avoid C compil warnings
if
(
xxf
>
xxi
&&
yyf
>
yyi
)
if
(
xxf
>
xxi
&&
yyf
>
yyi
)
{
{
xo
=
xxf
;
xo
=
xxf
;
yo
=
yyi
;
yo
=
yyi
;
}
}
else
if
(
xxf
<
xxi
&&
yyf
>
yyi
)
else
if
(
xxf
<
xxi
&&
yyf
>
yyi
)
{
{
xo
=
xxi
;
xo
=
xxi
;
yo
=
yyf
;
yo
=
yyf
;
}
}
else
if
(
xxf
<
xxi
&&
yyf
<
yyi
)
else
if
(
xxf
<
xxi
&&
yyf
<
yyi
)
{
{
xo
=
xxf
;
xo
=
xxf
;
yo
=
yyi
;
yo
=
yyi
;
}
}
else
if
(
xxf
>
xxi
&&
yyf
<
yyi
)
else
if
(
xxf
>
xxi
&&
yyf
<
yyi
)
{
{
xo
=
xxi
;
xo
=
xxi
;
yo
=
yyf
;
yo
=
yyf
;
}
}
rx
=
fabs
(
(
double
)(
xxi
-
xxf
)
);
ry
=
fabs
(
(
double
)(
yyi
-
yyf
)
);
rx
=
fabs
(
(
double
)
(
xxi
-
xxf
)
);
bool
test
;
ry
=
fabs
(
(
double
)
(
yyi
-
yyf
)
);
double
xx1
,
xx2
,
yy1
,
yy2
,
aa
;
bool
test
;
double
xx1
,
xx2
,
yy1
,
yy2
,
aa
;
if
(
bVert
)
if
(
bVert
)
{
{
// shift vertical line to coordinate system of ellipse
// shift vertical line to coordinate system of ellipse
aa
=
a
-
xo
;
aa
=
a
-
xo
;
test
=
FindVerticalLineEllipseIntersections
(
rx
,
ry
,
aa
,
&
yy1
,
&
yy2
);
test
=
FindVerticalLineEllipseIntersections
(
rx
,
ry
,
aa
,
&
yy1
,
&
yy2
);
if
(
!
test
)
if
(
!
test
)
return
0
;
return
0
;
// shift back to PCB coordinates
// shift back to PCB coordinates
yy1
+=
yo
;
yy1
+=
yo
;
yy2
+=
yo
;
yy2
+=
yo
;
...
@@ -424,66 +475,76 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
...
@@ -424,66 +475,76 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
else
else
{
{
// shift line to coordinate system of ellipse
// shift line to coordinate system of ellipse
aa
=
a
+
b
*
xo
-
yo
;
aa
=
a
+
b
*
xo
-
yo
;
test
=
FindLineEllipseIntersections
(
rx
,
ry
,
aa
,
b
,
&
xx1
,
&
xx2
);
test
=
FindLineEllipseIntersections
(
rx
,
ry
,
aa
,
b
,
&
xx1
,
&
xx2
);
if
(
!
test
)
if
(
!
test
)
return
0
;
return
0
;
// shift back to PCB coordinates
// shift back to PCB coordinates
yy1
=
aa
+
b
*
xx1
;
yy1
=
aa
+
b
*
xx1
;
xx1
+=
xo
;
xx1
+=
xo
;
yy1
+=
yo
;
yy1
+=
yo
;
yy2
=
aa
+
b
*
xx2
;
yy2
=
aa
+
b
*
xx2
;
xx2
+=
xo
;
xx2
+=
xo
;
yy2
+=
yo
;
yy2
+=
yo
;
}
}
int
npts
=
0
;
int
npts
=
0
;
if
(
(
xxf
>
xxi
&&
xx1
<
xxf
&&
xx1
>
xxi
)
||
(
xxf
<
xxi
&&
xx1
<
xxi
&&
xx1
>
xxf
)
)
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
)
)
if
(
(
yyf
>
yyi
&&
yy1
<
yyf
&&
yy1
>
yyi
)
||
(
yyf
<
yyi
&&
yy1
<
yyi
&&
yy1
>
yyf
)
)
{
{
*
x1
=
xx1
;
*
x1
=
xx1
;
*
y1
=
yy1
;
*
y1
=
yy1
;
npts
=
1
;
npts
=
1
;
}
}
}
}
if
(
(
xxf
>
xxi
&&
xx2
<
xxf
&&
xx2
>
xxi
)
||
(
xxf
<
xxi
&&
xx2
<
xxi
&&
xx2
>
xxf
)
)
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
(
(
yyf
>
yyi
&&
yy2
<
yyf
&&
yy2
>
yyi
)
||
(
yyf
<
yyi
&&
yy2
<
yyi
&&
yy2
>
yyf
)
)
{
{
if
(
npts
==
0
)
if
(
npts
==
0
)
{
{
*
x1
=
xx2
;
*
x1
=
xx2
;
*
y1
=
yy2
;
*
y1
=
yy2
;
npts
=
1
;
npts
=
1
;
}
}
else
else
{
{
*
x2
=
xx2
;
*
x2
=
xx2
;
*
y2
=
yy2
;
*
y2
=
yy2
;
npts
=
2
;
npts
=
2
;
}
}
}
}
}
}
return
npts
;
return
npts
;
}
}
else
else
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
else
else
{
{
// vertical line segment
// vertical line segment
if
(
bVert
)
if
(
bVert
)
return
0
;
return
0
;
xx
=
xi
;
yy
=
a
+
b
*
xx
;
xx
=
xi
;
yy
=
a
+
b
*
xx
;
if
(
(
yy
>=
yi
&&
yy
>
yf
)
||
(
yy
<=
yi
&&
yy
<
yf
)
)
if
(
(
yy
>=
yi
&&
yy
>
yf
)
||
(
yy
<=
yi
&&
yy
<
yf
)
)
return
0
;
return
0
;
}
}
*
x1
=
xx
;
*
x1
=
xx
;
*
y1
=
yy
;
*
y1
=
yy
;
return
1
;
return
1
;
}
}
/*
/*
* Function TestForIntersectionOfStraightLineSegments
* Function TestForIntersectionOfStraightLineSegments
* Test for intersection of line segments
* Test for intersection of line segments
...
@@ -492,10 +553,11 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
...
@@ -492,10 +553,11 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
* if false, returns min. distance in dist (may be 0.0 if parallel)
* if false, returns min. distance in dist (may be 0.0 if parallel)
*/
*/
bool
TestForIntersectionOfStraightLineSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
bool
TestForIntersectionOfStraightLineSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
*
x
,
int
*
y
,
double
*
d
)
int
*
x
,
int
*
y
,
double
*
d
)
{
{
double
a
,
b
,
dist
;
double
a
,
b
,
dist
;
// first, test for intersection
// first, test for intersection
if
(
x1i
==
x1f
&&
x2i
==
x2f
)
if
(
x1i
==
x1f
&&
x2i
==
x2f
)
{
{
...
@@ -513,10 +575,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -513,10 +575,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{
{
if
(
x
)
if
(
x
)
*
x
=
x1i
;
*
x
=
x1i
;
if
(
y
)
if
(
y
)
*
y
=
y2i
;
*
y
=
y2i
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
...
@@ -528,10 +593,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -528,10 +593,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{
{
if
(
x
)
if
(
x
)
*
x
=
x2i
;
*
x
=
x2i
;
if
(
y
)
if
(
y
)
*
y
=
y1i
;
*
y
=
y1i
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
...
@@ -539,21 +607,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -539,21 +607,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{
{
// first segment vertical, second oblique
// first segment vertical, second oblique
// get a and b for second line segment, so that y = a + bx;
// get a and b for second line segment, so that y = a + bx;
b
=
(
double
)(
y2f
-
y2i
)
/
(
x2f
-
x2i
);
b
=
double
(
y2f
-
y2i
)
/
(
x2f
-
x2i
);
a
=
(
double
)
y2i
-
b
*
x2i
;
a
=
(
double
)
y2i
-
b
*
x2i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
double
x1
,
y1
,
x2
,
y2
;
&
x1
,
&
y1
,
&
x2
,
&
y2
);
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
if
(
test
)
{
{
if
(
InRange
(
y1
,
y1i
,
y1f
)
&&
InRange
(
x1
,
x2i
,
x2f
)
&&
InRange
(
y1
,
y2i
,
y2f
)
)
if
(
InRange
(
y1
,
y1i
,
y1f
)
&&
InRange
(
x1
,
x2i
,
x2f
)
&&
InRange
(
y1
,
y2i
,
y2f
)
)
{
{
if
(
x
)
if
(
x
)
*
x
=
(
int
)
x1
;
*
x
=
(
int
)
x1
;
if
(
y
)
if
(
y
)
*
y
=
(
int
)
y1
;
*
y
=
(
int
)
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
...
@@ -562,21 +635,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -562,21 +635,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{
{
// first segment horizontal, second oblique
// first segment horizontal, second oblique
// get a and b for second line segment, so that y = a + bx;
// get a and b for second line segment, so that y = a + bx;
b
=
(
double
)(
y2f
-
y2i
)
/
(
x2f
-
x2i
);
b
=
double
(
y2f
-
y2i
)
/
(
x2f
-
x2i
);
a
=
(
double
)
y2i
-
b
*
x2i
;
a
=
(
double
)
y2i
-
b
*
x2i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
double
x1
,
y1
,
x2
,
y2
;
&
x1
,
&
y1
,
&
x2
,
&
y2
);
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
if
(
test
)
{
{
if
(
InRange
(
x1
,
x1i
,
x1f
)
&&
InRange
(
x1
,
x2i
,
x2f
)
&&
InRange
(
y1
,
y2i
,
y2f
)
)
if
(
InRange
(
x1
,
x1i
,
x1f
)
&&
InRange
(
x1
,
x2i
,
x2f
)
&&
InRange
(
y1
,
y2i
,
y2f
)
)
{
{
if
(
x
)
if
(
x
)
*
x
=
(
int
)
x1
;
*
x
=
(
int
)
x1
;
if
(
y
)
if
(
y
)
*
y
=
(
int
)
y1
;
*
y
=
(
int
)
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
...
@@ -585,21 +663,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -585,21 +663,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{
{
// second segment vertical, first oblique
// second segment vertical, first oblique
// get a and b for first line segment, so that y = a + bx;
// get a and b for first line segment, so that y = a + bx;
b
=
(
double
)(
y1f
-
y1i
)
/
(
x1f
-
x1i
);
b
=
double
(
y1f
-
y1i
)
/
(
x1f
-
x1i
);
a
=
(
double
)
y1i
-
b
*
x1i
;
a
=
(
double
)
y1i
-
b
*
x1i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
double
x1
,
y1
,
x2
,
y2
;
&
x1
,
&
y1
,
&
x2
,
&
y2
);
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
if
(
test
)
{
{
if
(
InRange
(
x1
,
x1i
,
x1f
)
&&
InRange
(
y1
,
y1i
,
y1f
)
&&
InRange
(
y1
,
y2i
,
y2f
)
)
if
(
InRange
(
x1
,
x1i
,
x1f
)
&&
InRange
(
y1
,
y1i
,
y1f
)
&&
InRange
(
y1
,
y2i
,
y2f
)
)
{
{
if
(
x
)
if
(
x
)
*
x
=
(
int
)
x1
;
*
x
=
(
int
)
x1
;
if
(
y
)
if
(
y
)
*
y
=
(
int
)
y1
;
*
y
=
(
int
)
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
...
@@ -608,21 +691,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -608,21 +691,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{
{
// second segment horizontal, first oblique
// second segment horizontal, first oblique
// get a and b for second line segment, so that y = a + bx;
// get a and b for second line segment, so that y = a + bx;
b
=
(
double
)(
y1f
-
y1i
)
/
(
x1f
-
x1i
);
b
=
double
(
y1f
-
y1i
)
/
(
x1f
-
x1i
);
a
=
(
double
)
y1i
-
b
*
x1i
;
a
=
(
double
)
y1i
-
b
*
x1i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
double
x1
,
y1
,
x2
,
y2
;
&
x1
,
&
y1
,
&
x2
,
&
y2
);
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
if
(
test
)
if
(
test
)
{
{
if
(
InRange
(
x1
,
x1i
,
x1f
)
&&
InRange
(
y1
,
y1i
,
y1f
)
)
if
(
InRange
(
x1
,
x1i
,
x1f
)
&&
InRange
(
y1
,
y1i
,
y1f
)
)
{
{
if
(
x
)
if
(
x
)
*
x
=
(
int
)
x1
;
*
x
=
(
int
)
x1
;
if
(
y
)
if
(
y
)
*
y
=
(
int
)
y1
;
*
y
=
(
int
)
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
...
@@ -630,14 +718,25 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -630,14 +718,25 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
else
else
{
{
// both segments oblique
// both segments oblique
if
(
(
long
)(
y1f
-
y1i
)
*
(
x2f
-
x2i
)
!=
(
long
)(
y2f
-
y2i
)
*
(
x1f
-
x1i
)
)
if
(
long
(
y1f
-
y1i
)
*
(
x2f
-
x2i
)
!=
long
(
y2f
-
y2i
)
*
(
x1f
-
x1i
)
)
{
{
// not parallel, get a and b for first line segment, so that y = a + bx;
// not parallel, get a and b for first line segment, so that y = a + bx;
b
=
(
double
)(
y1f
-
y1i
)
/
(
x1f
-
x1i
);
b
=
double
(
y1f
-
y1i
)
/
(
x1f
-
x1i
);
a
=
(
double
)
y1i
-
b
*
x1i
;
a
=
(
double
)
y1i
-
b
*
x1i
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
double
x1
,
y1
,
x2
,
y2
;
&
x1
,
&
y1
,
&
x2
,
&
y2
);
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
// both segments oblique
// both segments oblique
if
(
test
)
if
(
test
)
{
{
...
@@ -645,89 +744,110 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
...
@@ -645,89 +744,110 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{
{
if
(
x
)
if
(
x
)
*
x
=
(
int
)
x1
;
*
x
=
(
int
)
x1
;
if
(
y
)
if
(
y
)
*
y
=
(
int
)
y1
;
*
y
=
(
int
)
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
}
}
}
}
// don't intersect, get shortest distance between each endpoint and the other line segment
// don't intersect, get shortest distance between each endpoint and the other line segment
dist
=
GetPointToLineSegmentDistance
(
x1i
,
y1i
,
x2i
,
y2i
,
x2f
,
y2f
);
dist
=
GetPointToLineSegmentDistance
(
x1i
,
y1i
,
x2i
,
y2i
,
x2f
,
y2f
);
double
xx
=
x1i
;
double
yy
=
y1i
;
double
xx
=
x1i
;
double
dd
=
GetPointToLineSegmentDistance
(
x1f
,
y1f
,
x2i
,
y2i
,
x2f
,
y2f
);
double
yy
=
y1i
;
double
dd
=
GetPointToLineSegmentDistance
(
x1f
,
y1f
,
x2i
,
y2i
,
x2f
,
y2f
);
if
(
dd
<
dist
)
if
(
dd
<
dist
)
{
{
dist
=
dd
;
dist
=
dd
;
xx
=
x1f
;
xx
=
x1f
;
yy
=
y1f
;
yy
=
y1f
;
}
}
dd
=
GetPointToLineSegmentDistance
(
x2i
,
y2i
,
x1i
,
y1i
,
x1f
,
y1f
);
dd
=
GetPointToLineSegmentDistance
(
x2i
,
y2i
,
x1i
,
y1i
,
x1f
,
y1f
);
if
(
dd
<
dist
)
if
(
dd
<
dist
)
{
{
dist
=
dd
;
dist
=
dd
;
xx
=
x2i
;
xx
=
x2i
;
yy
=
y2i
;
yy
=
y2i
;
}
}
dd
=
GetPointToLineSegmentDistance
(
x2f
,
y2f
,
x1i
,
y1i
,
x1f
,
y1f
);
dd
=
GetPointToLineSegmentDistance
(
x2f
,
y2f
,
x1i
,
y1i
,
x1f
,
y1f
);
if
(
dd
<
dist
)
if
(
dd
<
dist
)
{
{
dist
=
dd
;
dist
=
dd
;
xx
=
x2f
;
xx
=
x2f
;
yy
=
y2f
;
yy
=
y2f
;
}
}
if
(
x
)
if
(
x
)
*
x
=
(
int
)
xx
;
*
x
=
(
int
)
xx
;
if
(
y
)
if
(
y
)
*
y
=
(
int
)
yy
;
*
y
=
(
int
)
yy
;
if
(
d
)
if
(
d
)
*
d
=
dist
;
*
d
=
dist
;
return
false
;
return
false
;
}
}
/*solves the Quadratic equation = a*x*x + b*x + c
/*solves the Quadratic equation = a*x*x + b*x + c
*/
*/
bool
Quadratic
(
double
a
,
double
b
,
double
c
,
double
*
x1
,
double
*
x2
)
bool
Quadratic
(
double
a
,
double
b
,
double
c
,
double
*
x1
,
double
*
x2
)
{
{
double
root
=
b
*
b
-
4.0
*
a
*
c
;
double
root
=
b
*
b
-
4.0
*
a
*
c
;
if
(
root
<
0.0
)
if
(
root
<
0.0
)
return
false
;
return
false
;
root
=
sqrt
(
root
);
*
x1
=
(
-
b
+
root
)
/
(
2.0
*
a
);
root
=
sqrt
(
root
);
*
x2
=
(
-
b
-
root
)
/
(
2.0
*
a
);
*
x1
=
(
-
b
+
root
)
/
(
2.0
*
a
);
*
x2
=
(
-
b
-
root
)
/
(
2.0
*
a
);
return
true
;
return
true
;
}
}
// finds intersections of vertical line at x
// finds intersections of vertical line at x
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// returns true if solution exist, with solutions in y1 and y2
// returns true if solution exist, with solutions in y1 and y2
// else returns false
// else returns false
//
//
bool
FindVerticalLineEllipseIntersections
(
double
a
,
double
b
,
double
x
,
double
*
y1
,
double
*
y2
)
bool
FindVerticalLineEllipseIntersections
(
double
a
,
double
b
,
double
x
,
double
*
y1
,
double
*
y2
)
{
{
double
y_sqr
=
(
1.0
-
(
x
*
x
)
/
(
a
*
a
))
*
b
*
b
;
double
y_sqr
=
(
1.0
-
(
x
*
x
)
/
(
a
*
a
)
)
*
b
*
b
;
if
(
y_sqr
<
0.0
)
if
(
y_sqr
<
0.0
)
return
false
;
return
false
;
*
y1
=
sqrt
(
y_sqr
);
*
y1
=
sqrt
(
y_sqr
);
*
y2
=
-*
y1
;
*
y2
=
-*
y1
;
return
true
;
return
true
;
}
}
// finds intersections of straight line y = c + dx
// finds intersections of straight line y = c + dx
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// returns true if solution exist, with solutions in x1 and x2
// returns true if solution exist, with solutions in x1 and x2
// else returns false
// else returns false
//
//
bool
FindLineEllipseIntersections
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x1
,
double
*
x2
)
bool
FindLineEllipseIntersections
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x1
,
double
*
x2
)
{
{
// quadratic terms
// quadratic terms
double
A
=
d
*
d
+
b
*
b
/
(
a
*
a
);
double
A
=
d
*
d
+
b
*
b
/
(
a
*
a
);
double
B
=
2.0
*
c
*
d
;
double
B
=
2.0
*
c
*
d
;
double
C
=
c
*
c
-
b
*
b
;
double
C
=
c
*
c
-
b
*
b
;
return
Quadratic
(
A
,
B
,
C
,
x1
,
x2
);
return
Quadratic
(
A
,
B
,
C
,
x1
,
x2
);
}
}
...
@@ -737,54 +857,66 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl
...
@@ -737,54 +857,66 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl
// in clearance > max_cl, just returns max_cl and doesn't return x,y
// in clearance > max_cl, just returns max_cl and doesn't return x,y
//
//
int
GetClearanceBetweenSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
style1
,
int
w1
,
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
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
style2
,
int
w2
,
int
max_cl
,
int
*
x
,
int
*
y
)
int
max_cl
,
int
*
x
,
int
*
y
)
{
{
// check clearance between bounding rectangles
// check clearance between bounding rectangles
int
test
=
max_cl
+
w1
/
2
+
w2
/
2
;
int
test
=
max_cl
+
w1
/
2
+
w2
/
2
;
if
(
min
(
x1i
,
x1f
)
-
max
(
x2i
,
x2f
)
>
test
)
if
(
min
(
x1i
,
x1f
)
-
max
(
x2i
,
x2f
)
>
test
)
return
max_cl
;
return
max_cl
;
if
(
min
(
x2i
,
x2f
)
-
max
(
x1i
,
x1f
)
>
test
)
if
(
min
(
x2i
,
x2f
)
-
max
(
x1i
,
x1f
)
>
test
)
return
max_cl
;
return
max_cl
;
if
(
min
(
y1i
,
y1f
)
-
max
(
y2i
,
y2f
)
>
test
)
if
(
min
(
y1i
,
y1f
)
-
max
(
y2i
,
y2f
)
>
test
)
return
max_cl
;
return
max_cl
;
if
(
min
(
y2i
,
y2f
)
-
max
(
y1i
,
y1f
)
>
test
)
if
(
min
(
y2i
,
y2f
)
-
max
(
y1i
,
y1f
)
>
test
)
return
max_cl
;
return
max_cl
;
if
(
style1
==
CPolyLine
::
STRAIGHT
&&
style1
==
CPolyLine
::
STRAIGHT
)
if
(
style1
==
CPolyLine
::
STRAIGHT
&&
style1
==
CPolyLine
::
STRAIGHT
)
{
{
// both segments are straight lines
// both segments are straight lines
int
xx
,
yy
;
int
xx
,
yy
;
double
dd
;
double
dd
;
TestForIntersectionOfStraightLineSegments
(
x1i
,
y1i
,
x1f
,
y1f
,
TestForIntersectionOfStraightLineSegments
(
x1i
,
y1i
,
x1f
,
y1f
,
x2i
,
y2i
,
x2f
,
y2f
,
&
xx
,
&
yy
,
&
dd
);
x2i
,
y2i
,
x2f
,
y2f
,
&
xx
,
&
yy
,
&
dd
);
int
d
=
max
(
0
,
(
int
)
dd
-
w1
/
2
-
w2
/
2
);
int
d
=
max
(
0
,
(
int
)
dd
-
w1
/
2
-
w2
/
2
);
if
(
x
)
if
(
x
)
*
x
=
xx
;
*
x
=
xx
;
if
(
y
)
if
(
y
)
*
y
=
yy
;
*
y
=
yy
;
return
d
;
return
d
;
}
}
// not both straight-line segments
// not both straight-line segments
// see if segments intersect
// see if segments intersect
double
xr
[
2
];
double
xr
[
2
];
double
yr
[
2
];
double
yr
[
2
];
test
=
FindSegmentIntersections
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
xr
,
yr
);
test
=
FindSegmentIntersections
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
xr
,
yr
);
if
(
test
)
if
(
test
)
{
{
if
(
x
)
if
(
x
)
*
x
=
(
int
)
xr
[
0
];
*
x
=
(
int
)
xr
[
0
];
if
(
y
)
if
(
y
)
*
y
=
(
int
)
yr
[
0
];
*
y
=
(
int
)
yr
[
0
];
return
0
;
return
0
;
}
}
// at least one segment is an arc
// at least one segment is an arc
EllipseKH
el1
;
EllipseKH
el1
;
EllipseKH
el2
;
EllipseKH
el2
;
bool
bArcs
;
bool
bArcs
;
int
xi
=
0
,
yi
=
0
,
xf
=
0
,
yf
=
0
;
int
xi
=
0
,
yi
=
0
,
xf
=
0
,
yf
=
0
;
if
(
style2
==
CPolyLine
::
STRAIGHT
)
if
(
style2
==
CPolyLine
::
STRAIGHT
)
{
{
// style1 = arc, style2 = straight
// style1 = arc, style2 = straight
...
@@ -798,10 +930,10 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
...
@@ -798,10 +930,10 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
else
if
(
style1
==
CPolyLine
::
STRAIGHT
)
else
if
(
style1
==
CPolyLine
::
STRAIGHT
)
{
{
// style2 = arc, style1 = straight
// style2 = arc, style1 = straight
xi
=
x1i
;
xi
=
x1i
;
yi
=
y1i
;
yi
=
y1i
;
xf
=
x1f
;
xf
=
x1f
;
yf
=
y1f
;
yf
=
y1f
;
MakeEllipseFromArc
(
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
&
el1
);
MakeEllipseFromArc
(
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
&
el1
);
bArcs
=
false
;
bArcs
=
false
;
}
}
...
@@ -812,106 +944,127 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
...
@@ -812,106 +944,127 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
MakeEllipseFromArc
(
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
&
el2
);
MakeEllipseFromArc
(
x2i
,
y2i
,
x2f
,
y2f
,
style2
,
&
el2
);
bArcs
=
true
;
bArcs
=
true
;
}
}
const
int
NSTEPS
=
32
;
const
int
NSTEPS
=
32
;
if
(
el1
.
theta2
>
el1
.
theta1
)
if
(
el1
.
theta2
>
el1
.
theta1
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
if
(
bArcs
&&
el2
.
theta2
>
el2
.
theta1
)
if
(
bArcs
&&
el2
.
theta2
>
el2
.
theta1
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
// test multiple points in both segments
// test multiple points in both segments
double
th1
;
double
th1
;
double
th2
;
double
th2
;
double
len2
;
double
len2
;
if
(
bArcs
)
if
(
bArcs
)
{
{
th1
=
el2
.
theta1
;
th1
=
el2
.
theta1
;
th2
=
el2
.
theta2
;
th2
=
el2
.
theta2
;
len2
=
max
(
el2
.
xrad
,
el2
.
yrad
);
len2
=
max
(
el2
.
xrad
,
el2
.
yrad
);
}
}
else
else
{
{
th1
=
1.0
;
th1
=
1.0
;
th2
=
0.0
;
th2
=
0.0
;
len2
=
abs
(
xf
-
xi
)
+
abs
(
yf
-
yi
);
len2
=
abs
(
xf
-
xi
)
+
abs
(
yf
-
yi
);
}
}
double
s_start
=
el1
.
theta1
;
double
s_end
=
el1
.
theta2
;
double
s_start
=
el1
.
theta1
;
double
s_start2
=
th1
;
double
s_end
=
el1
.
theta2
;
double
s_end2
=
th2
;
double
s_start2
=
th1
;
double
dmin
=
DBL_MAX
;
double
s_end2
=
th2
;
double
xmin
=
0
,
ymin
=
0
,
smin
=
0
,
smin2
=
0
;
// Init made to avoid C compil warnings
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
;
int
nsteps
=
NSTEPS
;
double
step
=
(
s_start
-
s_end
)
/
(
nsteps
-
1
);
int
nsteps2
=
NSTEPS
;
double
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
double
step
=
(
s_start
-
s_end
)
/
(
nsteps
-
1
);
while
(
(
step
*
max
(
el1
.
xrad
,
el1
.
yrad
))
>
0.1
*
NM_PER_MIL
double
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
&&
(
step2
*
len2
)
>
0.1
*
NM_PER_MIL
)
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
);
step
=
(
s_start
-
s_end
)
/
(
nsteps
-
1
);
for
(
int
i
=
0
;
i
<
nsteps
;
i
++
)
for
(
int
i
=
0
;
i
<
nsteps
;
i
++
)
{
{
double
s
;
double
s
;
if
(
i
<
nsteps
-
1
)
s
=
s_start
-
i
*
step
;
if
(
i
<
nsteps
-
1
)
s
=
s_start
-
i
*
step
;
else
else
s
=
s_end
;
s
=
s_end
;
double
x
=
el1
.
Center
.
X
+
el1
.
xrad
*
cos
(
s
);
double
y
=
el1
.
Center
.
Y
+
el1
.
yrad
*
sin
(
s
);
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
// if not an arc, use s2 as fractional distance along line
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
for
(
int
i2
=
0
;
i2
<
nsteps2
;
i2
++
)
for
(
int
i2
=
0
;
i2
<
nsteps2
;
i2
++
)
{
{
double
s2
;
double
s2
;
if
(
i2
<
nsteps2
-
1
)
s2
=
s_start2
-
i2
*
step2
;
if
(
i2
<
nsteps2
-
1
)
s2
=
s_start2
-
i2
*
step2
;
else
else
s2
=
s_end2
;
s2
=
s_end2
;
double
x2
,
y2
;
double
x2
,
y2
;
if
(
!
bArcs
)
if
(
!
bArcs
)
{
{
x2
=
xi
+
(
xf
-
xi
)
*
s2
;
x2
=
xi
+
(
xf
-
xi
)
*
s2
;
y2
=
yi
+
(
yf
-
yi
)
*
s2
;
y2
=
yi
+
(
yf
-
yi
)
*
s2
;
}
}
else
else
{
{
x2
=
el2
.
Center
.
X
+
el2
.
xrad
*
cos
(
s2
);
x2
=
el2
.
Center
.
X
+
el2
.
xrad
*
cos
(
s2
);
y2
=
el2
.
Center
.
Y
+
el2
.
yrad
*
sin
(
s2
);
y2
=
el2
.
Center
.
Y
+
el2
.
yrad
*
sin
(
s2
);
}
}
double
d
=
Distance
(
(
int
)
x
,
(
int
)
y
,
(
int
)
x2
,
(
int
)
y2
);
double
d
=
Distance
(
(
int
)
x
,
(
int
)
y
,
(
int
)
x2
,
(
int
)
y2
);
if
(
d
<
dmin
)
if
(
d
<
dmin
)
{
{
dmin
=
d
;
dmin
=
d
;
xmin
=
x
;
xmin
=
x
;
ymin
=
y
;
ymin
=
y
;
smin
=
s
;
smin
=
s
;
smin2
=
s2
;
smin2
=
s2
;
}
}
}
}
}
}
if
(
step
>
step2
)
if
(
step
>
step2
)
{
{
s_start
=
min
(
el1
.
theta1
,
smin
+
step
);
s_start
=
min
(
el1
.
theta1
,
smin
+
step
);
s_end
=
max
(
el1
.
theta2
,
smin
-
step
);
s_end
=
max
(
el1
.
theta2
,
smin
-
step
);
step
=
(
s_start
-
s_end
)
/
nsteps
;
step
=
(
s_start
-
s_end
)
/
nsteps
;
}
}
else
else
{
{
s_start2
=
min
(
th1
,
smin2
+
step2
);
s_start2
=
min
(
th1
,
smin2
+
step2
);
s_end2
=
max
(
th2
,
smin2
-
step2
);
s_end2
=
max
(
th2
,
smin2
-
step2
);
step2
=
(
s_start2
-
s_end2
)
/
nsteps2
;
step2
=
(
s_start2
-
s_end2
)
/
nsteps2
;
}
}
}
}
if
(
x
)
if
(
x
)
*
x
=
(
int
)
xmin
;
*
x
=
(
int
)
xmin
;
if
(
y
)
if
(
y
)
*
y
=
(
int
)
ymin
;
*
y
=
(
int
)
ymin
;
return
max
(
0
,
(
int
)
dmin
-
w1
/
2
-
w2
/
2
);
// allow for widths
return
max
(
0
,
(
int
)
dmin
-
w1
/
2
-
w2
/
2
);
// allow for widths
}
}
...
@@ -919,33 +1072,39 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
...
@@ -919,33 +1072,39 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
// if b > DBL_MAX/10, assume vertical line at x = a
// if b > DBL_MAX/10, assume vertical line at x = a
// returns closest point on line in xp, yp
// returns closest point on line in xp, yp
//
//
double
GetPointToLineDistance
(
double
a
,
double
b
,
int
x
,
int
y
,
double
*
xpp
,
double
*
ypp
)
double
GetPointToLineDistance
(
double
a
,
double
b
,
int
x
,
int
y
,
double
*
xpp
,
double
*
ypp
)
{
{
if
(
b
>
DBL_MAX
/
10
)
if
(
b
>
DBL_MAX
/
10
)
{
{
// vertical line
// vertical line
if
(
xpp
&&
ypp
)
if
(
xpp
&&
ypp
)
{
{
*
xpp
=
a
;
*
xpp
=
a
;
*
ypp
=
y
;
*
ypp
=
y
;
}
}
return
abs
(
a
-
x
);
return
abs
(
a
-
x
);
}
}
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
double
d
=
-
1.0
/
b
;
double
d
=
-
1.0
/
b
;
double
c
=
(
double
)
y
-
d
*
x
;
double
c
=
(
double
)
y
-
d
*
x
;
// find nearest point to (x,y) on line through (xi,yi) to (xf,yf)
// find nearest point to (x,y) on line through (xi,yi) to (xf,yf)
double
xp
=
(
a
-
c
)
/
(
d
-
b
);
double
xp
=
(
a
-
c
)
/
(
d
-
b
);
double
yp
=
a
+
b
*
xp
;
double
yp
=
a
+
b
*
xp
;
if
(
xpp
&&
ypp
)
if
(
xpp
&&
ypp
)
{
{
*
xpp
=
xp
;
*
xpp
=
xp
;
*
ypp
=
yp
;
*
ypp
=
yp
;
}
}
// find distance
// find distance
return
Distance
(
x
,
y
,
(
int
)
xp
,
(
int
)
yp
);
return
Distance
(
x
,
y
,
(
int
)
xp
,
(
int
)
yp
);
}
}
/***********************************************************************************/
/***********************************************************************************/
double
GetPointToLineSegmentDistance
(
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
)
double
GetPointToLineSegmentDistance
(
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
)
/***********************************************************************************/
/***********************************************************************************/
...
@@ -979,14 +1138,17 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
...
@@ -979,14 +1138,17 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
{
{
// oblique segment
// oblique segment
// find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx
// find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx
double
b
=
(
double
)(
yf
-
yi
)
/
(
xf
-
xi
);
double
b
=
(
double
)
(
yf
-
yi
)
/
(
xf
-
xi
);
double
a
=
(
double
)
yi
-
b
*
xi
;
double
a
=
(
double
)
yi
-
b
*
xi
;
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
double
d
=
-
1.0
/
b
;
double
d
=
-
1.0
/
b
;
double
c
=
(
double
)
y
-
d
*
x
;
double
c
=
(
double
)
y
-
d
*
x
;
// find nearest point to (x,y) on line through (xi,yi) to (xf,yf)
// find nearest point to (x,y) on line through (xi,yi) to (xf,yf)
double
xp
=
(
a
-
c
)
/
(
d
-
b
);
double
xp
=
(
a
-
c
)
/
(
d
-
b
);
double
yp
=
a
+
b
*
xp
;
double
yp
=
a
+
b
*
xp
;
// find distance
// find distance
if
(
InRange
(
xp
,
xi
,
xf
)
&&
InRange
(
yp
,
yi
,
yf
)
)
if
(
InRange
(
xp
,
xi
,
xf
)
&&
InRange
(
yp
,
yi
,
yf
)
)
return
Distance
(
x
,
y
,
(
int
)
xp
,
(
int
)
yp
);
return
Distance
(
x
,
y
,
(
int
)
xp
,
(
int
)
yp
);
...
@@ -995,11 +1157,12 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
...
@@ -995,11 +1157,12 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
}
}
}
}
// test for value within range
// test for value within range
//
//
bool
InRange
(
double
x
,
double
xi
,
double
xf
)
bool
InRange
(
double
x
,
double
xi
,
double
xf
)
{
{
if
(
xf
>
xi
)
if
(
xf
>
xi
)
{
{
if
(
x
>=
xi
&&
x
<=
xf
)
if
(
x
>=
xi
&&
x
<=
xf
)
return
true
;
return
true
;
...
@@ -1009,187 +1172,234 @@ bool InRange( double x, double xi, double xf )
...
@@ -1009,187 +1172,234 @@ bool InRange( double x, double xi, double xf )
if
(
x
>=
xf
&&
x
<=
xi
)
if
(
x
>=
xf
&&
x
<=
xi
)
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
// Get distance between 2 points
// Get distance between 2 points
//
//
double
Distance
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
double
Distance
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
{
double
d
;
double
dx
=
x1
-
x2
;
d
=
sqrt
(
(
double
)(
x1
-
x2
)
*
(
x1
-
x2
)
+
(
double
)(
y1
-
y2
)
*
(
y1
-
y2
)
);
double
dy
=
y1
-
y2
;
double
d
=
sqrt
(
dx
*
dx
+
dy
*
dy
);
if
(
d
>
INT_MAX
||
d
<
INT_MIN
)
if
(
d
>
INT_MAX
||
d
<
INT_MIN
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
return
(
int
)
d
;
// wxASSERT( d <= INT_MAX && d >= INT_MIN );
return
int
(
d
);
}
}
// this finds approximate solutions
// this finds approximate solutions
// note: this works best if el2 is smaller than el1
// note: this works best if el2 is smaller than el1
//
//
int
GetArcIntersections
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
int
GetArcIntersections
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
)
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
)
{
{
if
(
el1
->
theta2
>
el1
->
theta1
)
if
(
el1
->
theta2
>
el1
->
theta1
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
if
(
el2
->
theta2
>
el2
->
theta1
)
if
(
el2
->
theta2
>
el2
->
theta1
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
const
int
NSTEPS
=
32
;
const
int
NSTEPS
=
32
;
double
xret
[
2
],
yret
[
2
];
double
xret
[
2
],
yret
[
2
];
double
xscale
=
1.0
/
el1
->
xrad
;
double
yscale
=
1.0
/
el1
->
yrad
;
double
xscale
=
1.0
/
el1
->
xrad
;
double
yscale
=
1.0
/
el1
->
yrad
;
// now transform params of second ellipse into reference frame
// now transform params of second ellipse into reference frame
// with origin at center if first ellipse,
// with origin at center if first ellipse,
// scaled so the first ellipse is a circle of radius = 1.0
// scaled so the first ellipse is a circle of radius = 1.0
double
xo
=
(
el2
->
Center
.
X
-
el1
->
Center
.
X
)
*
xscale
;
double
xo
=
(
el2
->
Center
.
X
-
el1
->
Center
.
X
)
*
xscale
;
double
yo
=
(
el2
->
Center
.
Y
-
el1
->
Center
.
Y
)
*
yscale
;
double
yo
=
(
el2
->
Center
.
Y
-
el1
->
Center
.
Y
)
*
yscale
;
double
xr
=
el2
->
xrad
*
xscale
;
double
xr
=
el2
->
xrad
*
xscale
;
double
yr
=
el2
->
yrad
*
yscale
;
double
yr
=
el2
->
yrad
*
yscale
;
// now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta)
// now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta)
double
step
=
M_PI
/
((
NSTEPS
-
1
)
*
2.0
);
double
step
=
M_PI
/
(
(
NSTEPS
-
1
)
*
2.0
);
double
d_prev
=
0
;
double
d_prev
=
0
;
double
th_interp
;
double
th_interp
;
double
th1
;
double
th1
;
int
n
=
0
;
for
(
int
i
=
0
;
i
<
NSTEPS
;
i
++
)
int
n
=
0
;
for
(
int
i
=
0
;
i
<
NSTEPS
;
i
++
)
{
{
double
theta
;
double
theta
;
if
(
i
<
NSTEPS
-
1
)
theta
=
el2
->
theta1
-
i
*
step
;
if
(
i
<
NSTEPS
-
1
)
theta
=
el2
->
theta1
-
i
*
step
;
else
else
theta
=
el2
->
theta2
;
theta
=
el2
->
theta2
;
double
x
=
xo
+
xr
*
cos
(
theta
);
double
y
=
yo
+
yr
*
sin
(
theta
);
double
x
=
xo
+
xr
*
cos
(
theta
);
double
d
=
1.0
-
sqrt
(
x
*
x
+
y
*
y
);
double
y
=
yo
+
yr
*
sin
(
theta
);
double
d
=
1.0
-
sqrt
(
x
*
x
+
y
*
y
);
if
(
i
>
0
)
if
(
i
>
0
)
{
{
bool
bInt
=
false
;
bool
bInt
=
false
;
if
(
d
>=
0.0
&&
d_prev
<=
0.0
)
if
(
d
>=
0.0
&&
d_prev
<=
0.0
)
{
{
th_interp
=
theta
+
(
step
*
(
-
d_prev
))
/
(
d
-
d_prev
);
th_interp
=
theta
+
(
step
*
(
-
d_prev
)
)
/
(
d
-
d_prev
);
bInt
=
true
;
bInt
=
true
;
}
}
else
if
(
d
<=
0.0
&&
d_prev
>=
0.0
)
else
if
(
d
<=
0.0
&&
d_prev
>=
0.0
)
{
{
th_interp
=
theta
+
(
step
*
d_prev
)
/
(
d_prev
-
d
);
th_interp
=
theta
+
(
step
*
d_prev
)
/
(
d_prev
-
d
);
bInt
=
true
;
bInt
=
true
;
}
}
if
(
bInt
)
if
(
bInt
)
{
{
x
=
xo
+
xr
*
cos
(
th_interp
);
x
=
xo
+
xr
*
cos
(
th_interp
);
y
=
yo
+
yr
*
sin
(
th_interp
);
y
=
yo
+
yr
*
sin
(
th_interp
);
th1
=
atan2
(
y
,
x
);
th1
=
atan2
(
y
,
x
);
if
(
th1
<=
el1
->
theta1
&&
th1
>=
el1
->
theta2
)
if
(
th1
<=
el1
->
theta1
&&
th1
>=
el1
->
theta2
)
{
{
xret
[
n
]
=
x
*
el1
->
xrad
+
el1
->
Center
.
X
;
xret
[
n
]
=
x
*
el1
->
xrad
+
el1
->
Center
.
X
;
yret
[
n
]
=
y
*
el1
->
yrad
+
el1
->
Center
.
Y
;
yret
[
n
]
=
y
*
el1
->
yrad
+
el1
->
Center
.
Y
;
n
++
;
n
++
;
if
(
n
>
2
)
if
(
n
>
2
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
}
}
}
}
}
}
d_prev
=
d
;
d_prev
=
d
;
}
}
if
(
x1
)
if
(
x1
)
*
x1
=
xret
[
0
];
*
x1
=
xret
[
0
];
if
(
y1
)
if
(
y1
)
*
y1
=
yret
[
0
];
*
y1
=
yret
[
0
];
if
(
x2
)
if
(
x2
)
*
x2
=
xret
[
1
];
*
x2
=
xret
[
1
];
if
(
y2
)
if
(
y2
)
*
y2
=
yret
[
1
];
*
y2
=
yret
[
1
];
return
n
;
return
n
;
}
}
// this finds approximate solution
// this finds approximate solution
//
//
//double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
//
double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
double
GetArcClearance
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
double
GetArcClearance
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
double
*
x1
,
double
*
y1
)
double
*
x1
,
double
*
y1
)
{
{
const
int
NSTEPS
=
32
;
const
int
NSTEPS
=
32
;
if
(
el1
->
theta2
>
el1
->
theta1
)
if
(
el1
->
theta2
>
el1
->
theta1
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
if
(
el2
->
theta2
>
el2
->
theta1
)
if
(
el2
->
theta2
>
el2
->
theta1
)
{
{
wxASSERT
(
0
);
wxASSERT
(
0
);
}
}
// test multiple positions in both arcs, moving clockwise (ie. decreasing theta)
// test multiple positions in both arcs, moving clockwise (ie. decreasing theta)
double
th_start
=
el1
->
theta1
;
double
th_start
=
el1
->
theta1
;
double
th_end
=
el1
->
theta2
;
double
th_end
=
el1
->
theta2
;
double
th_start2
=
el2
->
theta1
;
double
th_start2
=
el2
->
theta1
;
double
th_end2
=
el2
->
theta2
;
double
th_end2
=
el2
->
theta2
;
double
dmin
=
DBL_MAX
;
double
dmin
=
DBL_MAX
;
double
xmin
=
0
,
ymin
=
0
,
thmin
=
0
,
thmin2
=
0
;
double
xmin
=
0
,
ymin
=
0
,
thmin
=
0
,
thmin2
=
0
;
int
nsteps
=
NSTEPS
;
int
nsteps
=
NSTEPS
;
int
nsteps2
=
NSTEPS
;
int
nsteps2
=
NSTEPS
;
double
step
=
(
th_start
-
th_end
)
/
(
nsteps
-
1
);
double
step
=
(
th_start
-
th_end
)
/
(
nsteps
-
1
);
double
step2
=
(
th_start2
-
th_end2
)
/
(
nsteps2
-
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
)
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
);
step
=
(
th_start
-
th_end
)
/
(
nsteps
-
1
);
for
(
int
i
=
0
;
i
<
nsteps
;
i
++
)
for
(
int
i
=
0
;
i
<
nsteps
;
i
++
)
{
{
double
theta
;
double
theta
;
if
(
i
<
nsteps
-
1
)
theta
=
th_start
-
i
*
step
;
if
(
i
<
nsteps
-
1
)
theta
=
th_start
-
i
*
step
;
else
else
theta
=
th_end
;
theta
=
th_end
;
double
x
=
el1
->
Center
.
X
+
el1
->
xrad
*
cos
(
theta
);
double
y
=
el1
->
Center
.
Y
+
el1
->
yrad
*
sin
(
theta
);
double
x
=
el1
->
Center
.
X
+
el1
->
xrad
*
cos
(
theta
);
step2
=
(
th_start2
-
th_end2
)
/
(
nsteps2
-
1
);
for
(
int
i2
=
0
;
i2
<
nsteps2
;
i2
++
)
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
;
double
theta2
;
if
(
i2
<
nsteps2
-
1
)
theta2
=
th_start2
-
i2
*
step2
;
if
(
i2
<
nsteps2
-
1
)
theta2
=
th_start2
-
i2
*
step2
;
else
else
theta2
=
th_end2
;
theta2
=
th_end2
;
double
x2
=
el2
->
Center
.
X
+
el2
->
xrad
*
cos
(
theta2
);
double
y2
=
el2
->
Center
.
Y
+
el2
->
yrad
*
sin
(
theta2
);
double
x2
=
el2
->
Center
.
X
+
el2
->
xrad
*
cos
(
theta2
);
double
d
=
Distance
(
(
int
)
x
,
(
int
)
y
,
(
int
)
x2
,
(
int
)
y2
);
double
y2
=
el2
->
Center
.
Y
+
el2
->
yrad
*
sin
(
theta2
);
double
d
=
Distance
(
(
int
)
x
,
(
int
)
y
,
(
int
)
x2
,
(
int
)
y2
);
if
(
d
<
dmin
)
if
(
d
<
dmin
)
{
{
dmin
=
d
;
dmin
=
d
;
xmin
=
x
;
xmin
=
x
;
ymin
=
y
;
ymin
=
y
;
thmin
=
theta
;
thmin
=
theta
;
thmin2
=
theta2
;
thmin2
=
theta2
;
}
}
}
}
}
}
if
(
step
>
step2
)
if
(
step
>
step2
)
{
{
th_start
=
min
(
el1
->
theta1
,
thmin
+
step
);
th_start
=
min
(
el1
->
theta1
,
thmin
+
step
);
th_end
=
max
(
el1
->
theta2
,
thmin
-
step
);
th_end
=
max
(
el1
->
theta2
,
thmin
-
step
);
step
=
(
th_start
-
th_end
)
/
nsteps
;
step
=
(
th_start
-
th_end
)
/
nsteps
;
}
}
else
else
{
{
th_start2
=
min
(
el2
->
theta1
,
thmin2
+
step2
);
th_start2
=
min
(
el2
->
theta1
,
thmin2
+
step2
);
th_end2
=
max
(
el2
->
theta2
,
thmin2
-
step2
);
th_end2
=
max
(
el2
->
theta2
,
thmin2
-
step2
);
step2
=
(
th_start2
-
th_end2
)
/
nsteps2
;
step2
=
(
th_start2
-
th_end2
)
/
nsteps2
;
}
}
}
}
if
(
x1
)
if
(
x1
)
*
x1
=
xmin
;
*
x1
=
xmin
;
if
(
y1
)
if
(
y1
)
*
y1
=
ymin
;
*
y1
=
ymin
;
return
dmin
;
return
dmin
;
}
}
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