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
e126042b
Commit
e126042b
authored
Dec 29, 2007
by
raburton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
set eol-style native on new files
parent
5eda8a52
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
4471 additions
and
4471 deletions
+4471
-4471
PolyLine.cpp
polygon/PolyLine.cpp
+1888
-1888
PolyLine.h
polygon/PolyLine.h
+177
-177
PolyLine2Kicad.h
polygon/PolyLine2Kicad.h
+94
-94
cdisplaylist_stuff.cpp
polygon/cdisplaylist_stuff.cpp
+85
-85
freepcbDisplayList.h
polygon/freepcbDisplayList.h
+269
-269
freepcb_ids.h
polygon/freepcb_ids.h
+118
-118
math_for_graphics.cpp
polygon/math_for_graphics.cpp
+1736
-1736
math_for_graphics.h
polygon/math_for_graphics.h
+104
-104
No files found.
polygon/PolyLine.cpp
View file @
e126042b
// PolyLine.cpp ... implementation of CPolyLine class
// PolyLine.cpp ... implementation of CPolyLine class
// from FreePCB.
// from FreePCB.
// Adaptation for kicad
// Adaptation for kicad
//
//
using
namespace
std
;
using
namespace
std
;
#include <math.h>
#include <math.h>
#include <vector>
#include <vector>
#include "PolyLine.h"
#include "PolyLine.h"
#define to_int(x) (int)round((x))
#define to_int(x) (int)round((x))
/* Stuff to compile PolyLine.cpp, used in std::vector as CArray. does not work. must be redesigned, only for test */
/* Stuff to compile PolyLine.cpp, used in std::vector as CArray. does not work. must be redesigned, only for test */
#define SetSize reserve
#define SetSize reserve
#define pi 3.14159265359
#define pi 3.14159265359
#define DENOM 10 // to use mils for php clipping
#define DENOM 10 // to use mils for php clipping
//#define DENOM 1 // to use internal units for php clipping
//#define DENOM 1 // to use internal units for php clipping
// dl is a pointer to CDisplayList for drawing graphic elements
// dl is a pointer to CDisplayList for drawing graphic elements
// if dl = NULL, doesn't draw anything but can still hold data
// if dl = NULL, doesn't draw anything but can still hold data
//
//
CPolyLine
::
CPolyLine
(
CDisplayList
*
dl
)
CPolyLine
::
CPolyLine
(
CDisplayList
*
dl
)
{
{
m_dlist
=
dl
;
m_dlist
=
dl
;
m_HatchStyle
=
0
;
m_HatchStyle
=
0
;
m_sel_box
=
0
;
m_sel_box
=
0
;
m_gpc_poly
=
new
gpc_polygon
;
m_gpc_poly
=
new
gpc_polygon
;
m_gpc_poly
->
num_contours
=
0
;
m_gpc_poly
->
num_contours
=
0
;
m_php_poly
=
new
polygon
;
m_php_poly
=
new
polygon
;
}
}
CPolyLine
::
CPolyLine
()
CPolyLine
::
CPolyLine
()
{
{
m_dlist
=
NULL
;
m_dlist
=
NULL
;
m_HatchStyle
=
0
;
m_HatchStyle
=
0
;
m_sel_box
=
0
;
m_sel_box
=
0
;
m_gpc_poly
=
new
gpc_polygon
;
m_gpc_poly
=
new
gpc_polygon
;
m_gpc_poly
->
num_contours
=
0
;
m_gpc_poly
->
num_contours
=
0
;
m_php_poly
=
new
polygon
;
m_php_poly
=
new
polygon
;
}
}
// destructor, removes display elements
// destructor, removes display elements
//
//
CPolyLine
::~
CPolyLine
()
CPolyLine
::~
CPolyLine
()
{
{
Undraw
();
Undraw
();
FreeGpcPoly
();
FreeGpcPoly
();
delete
m_gpc_poly
;
delete
m_gpc_poly
;
delete
m_php_poly
;
delete
m_php_poly
;
}
}
// Use the General Polygon Clipping Library to clip contours
// Use the General Polygon Clipping Library to clip contours
// If this results in new polygons, return them as std::vector p
// If this results in new polygons, return them as std::vector p
// If bRetainArcs == TRUE, try to retain arcs in polys
// If bRetainArcs == TRUE, try to retain arcs in polys
// Returns number of external contours, or -1 if error
// Returns number of external contours, or -1 if error
//
//
int
CPolyLine
::
NormalizeWithGpc
(
std
::
vector
<
CPolyLine
*>
*
pa
,
BOOL
bRetainArcs
)
int
CPolyLine
::
NormalizeWithGpc
(
std
::
vector
<
CPolyLine
*>
*
pa
,
BOOL
bRetainArcs
)
{
{
std
::
vector
<
CArc
>
arc_array
;
std
::
vector
<
CArc
>
arc_array
;
if
(
bRetainArcs
)
if
(
bRetainArcs
)
MakeGpcPoly
(
-
1
,
&
arc_array
);
MakeGpcPoly
(
-
1
,
&
arc_array
);
else
else
MakeGpcPoly
(
-
1
,
NULL
);
MakeGpcPoly
(
-
1
,
NULL
);
Undraw
();
Undraw
();
// now, recreate poly
// now, recreate poly
// first, find outside contours and create new CPolyLines if necessary
// first, find outside contours and create new CPolyLines if necessary
int
n_ext_cont
=
0
;
int
n_ext_cont
=
0
;
for
(
int
ic
=
0
;
ic
<
m_gpc_poly
->
num_contours
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
m_gpc_poly
->
num_contours
;
ic
++
)
{
{
if
(
!
(
m_gpc_poly
->
hole
)[
ic
]
)
if
(
!
(
m_gpc_poly
->
hole
)[
ic
]
)
{
{
if
(
n_ext_cont
==
0
)
if
(
n_ext_cont
==
0
)
{
{
// first external contour, replace this poly
// first external contour, replace this poly
corner
.
clear
();
corner
.
clear
();
side_style
.
clear
();
side_style
.
clear
();
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
{
{
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
if
(
i
==
0
)
if
(
i
==
0
)
Start
(
m_layer
,
m_Width
,
m_sel_box
,
x
,
y
,
m_HatchStyle
);
Start
(
m_layer
,
m_Width
,
m_sel_box
,
x
,
y
,
m_HatchStyle
);
else
else
AppendCorner
(
x
,
y
,
STRAIGHT
,
FALSE
);
AppendCorner
(
x
,
y
,
STRAIGHT
,
FALSE
);
}
}
Close
();
Close
();
n_ext_cont
++
;
n_ext_cont
++
;
}
}
else
if
(
pa
)
else
if
(
pa
)
{
{
// next external contour, create new poly
// next external contour, create new poly
CPolyLine
*
poly
=
new
CPolyLine
;
CPolyLine
*
poly
=
new
CPolyLine
;
pa
->
SetSize
(
n_ext_cont
);
// put in array
pa
->
SetSize
(
n_ext_cont
);
// put in array
(
*
pa
)[
n_ext_cont
-
1
]
=
poly
;
(
*
pa
)[
n_ext_cont
-
1
]
=
poly
;
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
{
{
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
if
(
i
==
0
)
if
(
i
==
0
)
poly
->
Start
(
m_layer
,
m_Width
,
m_sel_box
,
x
,
y
,
m_HatchStyle
);
poly
->
Start
(
m_layer
,
m_Width
,
m_sel_box
,
x
,
y
,
m_HatchStyle
);
else
else
poly
->
AppendCorner
(
x
,
y
,
STRAIGHT
,
FALSE
);
poly
->
AppendCorner
(
x
,
y
,
STRAIGHT
,
FALSE
);
}
}
poly
->
Close
(
STRAIGHT
,
FALSE
);
poly
->
Close
(
STRAIGHT
,
FALSE
);
n_ext_cont
++
;
n_ext_cont
++
;
}
}
}
}
}
}
// now add cutouts to the CPolyLine(s)
// now add cutouts to the CPolyLine(s)
for
(
int
ic
=
0
;
ic
<
m_gpc_poly
->
num_contours
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
m_gpc_poly
->
num_contours
;
ic
++
)
{
{
if
(
(
m_gpc_poly
->
hole
)[
ic
]
)
if
(
(
m_gpc_poly
->
hole
)[
ic
]
)
{
{
CPolyLine
*
ext_poly
=
NULL
;
CPolyLine
*
ext_poly
=
NULL
;
if
(
n_ext_cont
==
1
)
if
(
n_ext_cont
==
1
)
{
{
ext_poly
=
this
;
ext_poly
=
this
;
}
}
else
else
{
{
// find the polygon that contains this hole
// find the polygon that contains this hole
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
{
{
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
if
(
TestPointInside
(
x
,
y
)
)
if
(
TestPointInside
(
x
,
y
)
)
ext_poly
=
this
;
ext_poly
=
this
;
else
else
{
{
for
(
int
ext_ic
=
0
;
ext_ic
<
n_ext_cont
-
1
;
ext_ic
++
)
for
(
int
ext_ic
=
0
;
ext_ic
<
n_ext_cont
-
1
;
ext_ic
++
)
{
{
if
(
(
*
pa
)[
ext_ic
]
->
TestPointInside
(
x
,
y
)
)
if
(
(
*
pa
)[
ext_ic
]
->
TestPointInside
(
x
,
y
)
)
{
{
ext_poly
=
(
*
pa
)[
ext_ic
];
ext_poly
=
(
*
pa
)[
ext_ic
];
break
;
break
;
}
}
}
}
}
}
if
(
ext_poly
)
if
(
ext_poly
)
break
;
break
;
}
}
}
}
if
(
!
ext_poly
)
if
(
!
ext_poly
)
ASSERT
(
0
);
ASSERT
(
0
);
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
for
(
int
i
=
0
;
i
<
m_gpc_poly
->
contour
[
ic
].
num_vertices
;
i
++
)
{
{
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
x
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
x
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
int
y
=
to_int
(((
m_gpc_poly
->
contour
)[
ic
].
vertex
)[
i
].
y
);
ext_poly
->
AppendCorner
(
x
,
y
,
STRAIGHT
,
FALSE
);
ext_poly
->
AppendCorner
(
x
,
y
,
STRAIGHT
,
FALSE
);
}
}
ext_poly
->
Close
(
STRAIGHT
,
FALSE
);
ext_poly
->
Close
(
STRAIGHT
,
FALSE
);
}
}
}
}
if
(
bRetainArcs
)
if
(
bRetainArcs
)
RestoreArcs
(
&
arc_array
,
pa
);
RestoreArcs
(
&
arc_array
,
pa
);
FreeGpcPoly
();
FreeGpcPoly
();
return
n_ext_cont
;
return
n_ext_cont
;
}
}
// make a php_polygon from first contour
// make a php_polygon from first contour
int
CPolyLine
::
MakePhpPoly
()
int
CPolyLine
::
MakePhpPoly
()
{
{
FreePhpPoly
();
FreePhpPoly
();
polygon
test_poly
;
polygon
test_poly
;
int
nv
=
GetContourEnd
(
0
);
int
nv
=
GetContourEnd
(
0
);
for
(
int
iv
=
0
;
iv
<=
nv
;
iv
++
)
for
(
int
iv
=
0
;
iv
<=
nv
;
iv
++
)
{
{
int
x
=
GetX
(
iv
)
/
DENOM
;
int
x
=
GetX
(
iv
)
/
DENOM
;
int
y
=
GetY
(
iv
)
/
DENOM
;
int
y
=
GetY
(
iv
)
/
DENOM
;
m_php_poly
->
addv
(
x
,
y
);
m_php_poly
->
addv
(
x
,
y
);
}
}
return
0
;
return
0
;
}
}
void
CPolyLine
::
FreePhpPoly
()
void
CPolyLine
::
FreePhpPoly
()
{
{
// delete all vertices
// delete all vertices
while
(
m_php_poly
->
m_cnt
>
1
)
while
(
m_php_poly
->
m_cnt
>
1
)
{
{
vertex
*
fv
=
m_php_poly
->
getFirst
();
vertex
*
fv
=
m_php_poly
->
getFirst
();
m_php_poly
->
del
(
fv
->
m_nextV
);
m_php_poly
->
del
(
fv
->
m_nextV
);
}
}
delete
m_php_poly
->
m_first
;
delete
m_php_poly
->
m_first
;
m_php_poly
->
m_first
=
NULL
;
m_php_poly
->
m_first
=
NULL
;
m_php_poly
->
m_cnt
=
0
;
m_php_poly
->
m_cnt
=
0
;
}
}
// Use the php clipping lib to clip this poly against poly
// Use the php clipping lib to clip this poly against poly
//
//
void
CPolyLine
::
ClipPhpPolygon
(
int
php_op
,
CPolyLine
*
poly
)
void
CPolyLine
::
ClipPhpPolygon
(
int
php_op
,
CPolyLine
*
poly
)
{
{
Undraw
();
Undraw
();
poly
->
MakePhpPoly
();
poly
->
MakePhpPoly
();
MakePhpPoly
();
MakePhpPoly
();
polygon
*
p
=
m_php_poly
->
boolean
(
poly
->
m_php_poly
,
php_op
);
polygon
*
p
=
m_php_poly
->
boolean
(
poly
->
m_php_poly
,
php_op
);
poly
->
FreePhpPoly
();
poly
->
FreePhpPoly
();
FreePhpPoly
();
FreePhpPoly
();
if
(
p
)
if
(
p
)
{
{
// now screw with the PolyLine
// now screw with the PolyLine
corner
.
clear
();
corner
.
clear
();
side_style
.
clear
();
side_style
.
clear
();
do
do
{
{
vertex
*
v
=
p
->
getFirst
();
vertex
*
v
=
p
->
getFirst
();
Start
(
m_layer
,
m_Width
,
m_sel_box
,
Start
(
m_layer
,
m_Width
,
m_sel_box
,
to_int
(
v
->
X
()
*
DENOM
),
to_int
(
v
->
X
()
*
DENOM
),
to_int
(
v
->
Y
()
*
DENOM
),
to_int
(
v
->
Y
()
*
DENOM
),
m_HatchStyle
);
m_HatchStyle
);
do
do
{
{
vertex
*
n
=
v
->
Next
();
vertex
*
n
=
v
->
Next
();
AppendCorner
(
to_int
(
v
->
X
()
*
DENOM
),
to_int
((
v
->
Y
()
*
DENOM
))
);
AppendCorner
(
to_int
(
v
->
X
()
*
DENOM
),
to_int
((
v
->
Y
()
*
DENOM
))
);
v
=
n
;
v
=
n
;
}
}
while
(
v
->
id
()
!=
p
->
getFirst
()
->
id
()
);
while
(
v
->
id
()
!=
p
->
getFirst
()
->
id
()
);
Close
();
Close
();
// p = p->NextPoly();
// p = p->NextPoly();
delete
p
;
delete
p
;
p
=
NULL
;
p
=
NULL
;
}
}
while
(
p
);
while
(
p
);
}
}
Draw
();
Draw
();
}
}
// make a gpc_polygon for a closed polyline contour
// make a gpc_polygon for a closed polyline contour
// approximates arcs with multiple straight-line segments
// approximates arcs with multiple straight-line segments
// if icontour = -1, make polygon with all contours,
// if icontour = -1, make polygon with all contours,
// combining intersecting contours if possible
// combining intersecting contours if possible
// returns data on arcs in arc_array
// returns data on arcs in arc_array
//
//
int
CPolyLine
::
MakeGpcPoly
(
int
icontour
,
std
::
vector
<
CArc
>
*
arc_array
)
int
CPolyLine
::
MakeGpcPoly
(
int
icontour
,
std
::
vector
<
CArc
>
*
arc_array
)
{
{
if
(
m_gpc_poly
->
num_contours
)
if
(
m_gpc_poly
->
num_contours
)
FreeGpcPoly
();
FreeGpcPoly
();
if
(
!
GetClosed
()
&&
(
icontour
==
(
GetNumContours
()
-
1
)
||
icontour
==
-
1
))
if
(
!
GetClosed
()
&&
(
icontour
==
(
GetNumContours
()
-
1
)
||
icontour
==
-
1
))
return
1
;
// error
return
1
;
// error
// initialize m_gpc_poly
// initialize m_gpc_poly
m_gpc_poly
->
num_contours
=
0
;
m_gpc_poly
->
num_contours
=
0
;
m_gpc_poly
->
hole
=
NULL
;
m_gpc_poly
->
hole
=
NULL
;
m_gpc_poly
->
contour
=
NULL
;
m_gpc_poly
->
contour
=
NULL
;
int
n_arcs
=
0
;
int
n_arcs
=
0
;
int
first_contour
=
icontour
;
int
first_contour
=
icontour
;
int
last_contour
=
icontour
;
int
last_contour
=
icontour
;
if
(
icontour
==
-
1
)
if
(
icontour
==
-
1
)
{
{
first_contour
=
0
;
first_contour
=
0
;
last_contour
=
GetNumContours
()
-
1
;
last_contour
=
GetNumContours
()
-
1
;
}
}
if
(
arc_array
)
if
(
arc_array
)
arc_array
->
SetSize
(
0
);
arc_array
->
SetSize
(
0
);
int
iarc
=
0
;
int
iarc
=
0
;
for
(
int
icont
=
first_contour
;
icont
<=
last_contour
;
icont
++
)
for
(
int
icont
=
first_contour
;
icont
<=
last_contour
;
icont
++
)
{
{
// make gpc_polygon for this contour
// make gpc_polygon for this contour
gpc_polygon
*
gpc
=
new
gpc_polygon
;
gpc_polygon
*
gpc
=
new
gpc_polygon
;
gpc
->
num_contours
=
0
;
gpc
->
num_contours
=
0
;
gpc
->
hole
=
NULL
;
gpc
->
hole
=
NULL
;
gpc
->
contour
=
NULL
;
gpc
->
contour
=
NULL
;
// first, calculate number of vertices in contour
// first, calculate number of vertices in contour
int
n_vertices
=
0
;
int
n_vertices
=
0
;
int
ic_st
=
GetContourStart
(
icont
);
int
ic_st
=
GetContourStart
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
for
(
int
ic
=
ic_st
;
ic
<=
ic_end
;
ic
++
)
for
(
int
ic
=
ic_st
;
ic
<=
ic_end
;
ic
++
)
{
{
int
style
=
side_style
[
ic
];
int
style
=
side_style
[
ic
];
int
x1
=
corner
[
ic
].
x
;
int
x1
=
corner
[
ic
].
x
;
int
y1
=
corner
[
ic
].
y
;
int
y1
=
corner
[
ic
].
y
;
int
x2
,
y2
;
int
x2
,
y2
;
if
(
ic
<
ic_end
)
if
(
ic
<
ic_end
)
{
{
x2
=
corner
[
ic
+
1
].
x
;
x2
=
corner
[
ic
+
1
].
x
;
y2
=
corner
[
ic
+
1
].
y
;
y2
=
corner
[
ic
+
1
].
y
;
}
}
else
else
{
{
x2
=
corner
[
ic_st
].
x
;
x2
=
corner
[
ic_st
].
x
;
y2
=
corner
[
ic_st
].
y
;
y2
=
corner
[
ic_st
].
y
;
}
}
if
(
style
==
STRAIGHT
)
if
(
style
==
STRAIGHT
)
n_vertices
++
;
n_vertices
++
;
else
else
{
{
// style is ARC_CW or ARC_CCW
// style is ARC_CW or ARC_CCW
int
n
;
// number of steps for arcs
int
n
;
// number of steps for arcs
n
=
(
abs
(
x2
-
x1
)
+
abs
(
y2
-
y1
))
/
(
CArc
::
MAX_STEP
);
n
=
(
abs
(
x2
-
x1
)
+
abs
(
y2
-
y1
))
/
(
CArc
::
MAX_STEP
);
n
=
max
(
n
,
CArc
::
MIN_STEPS
);
// or at most 5 degrees of arc
n
=
max
(
n
,
CArc
::
MIN_STEPS
);
// or at most 5 degrees of arc
n_vertices
+=
n
;
n_vertices
+=
n
;
n_arcs
++
;
n_arcs
++
;
}
}
}
}
// now create gcp_vertex_list for this contour
// now create gcp_vertex_list for this contour
gpc_vertex_list
*
g_v_list
=
new
gpc_vertex_list
;
gpc_vertex_list
*
g_v_list
=
new
gpc_vertex_list
;
g_v_list
->
vertex
=
(
gpc_vertex
*
)
calloc
(
sizeof
(
gpc_vertex
),
n_vertices
);
g_v_list
->
vertex
=
(
gpc_vertex
*
)
calloc
(
sizeof
(
gpc_vertex
),
n_vertices
);
g_v_list
->
num_vertices
=
n_vertices
;
g_v_list
->
num_vertices
=
n_vertices
;
int
ivtx
=
0
;
int
ivtx
=
0
;
for
(
int
ic
=
ic_st
;
ic
<=
ic_end
;
ic
++
)
for
(
int
ic
=
ic_st
;
ic
<=
ic_end
;
ic
++
)
{
{
int
style
=
side_style
[
ic
];
int
style
=
side_style
[
ic
];
int
x1
=
corner
[
ic
].
x
;
int
x1
=
corner
[
ic
].
x
;
int
y1
=
corner
[
ic
].
y
;
int
y1
=
corner
[
ic
].
y
;
int
x2
,
y2
;
int
x2
,
y2
;
if
(
ic
<
ic_end
)
if
(
ic
<
ic_end
)
{
{
x2
=
corner
[
ic
+
1
].
x
;
x2
=
corner
[
ic
+
1
].
x
;
y2
=
corner
[
ic
+
1
].
y
;
y2
=
corner
[
ic
+
1
].
y
;
}
}
else
else
{
{
x2
=
corner
[
ic_st
].
x
;
x2
=
corner
[
ic_st
].
x
;
y2
=
corner
[
ic_st
].
y
;
y2
=
corner
[
ic_st
].
y
;
}
}
if
(
style
==
STRAIGHT
)
if
(
style
==
STRAIGHT
)
{
{
g_v_list
->
vertex
[
ivtx
].
x
=
x1
;
g_v_list
->
vertex
[
ivtx
].
x
=
x1
;
g_v_list
->
vertex
[
ivtx
].
y
=
y1
;
g_v_list
->
vertex
[
ivtx
].
y
=
y1
;
ivtx
++
;
ivtx
++
;
}
}
else
else
{
{
// style is arc_cw or arc_ccw
// style is arc_cw or arc_ccw
int
n
;
// number of steps for arcs
int
n
;
// number of steps for arcs
n
=
(
abs
(
x2
-
x1
)
+
abs
(
y2
-
y1
))
/
(
CArc
::
MAX_STEP
);
n
=
(
abs
(
x2
-
x1
)
+
abs
(
y2
-
y1
))
/
(
CArc
::
MAX_STEP
);
n
=
max
(
n
,
CArc
::
MIN_STEPS
);
// or at most 5 degrees of arc
n
=
max
(
n
,
CArc
::
MIN_STEPS
);
// or at most 5 degrees of arc
double
xo
,
yo
,
theta1
,
theta2
,
a
,
b
;
double
xo
,
yo
,
theta1
,
theta2
,
a
,
b
;
a
=
fabs
(
(
double
)(
x1
-
x2
)
);
a
=
fabs
(
(
double
)(
x1
-
x2
)
);
b
=
fabs
(
(
double
)(
y1
-
y2
)
);
b
=
fabs
(
(
double
)(
y1
-
y2
)
);
if
(
style
==
CPolyLine
::
ARC_CW
)
if
(
style
==
CPolyLine
::
ARC_CW
)
{
{
// clockwise arc (ie.quadrant of ellipse)
// clockwise arc (ie.quadrant of ellipse)
if
(
x2
>
x1
&&
y2
>
y1
)
if
(
x2
>
x1
&&
y2
>
y1
)
{
{
// first quadrant, draw second quadrant of ellipse
// first quadrant, draw second quadrant of ellipse
xo
=
x2
;
xo
=
x2
;
yo
=
y1
;
yo
=
y1
;
theta1
=
pi
;
theta1
=
pi
;
theta2
=
pi
/
2.0
;
theta2
=
pi
/
2.0
;
}
}
else
if
(
x2
<
x1
&&
y2
>
y1
)
else
if
(
x2
<
x1
&&
y2
>
y1
)
{
{
// second quadrant, draw third quadrant of ellipse
// second quadrant, draw third quadrant of ellipse
xo
=
x1
;
xo
=
x1
;
yo
=
y2
;
yo
=
y2
;
theta1
=
3.0
*
pi
/
2.0
;
theta1
=
3.0
*
pi
/
2.0
;
theta2
=
pi
;
theta2
=
pi
;
}
}
else
if
(
x2
<
x1
&&
y2
<
y1
)
else
if
(
x2
<
x1
&&
y2
<
y1
)
{
{
// third quadrant, draw fourth quadrant of ellipse
// third quadrant, draw fourth quadrant of ellipse
xo
=
x2
;
xo
=
x2
;
yo
=
y1
;
yo
=
y1
;
theta1
=
2.0
*
pi
;
theta1
=
2.0
*
pi
;
theta2
=
3.0
*
pi
/
2.0
;
theta2
=
3.0
*
pi
/
2.0
;
}
}
else
else
{
{
xo
=
x1
;
// fourth quadrant, draw first quadrant of ellipse
xo
=
x1
;
// fourth quadrant, draw first quadrant of ellipse
yo
=
y2
;
yo
=
y2
;
theta1
=
pi
/
2.0
;
theta1
=
pi
/
2.0
;
theta2
=
0.0
;
theta2
=
0.0
;
}
}
}
}
else
else
{
{
// counter-clockwise arc
// counter-clockwise arc
if
(
x2
>
x1
&&
y2
>
y1
)
if
(
x2
>
x1
&&
y2
>
y1
)
{
{
xo
=
x1
;
// first quadrant, draw fourth quadrant of ellipse
xo
=
x1
;
// first quadrant, draw fourth quadrant of ellipse
yo
=
y2
;
yo
=
y2
;
theta1
=
3.0
*
pi
/
2.0
;
theta1
=
3.0
*
pi
/
2.0
;
theta2
=
2.0
*
pi
;
theta2
=
2.0
*
pi
;
}
}
else
if
(
x2
<
x1
&&
y2
>
y1
)
else
if
(
x2
<
x1
&&
y2
>
y1
)
{
{
xo
=
x2
;
// second quadrant
xo
=
x2
;
// second quadrant
yo
=
y1
;
yo
=
y1
;
theta1
=
0.0
;
theta1
=
0.0
;
theta2
=
pi
/
2.0
;
theta2
=
pi
/
2.0
;
}
}
else
if
(
x2
<
x1
&&
y2
<
y1
)
else
if
(
x2
<
x1
&&
y2
<
y1
)
{
{
xo
=
x1
;
// third quadrant
xo
=
x1
;
// third quadrant
yo
=
y2
;
yo
=
y2
;
theta1
=
pi
/
2.0
;
theta1
=
pi
/
2.0
;
theta2
=
pi
;
theta2
=
pi
;
}
}
else
else
{
{
xo
=
x2
;
// fourth quadrant
xo
=
x2
;
// fourth quadrant
yo
=
y1
;
yo
=
y1
;
theta1
=
pi
;
theta1
=
pi
;
theta2
=
3.0
*
pi
/
2.0
;
theta2
=
3.0
*
pi
/
2.0
;
}
}
}
}
// now write steps for arc
// now write steps for arc
if
(
arc_array
)
if
(
arc_array
)
{
{
arc_array
->
SetSize
(
iarc
+
1
);
arc_array
->
SetSize
(
iarc
+
1
);
(
*
arc_array
)[
iarc
].
style
=
style
;
(
*
arc_array
)[
iarc
].
style
=
style
;
(
*
arc_array
)[
iarc
].
n_steps
=
n
;
(
*
arc_array
)[
iarc
].
n_steps
=
n
;
(
*
arc_array
)[
iarc
].
xi
=
x1
;
(
*
arc_array
)[
iarc
].
xi
=
x1
;
(
*
arc_array
)[
iarc
].
yi
=
y1
;
(
*
arc_array
)[
iarc
].
yi
=
y1
;
(
*
arc_array
)[
iarc
].
xf
=
x2
;
(
*
arc_array
)[
iarc
].
xf
=
x2
;
(
*
arc_array
)[
iarc
].
yf
=
y2
;
(
*
arc_array
)[
iarc
].
yf
=
y2
;
iarc
++
;
iarc
++
;
}
}
for
(
int
is
=
0
;
is
<
n
;
is
++
)
for
(
int
is
=
0
;
is
<
n
;
is
++
)
{
{
double
theta
=
theta1
+
((
theta2
-
theta1
)
*
(
double
)
is
)
/
n
;
double
theta
=
theta1
+
((
theta2
-
theta1
)
*
(
double
)
is
)
/
n
;
double
x
=
xo
+
a
*
cos
(
theta
);
double
x
=
xo
+
a
*
cos
(
theta
);
double
y
=
yo
+
b
*
sin
(
theta
);
double
y
=
yo
+
b
*
sin
(
theta
);
if
(
is
==
0
)
if
(
is
==
0
)
{
{
x
=
x1
;
x
=
x1
;
y
=
y1
;
y
=
y1
;
}
}
g_v_list
->
vertex
[
ivtx
].
x
=
x
;
g_v_list
->
vertex
[
ivtx
].
x
=
x
;
g_v_list
->
vertex
[
ivtx
].
y
=
y
;
g_v_list
->
vertex
[
ivtx
].
y
=
y
;
ivtx
++
;
ivtx
++
;
}
}
}
}
}
}
if
(
n_vertices
!=
ivtx
)
if
(
n_vertices
!=
ivtx
)
ASSERT
(
0
);
ASSERT
(
0
);
// add vertex_list to gpc
// add vertex_list to gpc
gpc_add_contour
(
gpc
,
g_v_list
,
0
);
gpc_add_contour
(
gpc
,
g_v_list
,
0
);
// now clip m_gpc_poly with gpc, put new poly into result
// now clip m_gpc_poly with gpc, put new poly into result
gpc_polygon
*
result
=
new
gpc_polygon
;
gpc_polygon
*
result
=
new
gpc_polygon
;
if
(
icontour
==
-
1
&&
icont
!=
0
)
if
(
icontour
==
-
1
&&
icont
!=
0
)
gpc_polygon_clip
(
GPC_DIFF
,
m_gpc_poly
,
gpc
,
result
);
// hole
gpc_polygon_clip
(
GPC_DIFF
,
m_gpc_poly
,
gpc
,
result
);
// hole
else
else
gpc_polygon_clip
(
GPC_UNION
,
m_gpc_poly
,
gpc
,
result
);
// outside
gpc_polygon_clip
(
GPC_UNION
,
m_gpc_poly
,
gpc
,
result
);
// outside
// now copy result to m_gpc_poly
// now copy result to m_gpc_poly
gpc_free_polygon
(
m_gpc_poly
);
gpc_free_polygon
(
m_gpc_poly
);
delete
m_gpc_poly
;
delete
m_gpc_poly
;
m_gpc_poly
=
result
;
m_gpc_poly
=
result
;
gpc_free_polygon
(
gpc
);
gpc_free_polygon
(
gpc
);
delete
gpc
;
delete
gpc
;
free
(
g_v_list
->
vertex
);
free
(
g_v_list
->
vertex
);
free
(
g_v_list
);
free
(
g_v_list
);
}
}
return
0
;
return
0
;
}
}
int
CPolyLine
::
FreeGpcPoly
()
int
CPolyLine
::
FreeGpcPoly
()
{
{
if
(
m_gpc_poly
->
num_contours
)
if
(
m_gpc_poly
->
num_contours
)
{
{
delete
m_gpc_poly
->
contour
->
vertex
;
delete
m_gpc_poly
->
contour
->
vertex
;
delete
m_gpc_poly
->
contour
;
delete
m_gpc_poly
->
contour
;
delete
m_gpc_poly
->
hole
;
delete
m_gpc_poly
->
hole
;
}
}
m_gpc_poly
->
num_contours
=
0
;
m_gpc_poly
->
num_contours
=
0
;
return
0
;
return
0
;
}
}
// Restore arcs to a polygon where they were replaced with steps
// Restore arcs to a polygon where they were replaced with steps
// If pa != NULL, also use polygons in pa array
// If pa != NULL, also use polygons in pa array
//
//
int
CPolyLine
::
RestoreArcs
(
std
::
vector
<
CArc
>
*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
)
int
CPolyLine
::
RestoreArcs
(
std
::
vector
<
CArc
>
*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
)
{
{
// get poly info
// get poly info
int
n_polys
=
1
;
int
n_polys
=
1
;
if
(
pa
)
if
(
pa
)
n_polys
+=
pa
->
size
();
n_polys
+=
pa
->
size
();
CPolyLine
*
poly
;
CPolyLine
*
poly
;
// undraw polys and clear utility flag for all corners
// undraw polys and clear utility flag for all corners
for
(
int
ip
=
0
;
ip
<
n_polys
;
ip
++
)
for
(
int
ip
=
0
;
ip
<
n_polys
;
ip
++
)
{
{
if
(
ip
==
0
)
if
(
ip
==
0
)
poly
=
this
;
poly
=
this
;
else
else
poly
=
(
*
pa
)[
ip
-
1
];
poly
=
(
*
pa
)[
ip
-
1
];
poly
->
Undraw
();
poly
->
Undraw
();
for
(
int
ic
=
0
;
ic
<
poly
->
GetNumCorners
();
ic
++
)
for
(
int
ic
=
0
;
ic
<
poly
->
GetNumCorners
();
ic
++
)
poly
->
SetUtility
(
ic
,
0
);
// clear utility flag
poly
->
SetUtility
(
ic
,
0
);
// clear utility flag
}
}
// find arcs and replace them
// find arcs and replace them
BOOL
bFound
;
BOOL
bFound
;
int
arc_start
;
int
arc_start
;
int
arc_end
;
int
arc_end
;
for
(
unsigned
iarc
=
0
;
iarc
<
arc_array
->
size
();
iarc
++
)
for
(
unsigned
iarc
=
0
;
iarc
<
arc_array
->
size
();
iarc
++
)
{
{
int
arc_xi
=
(
*
arc_array
)[
iarc
].
xi
;
int
arc_xi
=
(
*
arc_array
)[
iarc
].
xi
;
int
arc_yi
=
(
*
arc_array
)[
iarc
].
yi
;
int
arc_yi
=
(
*
arc_array
)[
iarc
].
yi
;
int
arc_xf
=
(
*
arc_array
)[
iarc
].
xf
;
int
arc_xf
=
(
*
arc_array
)[
iarc
].
xf
;
int
arc_yf
=
(
*
arc_array
)[
iarc
].
yf
;
int
arc_yf
=
(
*
arc_array
)[
iarc
].
yf
;
int
n_steps
=
(
*
arc_array
)[
iarc
].
n_steps
;
int
n_steps
=
(
*
arc_array
)[
iarc
].
n_steps
;
int
style
=
(
*
arc_array
)[
iarc
].
style
;
int
style
=
(
*
arc_array
)[
iarc
].
style
;
bFound
=
FALSE
;
bFound
=
FALSE
;
// loop through polys
// loop through polys
for
(
int
ip
=
0
;
ip
<
n_polys
;
ip
++
)
for
(
int
ip
=
0
;
ip
<
n_polys
;
ip
++
)
{
{
if
(
ip
==
0
)
if
(
ip
==
0
)
poly
=
this
;
poly
=
this
;
else
else
poly
=
(
*
pa
)[
ip
-
1
];
poly
=
(
*
pa
)[
ip
-
1
];
for
(
int
icont
=
0
;
icont
<
poly
->
GetNumContours
();
icont
++
)
for
(
int
icont
=
0
;
icont
<
poly
->
GetNumContours
();
icont
++
)
{
{
int
ic_start
=
poly
->
GetContourStart
(
icont
);
int
ic_start
=
poly
->
GetContourStart
(
icont
);
int
ic_end
=
poly
->
GetContourEnd
(
icont
);
int
ic_end
=
poly
->
GetContourEnd
(
icont
);
if
(
(
ic_end
-
ic_start
)
>
n_steps
)
if
(
(
ic_end
-
ic_start
)
>
n_steps
)
{
{
for
(
int
ic
=
ic_start
;
ic
<=
ic_end
;
ic
++
)
for
(
int
ic
=
ic_start
;
ic
<=
ic_end
;
ic
++
)
{
{
int
ic_next
=
ic
+
1
;
int
ic_next
=
ic
+
1
;
if
(
ic_next
>
ic_end
)
if
(
ic_next
>
ic_end
)
ic_next
=
ic_start
;
ic_next
=
ic_start
;
int
xi
=
poly
->
GetX
(
ic
);
int
xi
=
poly
->
GetX
(
ic
);
int
yi
=
poly
->
GetY
(
ic
);
int
yi
=
poly
->
GetY
(
ic
);
if
(
xi
==
arc_xi
&&
yi
==
arc_yi
)
if
(
xi
==
arc_xi
&&
yi
==
arc_yi
)
{
{
// test for forward arc
// test for forward arc
int
ic2
=
ic
+
n_steps
;
int
ic2
=
ic
+
n_steps
;
if
(
ic2
>
ic_end
)
if
(
ic2
>
ic_end
)
ic2
=
ic2
-
ic_end
+
ic_start
-
1
;
ic2
=
ic2
-
ic_end
+
ic_start
-
1
;
int
xf
=
poly
->
GetX
(
ic2
);
int
xf
=
poly
->
GetX
(
ic2
);
int
yf
=
poly
->
GetY
(
ic2
);
int
yf
=
poly
->
GetY
(
ic2
);
if
(
xf
==
arc_xf
&&
yf
==
arc_yf
)
if
(
xf
==
arc_xf
&&
yf
==
arc_yf
)
{
{
// arc from ic to ic2
// arc from ic to ic2
bFound
=
TRUE
;
bFound
=
TRUE
;
arc_start
=
ic
;
arc_start
=
ic
;
arc_end
=
ic2
;
arc_end
=
ic2
;
}
}
else
else
{
{
// try reverse arc
// try reverse arc
ic2
=
ic
-
n_steps
;
ic2
=
ic
-
n_steps
;
if
(
ic2
<
ic_start
)
if
(
ic2
<
ic_start
)
ic2
=
ic2
-
ic_start
+
ic_end
+
1
;
ic2
=
ic2
-
ic_start
+
ic_end
+
1
;
xf
=
poly
->
GetX
(
ic2
);
xf
=
poly
->
GetX
(
ic2
);
yf
=
poly
->
GetY
(
ic2
);
yf
=
poly
->
GetY
(
ic2
);
if
(
xf
==
arc_xf
&&
yf
==
arc_yf
)
if
(
xf
==
arc_xf
&&
yf
==
arc_yf
)
{
{
// arc from ic2 to ic
// arc from ic2 to ic
bFound
=
TRUE
;
bFound
=
TRUE
;
arc_start
=
ic2
;
arc_start
=
ic2
;
arc_end
=
ic
;
arc_end
=
ic
;
style
=
3
-
style
;
style
=
3
-
style
;
}
}
}
}
if
(
bFound
)
if
(
bFound
)
{
{
poly
->
side_style
[
arc_start
]
=
style
;
poly
->
side_style
[
arc_start
]
=
style
;
// mark corners for deletion from arc_start+1 to arc_end-1
// mark corners for deletion from arc_start+1 to arc_end-1
for
(
int
i
=
arc_start
+
1
;
i
!=
arc_end
;
)
for
(
int
i
=
arc_start
+
1
;
i
!=
arc_end
;
)
{
{
if
(
i
>
ic_end
)
if
(
i
>
ic_end
)
i
=
ic_start
;
i
=
ic_start
;
poly
->
SetUtility
(
i
,
1
);
poly
->
SetUtility
(
i
,
1
);
if
(
i
==
ic_end
)
if
(
i
==
ic_end
)
i
=
ic_start
;
i
=
ic_start
;
else
else
i
++
;
i
++
;
}
}
break
;
break
;
}
}
}
}
if
(
bFound
)
if
(
bFound
)
break
;
break
;
}
}
}
}
if
(
bFound
)
if
(
bFound
)
break
;
break
;
}
}
}
}
if
(
bFound
)
if
(
bFound
)
(
*
arc_array
)[
iarc
].
bFound
=
TRUE
;
(
*
arc_array
)[
iarc
].
bFound
=
TRUE
;
}
}
// now delete all marked corners
// now delete all marked corners
for
(
int
ip
=
0
;
ip
<
n_polys
;
ip
++
)
for
(
int
ip
=
0
;
ip
<
n_polys
;
ip
++
)
{
{
if
(
ip
==
0
)
if
(
ip
==
0
)
poly
=
this
;
poly
=
this
;
else
else
poly
=
(
*
pa
)[
ip
-
1
];
poly
=
(
*
pa
)[
ip
-
1
];
for
(
int
ic
=
poly
->
GetNumCorners
()
-
1
;
ic
>=
0
;
ic
--
)
for
(
int
ic
=
poly
->
GetNumCorners
()
-
1
;
ic
>=
0
;
ic
--
)
{
{
if
(
poly
->
GetUtility
(
ic
)
)
if
(
poly
->
GetUtility
(
ic
)
)
poly
->
DeleteCorner
(
ic
,
FALSE
);
poly
->
DeleteCorner
(
ic
,
FALSE
);
}
}
}
}
return
0
;
return
0
;
}
}
// initialize new polyline
// initialize new polyline
// set layer, width, selection box size, starting point, id and pointer
// set layer, width, selection box size, starting point, id and pointer
//
//
// if sel_box = 0, don't create selection elements at all
// if sel_box = 0, don't create selection elements at all
//
//
// if polyline is board outline, enter with:
// if polyline is board outline, enter with:
// id.type = ID_BOARD
// id.type = ID_BOARD
// id.st = ID_BOARD_OUTLINE
// id.st = ID_BOARD_OUTLINE
// id.i = 0
// id.i = 0
// ptr = NULL
// ptr = NULL
//
//
// if polyline is copper area, enter with:
// if polyline is copper area, enter with:
// id.type = ID_NET;
// id.type = ID_NET;
// id.st = ID_AREA
// id.st = ID_AREA
// id.i = index to area
// id.i = index to area
// ptr = pointer to net
// ptr = pointer to net
//
//
void
CPolyLine
::
Start
(
int
layer
,
int
w
,
int
sel_box
,
int
x
,
int
y
,
void
CPolyLine
::
Start
(
int
layer
,
int
w
,
int
sel_box
,
int
x
,
int
y
,
int
hatch
)
int
hatch
)
{
{
m_layer
=
layer
;
m_layer
=
layer
;
m_Width
=
w
;
m_Width
=
w
;
m_sel_box
=
sel_box
;
m_sel_box
=
sel_box
;
m_HatchStyle
=
hatch
;
m_HatchStyle
=
hatch
;
CPolyPt
poly_pt
(
x
,
y
);
CPolyPt
poly_pt
(
x
,
y
);
poly_pt
.
end_contour
=
FALSE
;
poly_pt
.
end_contour
=
FALSE
;
corner
.
push_back
(
poly_pt
);
corner
.
push_back
(
poly_pt
);
side_style
.
push_back
(
0
);
side_style
.
push_back
(
0
);
}
}
// add a corner to unclosed polyline
// add a corner to unclosed polyline
//
//
void
CPolyLine
::
AppendCorner
(
int
x
,
int
y
,
int
style
,
BOOL
bDraw
)
void
CPolyLine
::
AppendCorner
(
int
x
,
int
y
,
int
style
,
BOOL
bDraw
)
{
{
Undraw
();
Undraw
();
CPolyPt
poly_pt
(
x
,
y
);
CPolyPt
poly_pt
(
x
,
y
);
poly_pt
.
end_contour
=
FALSE
;
poly_pt
.
end_contour
=
FALSE
;
// add entries for new corner and side
// add entries for new corner and side
corner
.
push_back
(
poly_pt
);
corner
.
push_back
(
poly_pt
);
side_style
.
push_back
(
style
);
side_style
.
push_back
(
style
);
if
(
corner
.
size
()
>
0
&&
!
corner
[
corner
.
size
()
-
1
].
end_contour
)
if
(
corner
.
size
()
>
0
&&
!
corner
[
corner
.
size
()
-
1
].
end_contour
)
side_style
[
corner
.
size
()
-
1
]
=
style
;
side_style
[
corner
.
size
()
-
1
]
=
style
;
int
dl_type
;
int
dl_type
;
if
(
style
==
CPolyLine
::
STRAIGHT
)
if
(
style
==
CPolyLine
::
STRAIGHT
)
dl_type
=
DL_LINE
;
dl_type
=
DL_LINE
;
else
if
(
style
==
CPolyLine
::
ARC_CW
)
else
if
(
style
==
CPolyLine
::
ARC_CW
)
dl_type
=
DL_ARC_CW
;
dl_type
=
DL_ARC_CW
;
else
if
(
style
==
CPolyLine
::
ARC_CCW
)
else
if
(
style
==
CPolyLine
::
ARC_CCW
)
dl_type
=
DL_ARC_CCW
;
dl_type
=
DL_ARC_CCW
;
else
else
ASSERT
(
0
);
ASSERT
(
0
);
if
(
bDraw
)
if
(
bDraw
)
Draw
();
Draw
();
}
}
// close last polyline contour
// close last polyline contour
//
//
void
CPolyLine
::
Close
(
int
style
,
BOOL
bDraw
)
void
CPolyLine
::
Close
(
int
style
,
BOOL
bDraw
)
{
{
if
(
GetClosed
()
)
if
(
GetClosed
()
)
ASSERT
(
0
);
ASSERT
(
0
);
Undraw
();
Undraw
();
side_style
[
corner
.
size
()
-
1
]
=
style
;
side_style
[
corner
.
size
()
-
1
]
=
style
;
corner
[
corner
.
size
()
-
1
].
end_contour
=
TRUE
;
corner
[
corner
.
size
()
-
1
].
end_contour
=
TRUE
;
if
(
bDraw
)
if
(
bDraw
)
Draw
();
Draw
();
}
}
// move corner of polyline
// move corner of polyline
//
//
void
CPolyLine
::
MoveCorner
(
int
ic
,
int
x
,
int
y
)
void
CPolyLine
::
MoveCorner
(
int
ic
,
int
x
,
int
y
)
{
{
Undraw
();
Undraw
();
corner
[
ic
].
x
=
x
;
corner
[
ic
].
x
=
x
;
corner
[
ic
].
y
=
y
;
corner
[
ic
].
y
=
y
;
Draw
();
Draw
();
}
}
// delete corner and adjust arrays
// delete corner and adjust arrays
//
//
void
CPolyLine
::
DeleteCorner
(
int
ic
,
BOOL
bDraw
)
void
CPolyLine
::
DeleteCorner
(
int
ic
,
BOOL
bDraw
)
{
{
Undraw
();
Undraw
();
int
icont
=
GetContour
(
ic
);
int
icont
=
GetContour
(
ic
);
int
istart
=
GetContourStart
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
BOOL
bClosed
=
icont
<
GetNumContours
()
-
1
||
GetClosed
();
BOOL
bClosed
=
icont
<
GetNumContours
()
-
1
||
GetClosed
();
if
(
!
bClosed
)
if
(
!
bClosed
)
{
{
// open contour, must be last contour
// open contour, must be last contour
corner
.
erase
(
corner
.
begin
()
+
ic
);
corner
.
erase
(
corner
.
begin
()
+
ic
);
if
(
ic
!=
istart
)
if
(
ic
!=
istart
)
side_style
.
erase
(
side_style
.
begin
()
+
ic
-
1
);
side_style
.
erase
(
side_style
.
begin
()
+
ic
-
1
);
}
}
else
else
{
{
// closed contour
// closed contour
corner
.
erase
(
corner
.
begin
()
+
ic
);
corner
.
erase
(
corner
.
begin
()
+
ic
);
side_style
.
erase
(
side_style
.
begin
()
+
ic
);
side_style
.
erase
(
side_style
.
begin
()
+
ic
);
if
(
ic
==
iend
)
if
(
ic
==
iend
)
corner
[
ic
-
1
].
end_contour
=
TRUE
;
corner
[
ic
-
1
].
end_contour
=
TRUE
;
}
}
if
(
bClosed
&&
GetContourSize
(
icont
)
<
3
)
if
(
bClosed
&&
GetContourSize
(
icont
)
<
3
)
{
{
// delete the entire contour
// delete the entire contour
RemoveContour
(
icont
);
RemoveContour
(
icont
);
}
}
if
(
bDraw
)
if
(
bDraw
)
Draw
();
Draw
();
}
}
void
CPolyLine
::
RemoveContour
(
int
icont
)
void
CPolyLine
::
RemoveContour
(
int
icont
)
{
{
Undraw
();
Undraw
();
int
istart
=
GetContourStart
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
if
(
icont
==
0
&&
GetNumContours
()
==
1
)
if
(
icont
==
0
&&
GetNumContours
()
==
1
)
{
{
// remove the only contour
// remove the only contour
ASSERT
(
0
);
ASSERT
(
0
);
}
}
else
if
(
icont
==
GetNumContours
()
-
1
)
else
if
(
icont
==
GetNumContours
()
-
1
)
{
{
// remove last contour
// remove last contour
corner
.
erase
(
corner
.
begin
()
+
icont
,
corner
.
end
()
);
corner
.
erase
(
corner
.
begin
()
+
icont
,
corner
.
end
()
);
side_style
.
erase
(
side_style
.
begin
()
+
icont
,
side_style
.
end
()
);
side_style
.
erase
(
side_style
.
begin
()
+
icont
,
side_style
.
end
()
);
}
}
else
else
{
{
// remove closed contour
// remove closed contour
for
(
int
ic
=
iend
;
ic
>=
istart
;
ic
--
)
for
(
int
ic
=
iend
;
ic
>=
istart
;
ic
--
)
{
{
corner
.
erase
(
corner
.
begin
()
+
ic
);
corner
.
erase
(
corner
.
begin
()
+
ic
);
side_style
.
erase
(
side_style
.
begin
()
+
ic
);
side_style
.
erase
(
side_style
.
begin
()
+
ic
);
}
}
}
}
Draw
();
Draw
();
}
}
/** Function InsertCorner
/** Function InsertCorner
* insert a new corner between two existing corners
* insert a new corner between two existing corners
* @param ic = index for the insertion point: the corner is inserted AFTER ic
* @param ic = index for the insertion point: the corner is inserted AFTER ic
* @param x, y = coordinates corner to insert
* @param x, y = coordinates corner to insert
*/
*/
void
CPolyLine
::
InsertCorner
(
int
ic
,
int
x
,
int
y
)
void
CPolyLine
::
InsertCorner
(
int
ic
,
int
x
,
int
y
)
{
{
Undraw
();
Undraw
();
if
(
(
unsigned
)(
ic
)
>=
corner
.
size
()
)
if
(
(
unsigned
)(
ic
)
>=
corner
.
size
()
)
{
{
corner
.
push_back
(
CPolyPt
(
x
,
y
)
);
corner
.
push_back
(
CPolyPt
(
x
,
y
)
);
side_style
.
push_back
(
STRAIGHT
);
side_style
.
push_back
(
STRAIGHT
);
}
}
else
else
{
{
corner
.
insert
(
corner
.
begin
()
+
ic
+
1
,
CPolyPt
(
x
,
y
)
);
corner
.
insert
(
corner
.
begin
()
+
ic
+
1
,
CPolyPt
(
x
,
y
)
);
side_style
.
insert
(
side_style
.
begin
()
+
ic
+
1
,
STRAIGHT
);
side_style
.
insert
(
side_style
.
begin
()
+
ic
+
1
,
STRAIGHT
);
}
}
if
(
(
unsigned
)(
ic
+
1
)
<
corner
.
size
()
)
if
(
(
unsigned
)(
ic
+
1
)
<
corner
.
size
()
)
{
{
if
(
corner
[
ic
].
end_contour
)
if
(
corner
[
ic
].
end_contour
)
{
{
corner
[
ic
+
1
].
end_contour
=
TRUE
;
corner
[
ic
+
1
].
end_contour
=
TRUE
;
corner
[
ic
].
end_contour
=
FALSE
;
corner
[
ic
].
end_contour
=
FALSE
;
}
}
}
}
Draw
();
Draw
();
}
}
// undraw polyline by removing all graphic elements from display list
// undraw polyline by removing all graphic elements from display list
//
//
void
CPolyLine
::
Undraw
()
void
CPolyLine
::
Undraw
()
{
{
if
(
m_dlist
&&
bDrawn
)
if
(
m_dlist
&&
bDrawn
)
{
{
// remove display elements, if present
// remove display elements, if present
for
(
unsigned
i
=
0
;
i
<
dl_side
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
dl_side
.
size
();
i
++
)
m_dlist
->
Remove
(
dl_side
[
i
]
);
m_dlist
->
Remove
(
dl_side
[
i
]
);
for
(
unsigned
i
=
0
;
i
<
dl_side_sel
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
dl_side_sel
.
size
();
i
++
)
m_dlist
->
Remove
(
dl_side_sel
[
i
]
);
m_dlist
->
Remove
(
dl_side_sel
[
i
]
);
for
(
unsigned
i
=
0
;
i
<
dl_corner_sel
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
dl_corner_sel
.
size
();
i
++
)
m_dlist
->
Remove
(
dl_corner_sel
[
i
]
);
m_dlist
->
Remove
(
dl_corner_sel
[
i
]
);
// remove pointers
// remove pointers
dl_side
.
clear
();
dl_side
.
clear
();
dl_side_sel
.
clear
();
dl_side_sel
.
clear
();
dl_corner_sel
.
clear
();
dl_corner_sel
.
clear
();
}
}
m_HatchLines
.
clear
();
m_HatchLines
.
clear
();
bDrawn
=
FALSE
;
bDrawn
=
FALSE
;
}
}
// draw polyline by adding all graphics to display list
// draw polyline by adding all graphics to display list
// if side style is ARC_CW or ARC_CCW but endpoints are not angled,
// if side style is ARC_CW or ARC_CCW but endpoints are not angled,
// convert to STRAIGHT
// convert to STRAIGHT
//
//
void
CPolyLine
::
Draw
(
CDisplayList
*
dl
)
void
CPolyLine
::
Draw
(
CDisplayList
*
dl
)
{
{
// first, undraw if necessary
// first, undraw if necessary
if
(
bDrawn
)
if
(
bDrawn
)
Undraw
();
Undraw
();
// use new display list if provided
// use new display list if provided
if
(
dl
)
if
(
dl
)
m_dlist
=
dl
;
m_dlist
=
dl
;
#if 0
#if 0
int i_start_contour = 0;
int i_start_contour = 0;
if( m_dlist )
if( m_dlist )
{
{
// set up std::vectors
// set up std::vectors
dl_side.SetSize( corner.size() );
dl_side.SetSize( corner.size() );
if( m_sel_box )
if( m_sel_box )
{
{
dl_side_sel.SetSize( corner.size() );
dl_side_sel.SetSize( corner.size() );
dl_corner_sel.SetSize( corner.size() );
dl_corner_sel.SetSize( corner.size() );
}
}
else
else
{
{
dl_side_sel.clear();
dl_side_sel.clear();
dl_corner_sel.clear();
dl_corner_sel.clear();
}
}
// now draw elements
// now draw elements
for( int ic=0; ic<corner.size(); ic++ )
for( int ic=0; ic<corner.size(); ic++ )
{
{
m_id.ii = ic;
m_id.ii = ic;
int xi = corner[ic].x;
int xi = corner[ic].x;
int yi = corner[ic].y;
int yi = corner[ic].y;
int xf, yf;
int xf, yf;
if( corner[ic].end_contour == FALSE && ic < corner.size()-1 )
if( corner[ic].end_contour == FALSE && ic < corner.size()-1 )
{
{
xf = corner[ic+1].x;
xf = corner[ic+1].x;
yf = corner[ic+1].y;
yf = corner[ic+1].y;
}
}
else
else
{
{
xf = corner[i_start_contour].x;
xf = corner[i_start_contour].x;
yf = corner[i_start_contour].y;
yf = corner[i_start_contour].y;
i_start_contour = ic+1;
i_start_contour = ic+1;
}
}
// draw
// draw
if( m_sel_box )
if( m_sel_box )
{
{
m_id.sst = ID_SEL_CORNER;
m_id.sst = ID_SEL_CORNER;
dl_corner_sel[ic] = m_dlist->AddSelector( m_id, m_ptr, m_layer, DL_HOLLOW_RECT,
dl_corner_sel[ic] = m_dlist->AddSelector( m_id, m_ptr, m_layer, DL_HOLLOW_RECT,
1, 0, 0, xi-m_sel_box, yi-m_sel_box,
1, 0, 0, xi-m_sel_box, yi-m_sel_box,
xi+m_sel_box, yi+m_sel_box, 0, 0 );
xi+m_sel_box, yi+m_sel_box, 0, 0 );
}
}
if( ic<(corner.size()-1) || corner[ic].end_contour )
if( ic<(corner.size()-1) || corner[ic].end_contour )
{
{
// draw side
// draw side
if( xi == xf || yi == yf )
if( xi == xf || yi == yf )
{
{
// if endpoints not angled, make side STRAIGHT
// if endpoints not angled, make side STRAIGHT
side_style[ic] = STRAIGHT;
side_style[ic] = STRAIGHT;
}
}
int g_type = DL_LINE;
int g_type = DL_LINE;
if( side_style[ic] == STRAIGHT )
if( side_style[ic] == STRAIGHT )
g_type = DL_LINE;
g_type = DL_LINE;
else if( side_style[ic] == ARC_CW )
else if( side_style[ic] == ARC_CW )
g_type = DL_ARC_CW;
g_type = DL_ARC_CW;
else if( side_style[ic] == ARC_CCW )
else if( side_style[ic] == ARC_CCW )
g_type = DL_ARC_CCW;
g_type = DL_ARC_CCW;
m_id.sst = ID_SIDE;
m_id.sst = ID_SIDE;
dl_side[ic] = m_dlist->Add( m_id, m_ptr, m_layer, g_type,
dl_side[ic] = m_dlist->Add( m_id, m_ptr, m_layer, g_type,
1, m_w, 0, xi, yi, xf, yf, 0, 0 );
1, m_w, 0, xi, yi, xf, yf, 0, 0 );
if( m_sel_box )
if( m_sel_box )
{
{
m_id.sst = ID_SEL_SIDE;
m_id.sst = ID_SEL_SIDE;
dl_side_sel[ic] = m_dlist->AddSelector( m_id, m_ptr, m_layer, g_type,
dl_side_sel[ic] = m_dlist->AddSelector( m_id, m_ptr, m_layer, g_type,
1, m_w, 0, xi, yi, xf, yf, 0, 0 );
1, m_w, 0, xi, yi, xf, yf, 0, 0 );
}
}
}
}
}
}
// if( m_HatchStyle )
// if( m_HatchStyle )
// Hatch();
// Hatch();
}
}
#endif
#endif
Hatch
();
Hatch
();
bDrawn
=
TRUE
;
bDrawn
=
TRUE
;
}
}
// start dragging new corner to be inserted into side, make side and hatching invisible
// start dragging new corner to be inserted into side, make side and hatching invisible
//
//
void
CPolyLine
::
StartDraggingToInsertCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
)
void
CPolyLine
::
StartDraggingToInsertCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
)
{
{
if
(
!
m_dlist
)
if
(
!
m_dlist
)
ASSERT
(
0
);
ASSERT
(
0
);
int
icont
=
GetContour
(
ic
);
int
icont
=
GetContour
(
ic
);
int
istart
=
GetContourStart
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
post_c
;
int
post_c
;
if
(
ic
==
iend
)
if
(
ic
==
iend
)
post_c
=
istart
;
post_c
=
istart
;
else
else
post_c
=
ic
+
1
;
post_c
=
ic
+
1
;
int
xi
=
corner
[
ic
].
x
;
int
xi
=
corner
[
ic
].
x
;
int
yi
=
corner
[
ic
].
y
;
int
yi
=
corner
[
ic
].
y
;
int
xf
=
corner
[
post_c
].
x
;
int
xf
=
corner
[
post_c
].
x
;
int
yf
=
corner
[
post_c
].
y
;
int
yf
=
corner
[
post_c
].
y
;
m_dlist
->
StartDraggingLineVertex
(
pDC
,
x
,
y
,
xi
,
yi
,
xf
,
yf
,
m_dlist
->
StartDraggingLineVertex
(
pDC
,
x
,
y
,
xi
,
yi
,
xf
,
yf
,
LAY_SELECTION
,
LAY_SELECTION
,
1
,
1
,
DSS_STRAIGHT
,
DSS_STRAIGHT
,
LAY_SELECTION
,
LAY_SELECTION
,
1
,
1
,
DSS_STRAIGHT
,
DSS_STRAIGHT
,
0
,
0
,
0
,
0
,
1
);
0
,
0
,
0
,
0
,
1
);
m_dlist
->
CancelHighLight
();
m_dlist
->
CancelHighLight
();
m_dlist
->
Set_visible
(
dl_side
[
ic
],
0
);
m_dlist
->
Set_visible
(
dl_side
[
ic
],
0
);
/* for( int ih=0; ih<m_nhatch; ih++ )
/* for( int ih=0; ih<m_nhatch; ih++ )
m_dlist->Set_visible( dl_hatch[ih], 0 );
m_dlist->Set_visible( dl_hatch[ih], 0 );
*/
*/
}
}
// cancel dragging inserted corner, make side and hatching visible again
// cancel dragging inserted corner, make side and hatching visible again
//
//
void
CPolyLine
::
CancelDraggingToInsertCorner
(
int
ic
)
void
CPolyLine
::
CancelDraggingToInsertCorner
(
int
ic
)
{
{
if
(
!
m_dlist
)
if
(
!
m_dlist
)
ASSERT
(
0
);
ASSERT
(
0
);
int
post_c
;
int
post_c
;
if
(
ic
==
(
int
)(
corner
.
size
()
-
1
)
)
if
(
ic
==
(
int
)(
corner
.
size
()
-
1
)
)
post_c
=
0
;
post_c
=
0
;
else
else
post_c
=
ic
+
1
;
post_c
=
ic
+
1
;
m_dlist
->
StopDragging
();
m_dlist
->
StopDragging
();
/* m_dlist->Set_visible( dl_side[ic], 1 );
/* m_dlist->Set_visible( dl_side[ic], 1 );
for( int ih=0; ih<m_nhatch; ih++ )
for( int ih=0; ih<m_nhatch; ih++ )
m_dlist->Set_visible( dl_hatch[ih], 1 );
m_dlist->Set_visible( dl_hatch[ih], 1 );
*/
*/
}
}
// start dragging corner to new position, make adjacent sides and hatching invisible
// start dragging corner to new position, make adjacent sides and hatching invisible
//
//
void
CPolyLine
::
StartDraggingToMoveCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
)
void
CPolyLine
::
StartDraggingToMoveCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
)
{
{
if
(
!
m_dlist
)
if
(
!
m_dlist
)
ASSERT
(
0
);
ASSERT
(
0
);
// see if corner is the first or last corner of an open contour
// see if corner is the first or last corner of an open contour
int
icont
=
GetContour
(
ic
);
int
icont
=
GetContour
(
ic
);
int
istart
=
GetContourStart
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
if
(
!
GetClosed
()
if
(
!
GetClosed
()
&&
icont
==
GetNumContours
()
-
1
&&
icont
==
GetNumContours
()
-
1
&&
(
ic
==
istart
||
ic
==
iend
)
)
&&
(
ic
==
istart
||
ic
==
iend
)
)
{
{
// yes
// yes
int
style
,
xi
,
yi
,
iside
;
int
style
,
xi
,
yi
,
iside
;
if
(
ic
==
istart
)
if
(
ic
==
istart
)
{
{
// first corner
// first corner
iside
=
ic
;
iside
=
ic
;
xi
=
GetX
(
ic
+
1
);
xi
=
GetX
(
ic
+
1
);
yi
=
GetY
(
ic
+
1
);
yi
=
GetY
(
ic
+
1
);
style
=
GetSideStyle
(
iside
);
style
=
GetSideStyle
(
iside
);
// reverse arc since we are drawing from corner 1 to 0
// reverse arc since we are drawing from corner 1 to 0
if
(
style
==
CPolyLine
::
ARC_CW
)
if
(
style
==
CPolyLine
::
ARC_CW
)
style
=
CPolyLine
::
ARC_CCW
;
style
=
CPolyLine
::
ARC_CCW
;
else
if
(
style
==
CPolyLine
::
ARC_CCW
)
else
if
(
style
==
CPolyLine
::
ARC_CCW
)
style
=
CPolyLine
::
ARC_CW
;
style
=
CPolyLine
::
ARC_CW
;
}
}
else
else
{
{
// last corner
// last corner
iside
=
ic
-
1
;
iside
=
ic
-
1
;
xi
=
GetX
(
ic
-
1
);
xi
=
GetX
(
ic
-
1
);
yi
=
GetY
(
ic
-
1
);
yi
=
GetY
(
ic
-
1
);
style
=
GetSideStyle
(
iside
);
style
=
GetSideStyle
(
iside
);
}
}
m_dlist
->
StartDraggingArc
(
pDC
,
style
,
GetX
(
ic
),
GetY
(
ic
),
xi
,
yi
,
LAY_SELECTION
,
1
,
1
);
m_dlist
->
StartDraggingArc
(
pDC
,
style
,
GetX
(
ic
),
GetY
(
ic
),
xi
,
yi
,
LAY_SELECTION
,
1
,
1
);
m_dlist
->
CancelHighLight
();
m_dlist
->
CancelHighLight
();
m_dlist
->
Set_visible
(
dl_side
[
iside
],
0
);
m_dlist
->
Set_visible
(
dl_side
[
iside
],
0
);
/* for( int ih=0; ih<m_nhatch; ih++ )
/* for( int ih=0; ih<m_nhatch; ih++ )
m_dlist->Set_visible( dl_hatch[ih], 0 );
m_dlist->Set_visible( dl_hatch[ih], 0 );
*/
*/
}
}
else
else
{
{
// no
// no
// get indexes for preceding and following corners
// get indexes for preceding and following corners
int
pre_c
,
post_c
;
int
pre_c
,
post_c
;
int
poly_side_style1
,
poly_side_style2
;
int
poly_side_style1
,
poly_side_style2
;
int
style1
,
style2
;
int
style1
,
style2
;
if
(
ic
==
istart
)
if
(
ic
==
istart
)
{
{
pre_c
=
iend
;
pre_c
=
iend
;
post_c
=
istart
+
1
;
post_c
=
istart
+
1
;
poly_side_style1
=
side_style
[
iend
];
poly_side_style1
=
side_style
[
iend
];
poly_side_style2
=
side_style
[
istart
];
poly_side_style2
=
side_style
[
istart
];
}
}
else
if
(
ic
==
iend
)
else
if
(
ic
==
iend
)
{
{
// last side
// last side
pre_c
=
ic
-
1
;
pre_c
=
ic
-
1
;
post_c
=
istart
;
post_c
=
istart
;
poly_side_style1
=
side_style
[
ic
-
1
];
poly_side_style1
=
side_style
[
ic
-
1
];
poly_side_style2
=
side_style
[
ic
];
poly_side_style2
=
side_style
[
ic
];
}
}
else
else
{
{
pre_c
=
ic
-
1
;
pre_c
=
ic
-
1
;
post_c
=
ic
+
1
;
post_c
=
ic
+
1
;
poly_side_style1
=
side_style
[
ic
-
1
];
poly_side_style1
=
side_style
[
ic
-
1
];
poly_side_style2
=
side_style
[
ic
];
poly_side_style2
=
side_style
[
ic
];
}
}
if
(
poly_side_style1
==
STRAIGHT
)
if
(
poly_side_style1
==
STRAIGHT
)
style1
=
DSS_STRAIGHT
;
style1
=
DSS_STRAIGHT
;
else
if
(
poly_side_style1
==
ARC_CW
)
else
if
(
poly_side_style1
==
ARC_CW
)
style1
=
DSS_ARC_CW
;
style1
=
DSS_ARC_CW
;
else
if
(
poly_side_style1
==
ARC_CCW
)
else
if
(
poly_side_style1
==
ARC_CCW
)
style1
=
DSS_ARC_CCW
;
style1
=
DSS_ARC_CCW
;
if
(
poly_side_style2
==
STRAIGHT
)
if
(
poly_side_style2
==
STRAIGHT
)
style2
=
DSS_STRAIGHT
;
style2
=
DSS_STRAIGHT
;
else
if
(
poly_side_style2
==
ARC_CW
)
else
if
(
poly_side_style2
==
ARC_CW
)
style2
=
DSS_ARC_CW
;
style2
=
DSS_ARC_CW
;
else
if
(
poly_side_style2
==
ARC_CCW
)
else
if
(
poly_side_style2
==
ARC_CCW
)
style2
=
DSS_ARC_CCW
;
style2
=
DSS_ARC_CCW
;
int
xi
=
corner
[
pre_c
].
x
;
int
xi
=
corner
[
pre_c
].
x
;
int
yi
=
corner
[
pre_c
].
y
;
int
yi
=
corner
[
pre_c
].
y
;
int
xf
=
corner
[
post_c
].
x
;
int
xf
=
corner
[
post_c
].
x
;
int
yf
=
corner
[
post_c
].
y
;
int
yf
=
corner
[
post_c
].
y
;
m_dlist
->
StartDraggingLineVertex
(
pDC
,
x
,
y
,
xi
,
yi
,
xf
,
yf
,
m_dlist
->
StartDraggingLineVertex
(
pDC
,
x
,
y
,
xi
,
yi
,
xf
,
yf
,
LAY_SELECTION
,
LAY_SELECTION
,
1
,
1
,
style1
,
style2
,
LAY_SELECTION
,
LAY_SELECTION
,
1
,
1
,
style1
,
style2
,
0
,
0
,
0
,
0
,
1
);
0
,
0
,
0
,
0
,
1
);
m_dlist
->
CancelHighLight
();
m_dlist
->
CancelHighLight
();
m_dlist
->
Set_visible
(
dl_side
[
pre_c
],
0
);
m_dlist
->
Set_visible
(
dl_side
[
pre_c
],
0
);
m_dlist
->
Set_visible
(
dl_side
[
ic
],
0
);
m_dlist
->
Set_visible
(
dl_side
[
ic
],
0
);
/* for( int ih=0; ih<m_nhatch; ih++ )
/* for( int ih=0; ih<m_nhatch; ih++ )
m_dlist->Set_visible( dl_hatch[ih], 0 );
m_dlist->Set_visible( dl_hatch[ih], 0 );
*/
}
*/
}
}
}
// cancel dragging corner to new position, make sides and hatching visible again
// cancel dragging corner to new position, make sides and hatching visible again
//
//
// highlight side by drawing line over it
// highlight side by drawing line over it
//
//
void
CPolyLine
::
HighlightSide
(
int
is
)
void
CPolyLine
::
HighlightSide
(
int
is
)
{
{
if
(
!
m_dlist
)
if
(
!
m_dlist
)
ASSERT
(
0
);
ASSERT
(
0
);
if
(
GetClosed
()
&&
is
>=
(
int
)
corner
.
size
()
)
if
(
GetClosed
()
&&
is
>=
(
int
)
corner
.
size
()
)
return
;
return
;
if
(
!
GetClosed
()
&&
is
>=
(
int
)(
corner
.
size
()
-
1
)
)
if
(
!
GetClosed
()
&&
is
>=
(
int
)(
corner
.
size
()
-
1
)
)
return
;
return
;
int
style
;
int
style
;
if
(
side_style
[
is
]
==
CPolyLine
::
STRAIGHT
)
if
(
side_style
[
is
]
==
CPolyLine
::
STRAIGHT
)
style
=
DL_LINE
;
style
=
DL_LINE
;
else
if
(
side_style
[
is
]
==
CPolyLine
::
ARC_CW
)
else
if
(
side_style
[
is
]
==
CPolyLine
::
ARC_CW
)
style
=
DL_ARC_CW
;
style
=
DL_ARC_CW
;
else
if
(
side_style
[
is
]
==
CPolyLine
::
ARC_CCW
)
else
if
(
side_style
[
is
]
==
CPolyLine
::
ARC_CCW
)
style
=
DL_ARC_CCW
;
style
=
DL_ARC_CCW
;
m_dlist
->
HighLight
(
style
,
m_dlist
->
HighLight
(
style
,
m_dlist
->
Get_x
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_x
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_y
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_y
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_xf
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_xf
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_yf
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_yf
(
dl_side_sel
[
is
]
),
m_dlist
->
Get_w
(
dl_side_sel
[
is
])
);
m_dlist
->
Get_w
(
dl_side_sel
[
is
])
);
}
}
int
CPolyLine
::
GetX
(
int
ic
)
int
CPolyLine
::
GetX
(
int
ic
)
{
{
return
corner
[
ic
].
x
;
return
corner
[
ic
].
x
;
}
}
int
CPolyLine
::
GetY
(
int
ic
)
int
CPolyLine
::
GetY
(
int
ic
)
{
{
return
corner
[
ic
].
y
;
return
corner
[
ic
].
y
;
}
}
int
CPolyLine
::
GetEndContour
(
int
ic
)
int
CPolyLine
::
GetEndContour
(
int
ic
)
{
{
return
corner
[
ic
].
end_contour
;
return
corner
[
ic
].
end_contour
;
}
}
CRect
CPolyLine
::
GetBounds
()
CRect
CPolyLine
::
GetBounds
()
{
{
CRect
r
=
GetCornerBounds
();
CRect
r
=
GetCornerBounds
();
r
.
left
-=
m_Width
/
2
;
r
.
left
-=
m_Width
/
2
;
r
.
right
+=
m_Width
/
2
;
r
.
right
+=
m_Width
/
2
;
r
.
bottom
-=
m_Width
/
2
;
r
.
bottom
-=
m_Width
/
2
;
r
.
top
+=
m_Width
/
2
;
r
.
top
+=
m_Width
/
2
;
return
r
;
return
r
;
}
}
CRect
CPolyLine
::
GetCornerBounds
()
CRect
CPolyLine
::
GetCornerBounds
()
{
{
CRect
r
;
CRect
r
;
r
.
left
=
r
.
bottom
=
INT_MAX
;
r
.
left
=
r
.
bottom
=
INT_MAX
;
r
.
right
=
r
.
top
=
INT_MIN
;
r
.
right
=
r
.
top
=
INT_MIN
;
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
{
{
r
.
left
=
min
(
r
.
left
,
corner
[
i
].
x
);
r
.
left
=
min
(
r
.
left
,
corner
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
corner
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
corner
[
i
].
x
);
r
.
bottom
=
min
(
r
.
bottom
,
corner
[
i
].
y
);
r
.
bottom
=
min
(
r
.
bottom
,
corner
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
corner
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
corner
[
i
].
y
);
}
}
return
r
;
return
r
;
}
}
CRect
CPolyLine
::
GetCornerBounds
(
int
icont
)
CRect
CPolyLine
::
GetCornerBounds
(
int
icont
)
{
{
CRect
r
;
CRect
r
;
r
.
left
=
r
.
bottom
=
INT_MAX
;
r
.
left
=
r
.
bottom
=
INT_MAX
;
r
.
right
=
r
.
top
=
INT_MIN
;
r
.
right
=
r
.
top
=
INT_MIN
;
int
istart
=
GetContourStart
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
for
(
int
i
=
istart
;
i
<=
iend
;
i
++
)
for
(
int
i
=
istart
;
i
<=
iend
;
i
++
)
{
{
r
.
left
=
min
(
r
.
left
,
corner
[
i
].
x
);
r
.
left
=
min
(
r
.
left
,
corner
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
corner
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
corner
[
i
].
x
);
r
.
bottom
=
min
(
r
.
bottom
,
corner
[
i
].
y
);
r
.
bottom
=
min
(
r
.
bottom
,
corner
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
corner
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
corner
[
i
].
y
);
}
}
return
r
;
return
r
;
}
}
int
CPolyLine
::
GetNumCorners
()
int
CPolyLine
::
GetNumCorners
()
{
{
return
corner
.
size
();
return
corner
.
size
();
}
}
int
CPolyLine
::
GetNumSides
()
int
CPolyLine
::
GetNumSides
()
{
{
if
(
GetClosed
()
)
if
(
GetClosed
()
)
return
corner
.
size
();
return
corner
.
size
();
else
else
return
corner
.
size
()
-
1
;
return
corner
.
size
()
-
1
;
}
}
int
CPolyLine
::
GetW
()
int
CPolyLine
::
GetW
()
{
{
return
m_Width
;
return
m_Width
;
}
}
int
CPolyLine
::
GetSelBoxSize
()
int
CPolyLine
::
GetSelBoxSize
()
{
{
return
m_sel_box
;
return
m_sel_box
;
}
}
int
CPolyLine
::
GetNumContours
()
int
CPolyLine
::
GetNumContours
()
{
{
int
ncont
=
0
;
int
ncont
=
0
;
if
(
!
corner
.
size
()
)
if
(
!
corner
.
size
()
)
return
0
;
return
0
;
for
(
unsigned
ic
=
0
;
ic
<
corner
.
size
();
ic
++
)
for
(
unsigned
ic
=
0
;
ic
<
corner
.
size
();
ic
++
)
if
(
corner
[
ic
].
end_contour
)
if
(
corner
[
ic
].
end_contour
)
ncont
++
;
ncont
++
;
if
(
!
corner
[
corner
.
size
()
-
1
].
end_contour
)
if
(
!
corner
[
corner
.
size
()
-
1
].
end_contour
)
ncont
++
;
ncont
++
;
return
ncont
;
return
ncont
;
}
}
int
CPolyLine
::
GetContour
(
int
ic
)
int
CPolyLine
::
GetContour
(
int
ic
)
{
{
int
ncont
=
0
;
int
ncont
=
0
;
for
(
int
i
=
0
;
i
<
ic
;
i
++
)
for
(
int
i
=
0
;
i
<
ic
;
i
++
)
{
{
if
(
corner
[
i
].
end_contour
)
if
(
corner
[
i
].
end_contour
)
ncont
++
;
ncont
++
;
}
}
return
ncont
;
return
ncont
;
}
}
int
CPolyLine
::
GetContourStart
(
int
icont
)
int
CPolyLine
::
GetContourStart
(
int
icont
)
{
{
if
(
icont
==
0
)
if
(
icont
==
0
)
return
0
;
return
0
;
int
ncont
=
0
;
int
ncont
=
0
;
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
{
{
if
(
corner
[
i
].
end_contour
)
if
(
corner
[
i
].
end_contour
)
{
{
ncont
++
;
ncont
++
;
if
(
ncont
==
icont
)
if
(
ncont
==
icont
)
return
i
+
1
;
return
i
+
1
;
}
}
}
}
ASSERT
(
0
);
ASSERT
(
0
);
return
0
;
return
0
;
}
}
int
CPolyLine
::
GetContourEnd
(
int
icont
)
int
CPolyLine
::
GetContourEnd
(
int
icont
)
{
{
if
(
icont
<
0
)
if
(
icont
<
0
)
return
0
;
return
0
;
if
(
icont
==
GetNumContours
()
-
1
)
if
(
icont
==
GetNumContours
()
-
1
)
return
corner
.
size
()
-
1
;
return
corner
.
size
()
-
1
;
int
ncont
=
0
;
int
ncont
=
0
;
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
{
{
if
(
corner
[
i
].
end_contour
)
if
(
corner
[
i
].
end_contour
)
{
{
if
(
ncont
==
icont
)
if
(
ncont
==
icont
)
return
i
;
return
i
;
ncont
++
;
ncont
++
;
}
}
}
}
ASSERT
(
0
);
ASSERT
(
0
);
return
0
;
return
0
;
}
}
int
CPolyLine
::
GetContourSize
(
int
icont
)
int
CPolyLine
::
GetContourSize
(
int
icont
)
{
{
return
GetContourEnd
(
icont
)
-
GetContourStart
(
icont
)
+
1
;
return
GetContourEnd
(
icont
)
-
GetContourStart
(
icont
)
+
1
;
}
}
void
CPolyLine
::
SetSideStyle
(
int
is
,
int
style
)
void
CPolyLine
::
SetSideStyle
(
int
is
,
int
style
)
{
{
Undraw
();
Undraw
();
CPoint
p1
,
p2
;
CPoint
p1
,
p2
;
if
(
is
==
(
int
)(
corner
.
size
()
-
1
)
)
if
(
is
==
(
int
)(
corner
.
size
()
-
1
)
)
{
{
p1
.
x
=
corner
[
corner
.
size
()
-
1
].
x
;
p1
.
x
=
corner
[
corner
.
size
()
-
1
].
x
;
p1
.
y
=
corner
[
corner
.
size
()
-
1
].
y
;
p1
.
y
=
corner
[
corner
.
size
()
-
1
].
y
;
p2
.
x
=
corner
[
0
].
x
;
p2
.
x
=
corner
[
0
].
x
;
p2
.
y
=
corner
[
0
].
y
;
p2
.
y
=
corner
[
0
].
y
;
}
}
else
else
{
{
p1
.
x
=
corner
[
is
].
x
;
p1
.
x
=
corner
[
is
].
x
;
p1
.
y
=
corner
[
is
].
y
;
p1
.
y
=
corner
[
is
].
y
;
p2
.
x
=
corner
[
is
+
1
].
x
;
p2
.
x
=
corner
[
is
+
1
].
x
;
p2
.
y
=
corner
[
is
+
1
].
y
;
p2
.
y
=
corner
[
is
+
1
].
y
;
}
}
if
(
p1
.
x
==
p2
.
x
||
p1
.
y
==
p2
.
y
)
if
(
p1
.
x
==
p2
.
x
||
p1
.
y
==
p2
.
y
)
side_style
[
is
]
=
STRAIGHT
;
side_style
[
is
]
=
STRAIGHT
;
else
else
side_style
[
is
]
=
style
;
side_style
[
is
]
=
style
;
Draw
();
Draw
();
}
}
int
CPolyLine
::
GetSideStyle
(
int
is
)
int
CPolyLine
::
GetSideStyle
(
int
is
)
{
{
return
side_style
[
is
];
return
side_style
[
is
];
}
}
int
CPolyLine
::
GetClosed
()
int
CPolyLine
::
GetClosed
()
{
{
if
(
corner
.
size
()
==
0
)
if
(
corner
.
size
()
==
0
)
return
0
;
return
0
;
else
else
return
corner
[
corner
.
size
()
-
1
].
end_contour
;
return
corner
[
corner
.
size
()
-
1
].
end_contour
;
}
}
// draw hatch lines
// draw hatch lines
//
//
void
CPolyLine
::
Hatch
()
void
CPolyLine
::
Hatch
()
{
{
m_HatchLines
.
clear
();
m_HatchLines
.
clear
();
if
(
m_HatchStyle
==
NO_HATCH
)
if
(
m_HatchStyle
==
NO_HATCH
)
{
{
return
;
return
;
}
}
int
layer
=
m_layer
;
int
layer
=
m_layer
;
// if( /*m_dlist && */GetClosed() )
// if( /*m_dlist && */GetClosed() )
{
{
enum
{
enum
{
MAXPTS
=
100
,
MAXPTS
=
100
,
MAXLINES
=
1000
MAXLINES
=
1000
};
};
int
xx
[
MAXPTS
],
yy
[
MAXPTS
];
int
xx
[
MAXPTS
],
yy
[
MAXPTS
];
// define range for hatch lines
// define range for hatch lines
int
min_x
=
corner
[
0
].
x
;
int
min_x
=
corner
[
0
].
x
;
int
max_x
=
corner
[
0
].
x
;
int
max_x
=
corner
[
0
].
x
;
int
min_y
=
corner
[
0
].
y
;
int
min_y
=
corner
[
0
].
y
;
int
max_y
=
corner
[
0
].
y
;
int
max_y
=
corner
[
0
].
y
;
for
(
unsigned
ic
=
1
;
ic
<
corner
.
size
();
ic
++
)
for
(
unsigned
ic
=
1
;
ic
<
corner
.
size
();
ic
++
)
{
{
if
(
corner
[
ic
].
x
<
min_x
)
if
(
corner
[
ic
].
x
<
min_x
)
min_x
=
corner
[
ic
].
x
;
min_x
=
corner
[
ic
].
x
;
if
(
corner
[
ic
].
x
>
max_x
)
if
(
corner
[
ic
].
x
>
max_x
)
max_x
=
corner
[
ic
].
x
;
max_x
=
corner
[
ic
].
x
;
if
(
corner
[
ic
].
y
<
min_y
)
if
(
corner
[
ic
].
y
<
min_y
)
min_y
=
corner
[
ic
].
y
;
min_y
=
corner
[
ic
].
y
;
if
(
corner
[
ic
].
y
>
max_y
)
if
(
corner
[
ic
].
y
>
max_y
)
max_y
=
corner
[
ic
].
y
;
max_y
=
corner
[
ic
].
y
;
}
}
int
slope_flag
=
(
layer
&
1
)
?
1
:
-
1
;
// 1 or -1
int
slope_flag
=
(
layer
&
1
)
?
1
:
-
1
;
// 1 or -1
double
slope
=
0.707106
*
slope_flag
;
double
slope
=
0.707106
*
slope_flag
;
int
spacing
;
int
spacing
;
if
(
m_HatchStyle
==
DIAGONAL_EDGE
)
if
(
m_HatchStyle
==
DIAGONAL_EDGE
)
spacing
=
10
*
PCBU_PER_MIL
;
spacing
=
10
*
PCBU_PER_MIL
;
else
else
spacing
=
50
*
PCBU_PER_MIL
;
spacing
=
50
*
PCBU_PER_MIL
;
int
max_a
,
min_a
;
int
max_a
,
min_a
;
if
(
slope_flag
==
1
)
if
(
slope_flag
==
1
)
{
{
max_a
=
(
int
)(
max_y
-
slope
*
min_x
);
max_a
=
(
int
)(
max_y
-
slope
*
min_x
);
min_a
=
(
int
)(
min_y
-
slope
*
max_x
);
min_a
=
(
int
)(
min_y
-
slope
*
max_x
);
}
}
else
else
{
{
max_a
=
(
int
)(
max_y
-
slope
*
max_x
);
max_a
=
(
int
)(
max_y
-
slope
*
max_x
);
min_a
=
(
int
)(
min_y
-
slope
*
min_x
);
min_a
=
(
int
)(
min_y
-
slope
*
min_x
);
}
}
min_a
=
(
min_a
/
spacing
)
*
spacing
;
min_a
=
(
min_a
/
spacing
)
*
spacing
;
int
offset
;
int
offset
;
if
(
layer
<
(
LAY_TOP_COPPER
+
2
)
)
if
(
layer
<
(
LAY_TOP_COPPER
+
2
)
)
offset
=
0
;
offset
=
0
;
else
if
(
layer
<
(
LAY_TOP_COPPER
+
4
)
)
else
if
(
layer
<
(
LAY_TOP_COPPER
+
4
)
)
offset
=
spacing
/
2
;
offset
=
spacing
/
2
;
else
if
(
layer
<
(
LAY_TOP_COPPER
+
6
)
)
else
if
(
layer
<
(
LAY_TOP_COPPER
+
6
)
)
offset
=
spacing
/
4
;
offset
=
spacing
/
4
;
else
if
(
layer
<
(
LAY_TOP_COPPER
+
8
)
)
else
if
(
layer
<
(
LAY_TOP_COPPER
+
8
)
)
offset
=
3
*
spacing
/
4
;
offset
=
3
*
spacing
/
4
;
else
if
(
layer
<
(
LAY_TOP_COPPER
+
10
)
)
else
if
(
layer
<
(
LAY_TOP_COPPER
+
10
)
)
offset
=
1
*
spacing
/
8
;
offset
=
1
*
spacing
/
8
;
else
if
(
layer
<
(
LAY_TOP_COPPER
+
12
)
)
else
if
(
layer
<
(
LAY_TOP_COPPER
+
12
)
)
offset
=
3
*
spacing
/
8
;
offset
=
3
*
spacing
/
8
;
else
if
(
layer
<
(
LAY_TOP_COPPER
+
14
)
)
else
if
(
layer
<
(
LAY_TOP_COPPER
+
14
)
)
offset
=
5
*
spacing
/
8
;
offset
=
5
*
spacing
/
8
;
else
if
(
layer
<
(
LAY_TOP_COPPER
+
16
)
)
else
if
(
layer
<
(
LAY_TOP_COPPER
+
16
)
)
offset
=
7
*
spacing
/
8
;
offset
=
7
*
spacing
/
8
;
else
else
ASSERT
(
0
);
ASSERT
(
0
);
min_a
+=
offset
;
min_a
+=
offset
;
// now calculate and draw hatch lines
// now calculate and draw hatch lines
int
nc
=
corner
.
size
();
int
nc
=
corner
.
size
();
// loop through hatch lines
// loop through hatch lines
for
(
int
a
=
min_a
;
a
<
max_a
;
a
+=
spacing
)
for
(
int
a
=
min_a
;
a
<
max_a
;
a
+=
spacing
)
{
{
// get intersection points for this hatch line
// get intersection points for this hatch line
int
nloops
=
0
;
int
nloops
=
0
;
int
npts
;
int
npts
;
// make this a loop in case my homebrew hatching algorithm screws up
// make this a loop in case my homebrew hatching algorithm screws up
do
do
{
{
npts
=
0
;
npts
=
0
;
int
i_start_contour
=
0
;
int
i_start_contour
=
0
;
for
(
int
ic
=
0
;
ic
<
nc
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
nc
;
ic
++
)
{
{
double
x
,
y
,
x2
,
y2
;
double
x
,
y
,
x2
,
y2
;
int
ok
;
int
ok
;
if
(
corner
[
ic
].
end_contour
)
if
(
corner
[
ic
].
end_contour
)
{
{
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
i_start_contour
].
x
,
corner
[
i_start_contour
].
y
,
corner
[
i_start_contour
].
x
,
corner
[
i_start_contour
].
y
,
side_style
[
ic
],
side_style
[
ic
],
&
x
,
&
y
,
&
x2
,
&
y2
);
&
x
,
&
y
,
&
x2
,
&
y2
);
i_start_contour
=
ic
+
1
;
i_start_contour
=
ic
+
1
;
}
}
else
else
{
{
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
ic
+
1
].
x
,
corner
[
ic
+
1
].
y
,
corner
[
ic
+
1
].
x
,
corner
[
ic
+
1
].
y
,
side_style
[
ic
],
side_style
[
ic
],
&
x
,
&
y
,
&
x2
,
&
y2
);
&
x
,
&
y
,
&
x2
,
&
y2
);
}
}
if
(
ok
)
if
(
ok
)
{
{
xx
[
npts
]
=
(
int
)
x
;
xx
[
npts
]
=
(
int
)
x
;
yy
[
npts
]
=
(
int
)
y
;
yy
[
npts
]
=
(
int
)
y
;
npts
++
;
npts
++
;
ASSERT
(
npts
<
MAXPTS
);
// overflow
ASSERT
(
npts
<
MAXPTS
);
// overflow
}
}
if
(
ok
==
2
)
if
(
ok
==
2
)
{
{
xx
[
npts
]
=
(
int
)
x2
;
xx
[
npts
]
=
(
int
)
x2
;
yy
[
npts
]
=
(
int
)
y2
;
yy
[
npts
]
=
(
int
)
y2
;
npts
++
;
npts
++
;
ASSERT
(
npts
<
MAXPTS
);
// overflow
ASSERT
(
npts
<
MAXPTS
);
// overflow
}
}
}
}
nloops
++
;
nloops
++
;
a
+=
PCBU_PER_MIL
/
100
;
a
+=
PCBU_PER_MIL
/
100
;
}
while
(
npts
%
2
!=
0
&&
nloops
<
3
);
}
while
(
npts
%
2
!=
0
&&
nloops
<
3
);
ASSERT
(
npts
%
2
==
0
);
// odd number of intersection points, error
ASSERT
(
npts
%
2
==
0
);
// odd number of intersection points, error
// sort points in order of descending x (if more than 2)
// sort points in order of descending x (if more than 2)
if
(
npts
>
2
)
if
(
npts
>
2
)
{
{
for
(
int
istart
=
0
;
istart
<
(
npts
-
1
);
istart
++
)
for
(
int
istart
=
0
;
istart
<
(
npts
-
1
);
istart
++
)
{
{
int
max_x
=
INT_MIN
;
int
max_x
=
INT_MIN
;
int
imax
;
int
imax
;
for
(
int
i
=
istart
;
i
<
npts
;
i
++
)
for
(
int
i
=
istart
;
i
<
npts
;
i
++
)
{
{
if
(
xx
[
i
]
>
max_x
)
if
(
xx
[
i
]
>
max_x
)
{
{
max_x
=
xx
[
i
];
max_x
=
xx
[
i
];
imax
=
i
;
imax
=
i
;
}
}
}
}
int
temp
=
xx
[
istart
];
int
temp
=
xx
[
istart
];
xx
[
istart
]
=
xx
[
imax
];
xx
[
istart
]
=
xx
[
imax
];
xx
[
imax
]
=
temp
;
xx
[
imax
]
=
temp
;
temp
=
yy
[
istart
];
temp
=
yy
[
istart
];
yy
[
istart
]
=
yy
[
imax
];
yy
[
istart
]
=
yy
[
imax
];
yy
[
imax
]
=
temp
;
yy
[
imax
]
=
temp
;
}
}
}
}
// draw lines
// draw lines
for
(
int
ip
=
0
;
ip
<
npts
;
ip
+=
2
)
for
(
int
ip
=
0
;
ip
<
npts
;
ip
+=
2
)
{
{
double
dx
=
xx
[
ip
+
1
]
-
xx
[
ip
];
double
dx
=
xx
[
ip
+
1
]
-
xx
[
ip
];
if
(
m_HatchStyle
==
DIAGONAL_FULL
||
fabs
(
dx
)
<
40
*
NM_PER_MIL
)
if
(
m_HatchStyle
==
DIAGONAL_FULL
||
fabs
(
dx
)
<
40
*
NM_PER_MIL
)
{
{
m_HatchLines
.
push_back
(
CSegment
(
xx
[
ip
],
yy
[
ip
],
xx
[
ip
+
1
],
yy
[
ip
+
1
])
);
m_HatchLines
.
push_back
(
CSegment
(
xx
[
ip
],
yy
[
ip
],
xx
[
ip
+
1
],
yy
[
ip
+
1
])
);
}
}
else
else
{
{
double
dy
=
yy
[
ip
+
1
]
-
yy
[
ip
];
double
dy
=
yy
[
ip
+
1
]
-
yy
[
ip
];
double
slope
=
dy
/
dx
;
double
slope
=
dy
/
dx
;
if
(
dx
>
0
)
if
(
dx
>
0
)
dx
=
20
*
NM_PER_MIL
;
dx
=
20
*
NM_PER_MIL
;
else
else
dx
=
-
20
*
NM_PER_MIL
;
dx
=
-
20
*
NM_PER_MIL
;
double
x1
=
xx
[
ip
]
+
dx
;
double
x1
=
xx
[
ip
]
+
dx
;
double
x2
=
xx
[
ip
+
1
]
-
dx
;
double
x2
=
xx
[
ip
+
1
]
-
dx
;
double
y1
=
yy
[
ip
]
+
dx
*
slope
;
double
y1
=
yy
[
ip
]
+
dx
*
slope
;
double
y2
=
yy
[
ip
+
1
]
-
dx
*
slope
;
double
y2
=
yy
[
ip
+
1
]
-
dx
*
slope
;
m_HatchLines
.
push_back
(
CSegment
(
xx
[
ip
],
yy
[
ip
],
to_int
(
x1
),
to_int
(
y1
))
);
m_HatchLines
.
push_back
(
CSegment
(
xx
[
ip
],
yy
[
ip
],
to_int
(
x1
),
to_int
(
y1
))
);
m_HatchLines
.
push_back
(
CSegment
(
xx
[
ip
+
1
],
yy
[
ip
+
1
],
to_int
(
x2
),
to_int
(
y2
))
);
m_HatchLines
.
push_back
(
CSegment
(
xx
[
ip
+
1
],
yy
[
ip
+
1
],
to_int
(
x2
),
to_int
(
y2
))
);
}
}
}
}
}
// end for
}
// end for
}
}
}
}
// test to see if a point is inside polyline
// test to see if a point is inside polyline
//
//
BOOL
CPolyLine
::
TestPointInside
(
int
x
,
int
y
)
BOOL
CPolyLine
::
TestPointInside
(
int
x
,
int
y
)
{
{
enum
{
MAXPTS
=
100
};
enum
{
MAXPTS
=
100
};
if
(
!
GetClosed
()
)
if
(
!
GetClosed
()
)
ASSERT
(
0
);
ASSERT
(
0
);
// define line passing through (x,y), with slope = 2/3;
// define line passing through (x,y), with slope = 2/3;
// get intersection points
// get intersection points
double
xx
[
MAXPTS
],
yy
[
MAXPTS
];
double
xx
[
MAXPTS
],
yy
[
MAXPTS
];
double
slope
=
(
double
)
2.0
/
3.0
;
double
slope
=
(
double
)
2.0
/
3.0
;
double
a
=
y
-
slope
*
x
;
double
a
=
y
-
slope
*
x
;
int
nloops
=
0
;
int
nloops
=
0
;
int
npts
;
int
npts
;
// make this a loop so if my homebrew algorithm screws up, we try it again
// make this a loop so if my homebrew algorithm screws up, we try it again
do
do
{
{
// now find all intersection points of line with polyline sides
// now find all intersection points of line with polyline sides
npts
=
0
;
npts
=
0
;
for
(
int
icont
=
0
;
icont
<
GetNumContours
();
icont
++
)
for
(
int
icont
=
0
;
icont
<
GetNumContours
();
icont
++
)
{
{
int
istart
=
GetContourStart
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
for
(
int
ic
=
istart
;
ic
<=
iend
;
ic
++
)
for
(
int
ic
=
istart
;
ic
<=
iend
;
ic
++
)
{
{
double
x
,
y
,
x2
,
y2
;
double
x
,
y
,
x2
,
y2
;
int
ok
;
int
ok
;
if
(
ic
==
istart
)
if
(
ic
==
istart
)
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
iend
].
x
,
corner
[
iend
].
y
,
corner
[
iend
].
x
,
corner
[
iend
].
y
,
corner
[
istart
].
x
,
corner
[
istart
].
y
,
corner
[
istart
].
x
,
corner
[
istart
].
y
,
side_style
[
corner
.
size
()
-
1
],
side_style
[
corner
.
size
()
-
1
],
&
x
,
&
y
,
&
x2
,
&
y2
);
&
x
,
&
y
,
&
x2
,
&
y2
);
else
else
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
ic
-
1
].
x
,
corner
[
ic
-
1
].
y
,
corner
[
ic
-
1
].
x
,
corner
[
ic
-
1
].
y
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
side_style
[
ic
-
1
],
side_style
[
ic
-
1
],
&
x
,
&
y
,
&
x2
,
&
y2
);
&
x
,
&
y
,
&
x2
,
&
y2
);
if
(
ok
)
if
(
ok
)
{
{
xx
[
npts
]
=
(
int
)
x
;
xx
[
npts
]
=
(
int
)
x
;
yy
[
npts
]
=
(
int
)
y
;
yy
[
npts
]
=
(
int
)
y
;
npts
++
;
npts
++
;
ASSERT
(
npts
<
MAXPTS
);
// overflow
ASSERT
(
npts
<
MAXPTS
);
// overflow
}
}
if
(
ok
==
2
)
if
(
ok
==
2
)
{
{
xx
[
npts
]
=
(
int
)
x2
;
xx
[
npts
]
=
(
int
)
x2
;
yy
[
npts
]
=
(
int
)
y2
;
yy
[
npts
]
=
(
int
)
y2
;
npts
++
;
npts
++
;
ASSERT
(
npts
<
MAXPTS
);
// overflow
ASSERT
(
npts
<
MAXPTS
);
// overflow
}
}
}
}
}
}
nloops
++
;
nloops
++
;
a
+=
PCBU_PER_MIL
/
100
;
a
+=
PCBU_PER_MIL
/
100
;
}
while
(
npts
%
2
!=
0
&&
nloops
<
3
);
}
while
(
npts
%
2
!=
0
&&
nloops
<
3
);
ASSERT
(
npts
%
2
==
0
);
// odd number of intersection points, error
ASSERT
(
npts
%
2
==
0
);
// odd number of intersection points, error
// count intersection points to right of (x,y), if odd (x,y) is inside polyline
// count intersection points to right of (x,y), if odd (x,y) is inside polyline
int
ncount
=
0
;
int
ncount
=
0
;
for
(
int
ip
=
0
;
ip
<
npts
;
ip
++
)
for
(
int
ip
=
0
;
ip
<
npts
;
ip
++
)
{
{
if
(
xx
[
ip
]
==
x
&&
yy
[
ip
]
==
y
)
if
(
xx
[
ip
]
==
x
&&
yy
[
ip
]
==
y
)
return
FALSE
;
// (x,y) is on a side, call it outside
return
FALSE
;
// (x,y) is on a side, call it outside
else
if
(
xx
[
ip
]
>
x
)
else
if
(
xx
[
ip
]
>
x
)
ncount
++
;
ncount
++
;
}
}
if
(
ncount
%
2
)
if
(
ncount
%
2
)
return
TRUE
;
return
TRUE
;
else
else
return
FALSE
;
return
FALSE
;
}
}
// test to see if a point is inside polyline contour
// test to see if a point is inside polyline contour
//
//
BOOL
CPolyLine
::
TestPointInsideContour
(
int
icont
,
int
x
,
int
y
)
BOOL
CPolyLine
::
TestPointInsideContour
(
int
icont
,
int
x
,
int
y
)
{
{
if
(
icont
>=
GetNumContours
()
)
if
(
icont
>=
GetNumContours
()
)
return
FALSE
;
return
FALSE
;
enum
{
MAXPTS
=
100
};
enum
{
MAXPTS
=
100
};
if
(
!
GetClosed
()
)
if
(
!
GetClosed
()
)
ASSERT
(
0
);
ASSERT
(
0
);
// define line passing through (x,y), with slope = 2/3;
// define line passing through (x,y), with slope = 2/3;
// get intersection points
// get intersection points
double
xx
[
MAXPTS
],
yy
[
MAXPTS
];
double
xx
[
MAXPTS
],
yy
[
MAXPTS
];
double
slope
=
(
double
)
2.0
/
3.0
;
double
slope
=
(
double
)
2.0
/
3.0
;
double
a
=
y
-
slope
*
x
;
double
a
=
y
-
slope
*
x
;
int
nloops
=
0
;
int
nloops
=
0
;
int
npts
;
int
npts
;
// make this a loop so if my homebrew algorithm screws up, we try it again
// make this a loop so if my homebrew algorithm screws up, we try it again
do
do
{
{
// now find all intersection points of line with polyline sides
// now find all intersection points of line with polyline sides
npts
=
0
;
npts
=
0
;
int
istart
=
GetContourStart
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
for
(
int
ic
=
istart
;
ic
<=
iend
;
ic
++
)
for
(
int
ic
=
istart
;
ic
<=
iend
;
ic
++
)
{
{
double
x
,
y
,
x2
,
y2
;
double
x
,
y
,
x2
,
y2
;
int
ok
;
int
ok
;
if
(
ic
==
istart
)
if
(
ic
==
istart
)
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
iend
].
x
,
corner
[
iend
].
y
,
corner
[
iend
].
x
,
corner
[
iend
].
y
,
corner
[
istart
].
x
,
corner
[
istart
].
y
,
corner
[
istart
].
x
,
corner
[
istart
].
y
,
side_style
[
corner
.
size
()
-
1
],
side_style
[
corner
.
size
()
-
1
],
&
x
,
&
y
,
&
x2
,
&
y2
);
&
x
,
&
y
,
&
x2
,
&
y2
);
else
else
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
ic
-
1
].
x
,
corner
[
ic
-
1
].
y
,
corner
[
ic
-
1
].
x
,
corner
[
ic
-
1
].
y
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
side_style
[
ic
-
1
],
side_style
[
ic
-
1
],
&
x
,
&
y
,
&
x2
,
&
y2
);
&
x
,
&
y
,
&
x2
,
&
y2
);
if
(
ok
)
if
(
ok
)
{
{
xx
[
npts
]
=
(
int
)
x
;
xx
[
npts
]
=
(
int
)
x
;
yy
[
npts
]
=
(
int
)
y
;
yy
[
npts
]
=
(
int
)
y
;
npts
++
;
npts
++
;
ASSERT
(
npts
<
MAXPTS
);
// overflow
ASSERT
(
npts
<
MAXPTS
);
// overflow
}
}
if
(
ok
==
2
)
if
(
ok
==
2
)
{
{
xx
[
npts
]
=
(
int
)
x2
;
xx
[
npts
]
=
(
int
)
x2
;
yy
[
npts
]
=
(
int
)
y2
;
yy
[
npts
]
=
(
int
)
y2
;
npts
++
;
npts
++
;
ASSERT
(
npts
<
MAXPTS
);
// overflow
ASSERT
(
npts
<
MAXPTS
);
// overflow
}
}
}
}
nloops
++
;
nloops
++
;
a
+=
PCBU_PER_MIL
/
100
;
a
+=
PCBU_PER_MIL
/
100
;
}
while
(
npts
%
2
!=
0
&&
nloops
<
3
);
}
while
(
npts
%
2
!=
0
&&
nloops
<
3
);
ASSERT
(
npts
%
2
==
0
);
// odd number of intersection points, error
ASSERT
(
npts
%
2
==
0
);
// odd number of intersection points, error
// count intersection points to right of (x,y), if odd (x,y) is inside polyline
// count intersection points to right of (x,y), if odd (x,y) is inside polyline
int
ncount
=
0
;
int
ncount
=
0
;
for
(
int
ip
=
0
;
ip
<
npts
;
ip
++
)
for
(
int
ip
=
0
;
ip
<
npts
;
ip
++
)
{
{
if
(
xx
[
ip
]
==
x
&&
yy
[
ip
]
==
y
)
if
(
xx
[
ip
]
==
x
&&
yy
[
ip
]
==
y
)
return
FALSE
;
// (x,y) is on a side, call it outside
return
FALSE
;
// (x,y) is on a side, call it outside
else
if
(
xx
[
ip
]
>
x
)
else
if
(
xx
[
ip
]
>
x
)
ncount
++
;
ncount
++
;
}
}
if
(
ncount
%
2
)
if
(
ncount
%
2
)
return
TRUE
;
return
TRUE
;
else
else
return
FALSE
;
return
FALSE
;
}
}
// Test for intersection of sides
// Test for intersection of sides
//
//
int
CPolyLine
::
TestIntersection
(
CPolyLine
*
poly
)
int
CPolyLine
::
TestIntersection
(
CPolyLine
*
poly
)
{
{
if
(
!
GetClosed
()
)
if
(
!
GetClosed
()
)
ASSERT
(
0
);
ASSERT
(
0
);
if
(
!
poly
->
GetClosed
()
)
if
(
!
poly
->
GetClosed
()
)
ASSERT
(
0
);
ASSERT
(
0
);
for
(
int
ic
=
0
;
ic
<
GetNumContours
();
ic
++
)
for
(
int
ic
=
0
;
ic
<
GetNumContours
();
ic
++
)
{
{
int
istart
=
GetContourStart
(
ic
);
int
istart
=
GetContourStart
(
ic
);
int
iend
=
GetContourEnd
(
ic
);
int
iend
=
GetContourEnd
(
ic
);
for
(
int
is
=
istart
;
is
<=
iend
;
is
++
)
for
(
int
is
=
istart
;
is
<=
iend
;
is
++
)
{
{
int
xf
,
yf
;
int
xf
,
yf
;
if
(
is
<
GetContourEnd
(
ic
)
)
if
(
is
<
GetContourEnd
(
ic
)
)
{
{
xf
=
GetX
(
is
+
1
);
xf
=
GetX
(
is
+
1
);
yf
=
GetY
(
is
+
1
);
yf
=
GetY
(
is
+
1
);
}
}
else
else
{
{
xf
=
GetX
(
istart
);
xf
=
GetX
(
istart
);
yf
=
GetY
(
istart
);
yf
=
GetY
(
istart
);
}
}
for
(
int
ic2
=
0
;
ic2
<
poly
->
GetNumContours
();
ic2
++
)
for
(
int
ic2
=
0
;
ic2
<
poly
->
GetNumContours
();
ic2
++
)
{
{
int
istart2
=
poly
->
GetContourStart
(
ic2
);
int
istart2
=
poly
->
GetContourStart
(
ic2
);
int
iend2
=
poly
->
GetContourEnd
(
ic2
);
int
iend2
=
poly
->
GetContourEnd
(
ic2
);
for
(
int
is2
=
istart2
;
is2
<=
iend2
;
is2
++
)
for
(
int
is2
=
istart2
;
is2
<=
iend2
;
is2
++
)
{
{
int
xf2
,
yf2
;
int
xf2
,
yf2
;
if
(
is2
<
poly
->
GetContourEnd
(
ic2
)
)
if
(
is2
<
poly
->
GetContourEnd
(
ic2
)
)
{
{
xf2
=
poly
->
GetX
(
is2
+
1
);
xf2
=
poly
->
GetX
(
is2
+
1
);
yf2
=
poly
->
GetY
(
is2
+
1
);
yf2
=
poly
->
GetY
(
is2
+
1
);
}
}
else
else
{
{
xf2
=
poly
->
GetX
(
istart2
);
xf2
=
poly
->
GetX
(
istart2
);
yf2
=
poly
->
GetY
(
istart2
);
yf2
=
poly
->
GetY
(
istart2
);
}
}
// test for intersection between side and side2
// test for intersection between side and side2
}
}
}
}
}
}
}
}
return
0
;
return
0
;
}
}
// set selection box size
// set selection box size
//
//
void
CPolyLine
::
SetSelBoxSize
(
int
sel_box
)
void
CPolyLine
::
SetSelBoxSize
(
int
sel_box
)
{
{
// Undraw();
// Undraw();
m_sel_box
=
sel_box
;
m_sel_box
=
sel_box
;
// Draw();
// Draw();
}
}
// set pointer to display list, and draw into display list
// set pointer to display list, and draw into display list
//
//
void
CPolyLine
::
SetDisplayList
(
CDisplayList
*
dl
)
void
CPolyLine
::
SetDisplayList
(
CDisplayList
*
dl
)
{
{
if
(
m_dlist
)
if
(
m_dlist
)
Undraw
();
Undraw
();
m_dlist
=
dl
;
m_dlist
=
dl
;
if
(
m_dlist
)
if
(
m_dlist
)
Draw
();
Draw
();
}
}
// copy data from another poly, but don't draw it
// copy data from another poly, but don't draw it
//
//
void
CPolyLine
::
Copy
(
CPolyLine
*
src
)
void
CPolyLine
::
Copy
(
CPolyLine
*
src
)
{
{
Undraw
();
Undraw
();
m_dlist
=
src
->
m_dlist
;
m_dlist
=
src
->
m_dlist
;
m_sel_box
=
src
->
m_sel_box
;
m_sel_box
=
src
->
m_sel_box
;
// copy corners
// copy corners
for
(
unsigned
i
=
0
;
i
<
src
->
corner
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
src
->
corner
.
size
();
i
++
)
corner
.
push_back
(
src
->
corner
[
i
]);
corner
.
push_back
(
src
->
corner
[
i
]);
// copy side styles
// copy side styles
int
nsides
=
src
->
GetNumSides
();
int
nsides
=
src
->
GetNumSides
();
side_style
.
SetSize
(
nsides
);
side_style
.
SetSize
(
nsides
);
for
(
int
i
=
0
;
i
<
nsides
;
i
++
)
for
(
int
i
=
0
;
i
<
nsides
;
i
++
)
side_style
[
i
]
=
src
->
side_style
[
i
];
side_style
[
i
]
=
src
->
side_style
[
i
];
// don't copy the Gpc_poly, just clear the old one
// don't copy the Gpc_poly, just clear the old one
FreeGpcPoly
();
FreeGpcPoly
();
}
}
void
CPolyLine
::
MoveOrigin
(
int
x_off
,
int
y_off
)
void
CPolyLine
::
MoveOrigin
(
int
x_off
,
int
y_off
)
{
{
Undraw
();
Undraw
();
for
(
int
ic
=
0
;
ic
<
GetNumCorners
();
ic
++
)
for
(
int
ic
=
0
;
ic
<
GetNumCorners
();
ic
++
)
{
{
SetX
(
ic
,
GetX
(
ic
)
+
x_off
);
SetX
(
ic
,
GetX
(
ic
)
+
x_off
);
SetY
(
ic
,
GetY
(
ic
)
+
y_off
);
SetY
(
ic
,
GetY
(
ic
)
+
y_off
);
}
}
Draw
();
Draw
();
}
}
// Set various parameters:
// Set various parameters:
// the calling function should Undraw() before calling them,
// the calling function should Undraw() before calling them,
// and Draw() after
// and Draw() after
//
//
void
CPolyLine
::
SetX
(
int
ic
,
int
x
)
{
corner
[
ic
].
x
=
x
;
}
void
CPolyLine
::
SetX
(
int
ic
,
int
x
)
{
corner
[
ic
].
x
=
x
;
}
void
CPolyLine
::
SetY
(
int
ic
,
int
y
)
{
corner
[
ic
].
y
=
y
;
}
void
CPolyLine
::
SetY
(
int
ic
,
int
y
)
{
corner
[
ic
].
y
=
y
;
}
void
CPolyLine
::
SetEndContour
(
int
ic
,
BOOL
end_contour
)
{
corner
[
ic
].
end_contour
=
end_contour
;
}
void
CPolyLine
::
SetEndContour
(
int
ic
,
BOOL
end_contour
)
{
corner
[
ic
].
end_contour
=
end_contour
;
}
// Create CPolyLine for a pad
// Create CPolyLine for a pad
//
//
CPolyLine
*
CPolyLine
::
MakePolylineForPad
(
int
type
,
int
x
,
int
y
,
int
w
,
int
l
,
int
r
,
int
angle
)
CPolyLine
*
CPolyLine
::
MakePolylineForPad
(
int
type
,
int
x
,
int
y
,
int
w
,
int
l
,
int
r
,
int
angle
)
{
{
CPolyLine
*
poly
=
new
CPolyLine
;
CPolyLine
*
poly
=
new
CPolyLine
;
int
dx
=
l
/
2
;
int
dx
=
l
/
2
;
int
dy
=
w
/
2
;
int
dy
=
w
/
2
;
if
(
angle
%
180
==
90
)
if
(
angle
%
180
==
90
)
{
{
dx
=
w
/
2
;
dx
=
w
/
2
;
dy
=
l
/
2
;
dy
=
l
/
2
;
}
}
if
(
type
==
PAD_ROUND
)
if
(
type
==
PAD_ROUND
)
{
{
poly
->
Start
(
0
,
0
,
0
,
x
-
dx
,
y
,
0
);
poly
->
Start
(
0
,
0
,
0
,
x
-
dx
,
y
,
0
);
poly
->
AppendCorner
(
x
,
y
+
dy
,
ARC_CW
,
0
);
poly
->
AppendCorner
(
x
,
y
+
dy
,
ARC_CW
,
0
);
poly
->
AppendCorner
(
x
+
dx
,
y
,
ARC_CW
,
0
);
poly
->
AppendCorner
(
x
+
dx
,
y
,
ARC_CW
,
0
);
poly
->
AppendCorner
(
x
,
y
-
dy
,
ARC_CW
,
0
);
poly
->
AppendCorner
(
x
,
y
-
dy
,
ARC_CW
,
0
);
poly
->
Close
(
ARC_CW
);
poly
->
Close
(
ARC_CW
);
}
}
return
poly
;
return
poly
;
}
}
// Add cutout for a pad
// Add cutout for a pad
// Convert arcs to multiple straight lines
// Convert arcs to multiple straight lines
// Do NOT draw or undraw
// Do NOT draw or undraw
//
//
void
CPolyLine
::
AddContourForPadClearance
(
int
type
,
int
x
,
int
y
,
int
w
,
void
CPolyLine
::
AddContourForPadClearance
(
int
type
,
int
x
,
int
y
,
int
w
,
int
l
,
int
r
,
int
angle
,
int
fill_clearance
,
int
l
,
int
r
,
int
angle
,
int
fill_clearance
,
int
hole_w
,
int
hole_clearance
,
BOOL
bThermal
,
int
spoke_w
)
int
hole_w
,
int
hole_clearance
,
BOOL
bThermal
,
int
spoke_w
)
{
{
int
dx
=
l
/
2
;
int
dx
=
l
/
2
;
int
dy
=
w
/
2
;
int
dy
=
w
/
2
;
if
(
angle
%
180
==
90
)
if
(
angle
%
180
==
90
)
{
{
dx
=
w
/
2
;
dx
=
w
/
2
;
dy
=
l
/
2
;
dy
=
l
/
2
;
}
}
int
x_clearance
=
max
(
fill_clearance
,
hole_clearance
+
hole_w
/
2
-
dx
);
int
x_clearance
=
max
(
fill_clearance
,
hole_clearance
+
hole_w
/
2
-
dx
);
int
y_clearance
=
max
(
fill_clearance
,
hole_clearance
+
hole_w
/
2
-
dy
);
int
y_clearance
=
max
(
fill_clearance
,
hole_clearance
+
hole_w
/
2
-
dy
);
dx
+=
x_clearance
;
dx
+=
x_clearance
;
dy
+=
y_clearance
;
dy
+=
y_clearance
;
if
(
!
bThermal
)
if
(
!
bThermal
)
{
{
// normal clearance
// normal clearance
if
(
type
==
PAD_ROUND
||
(
type
==
PAD_NONE
&&
hole_w
>
0
)
)
if
(
type
==
PAD_ROUND
||
(
type
==
PAD_NONE
&&
hole_w
>
0
)
)
{
{
AppendCorner
(
x
-
dx
,
y
,
ARC_CW
,
0
);
AppendCorner
(
x
-
dx
,
y
,
ARC_CW
,
0
);
AppendCorner
(
x
,
y
+
dy
,
ARC_CW
,
0
);
AppendCorner
(
x
,
y
+
dy
,
ARC_CW
,
0
);
AppendCorner
(
x
+
dx
,
y
,
ARC_CW
,
0
);
AppendCorner
(
x
+
dx
,
y
,
ARC_CW
,
0
);
AppendCorner
(
x
,
y
-
dy
,
ARC_CW
,
0
);
AppendCorner
(
x
,
y
-
dy
,
ARC_CW
,
0
);
Close
(
ARC_CW
);
Close
(
ARC_CW
);
}
}
else
if
(
type
==
PAD_SQUARE
||
type
==
PAD_RECT
else
if
(
type
==
PAD_SQUARE
||
type
==
PAD_RECT
||
type
==
PAD_RRECT
||
type
==
PAD_OVAL
)
||
type
==
PAD_RRECT
||
type
==
PAD_OVAL
)
{
{
AppendCorner
(
x
-
dx
,
y
-
dy
,
STRAIGHT
,
0
);
AppendCorner
(
x
-
dx
,
y
-
dy
,
STRAIGHT
,
0
);
AppendCorner
(
x
+
dx
,
y
-
dy
,
STRAIGHT
,
0
);
AppendCorner
(
x
+
dx
,
y
-
dy
,
STRAIGHT
,
0
);
AppendCorner
(
x
+
dx
,
y
+
dy
,
STRAIGHT
,
0
);
AppendCorner
(
x
+
dx
,
y
+
dy
,
STRAIGHT
,
0
);
AppendCorner
(
x
-
dx
,
y
+
dy
,
STRAIGHT
,
0
);
AppendCorner
(
x
-
dx
,
y
+
dy
,
STRAIGHT
,
0
);
Close
(
STRAIGHT
);
Close
(
STRAIGHT
);
}
}
}
}
else
else
{
{
// thermal relief
// thermal relief
if
(
type
==
PAD_ROUND
||
(
type
==
PAD_NONE
&&
hole_w
>
0
)
)
if
(
type
==
PAD_ROUND
||
(
type
==
PAD_NONE
&&
hole_w
>
0
)
)
{
{
// draw 4 "wedges"
// draw 4 "wedges"
double
r
=
max
(
w
/
2
+
fill_clearance
,
hole_w
/
2
+
hole_clearance
);
double
r
=
max
(
w
/
2
+
fill_clearance
,
hole_w
/
2
+
hole_clearance
);
double
start_angle
=
asin
(
spoke_w
/
(
2.0
*
r
)
);
double
start_angle
=
asin
(
spoke_w
/
(
2.0
*
r
)
);
double
th1
,
th2
,
corner_x
,
corner_y
;
double
th1
,
th2
,
corner_x
,
corner_y
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
{
if
(
i
==
0
)
if
(
i
==
0
)
{
{
corner_x
=
spoke_w
/
2
;
corner_x
=
spoke_w
/
2
;
corner_y
=
spoke_w
/
2
;
corner_y
=
spoke_w
/
2
;
th1
=
start_angle
;
th1
=
start_angle
;
th2
=
pi
/
2.0
-
start_angle
;
th2
=
pi
/
2.0
-
start_angle
;
}
}
else
if
(
i
==
1
)
else
if
(
i
==
1
)
{
{
corner_x
=
-
spoke_w
/
2
;
corner_x
=
-
spoke_w
/
2
;
corner_y
=
spoke_w
/
2
;
corner_y
=
spoke_w
/
2
;
th1
=
pi
/
2.0
+
start_angle
;
th1
=
pi
/
2.0
+
start_angle
;
th2
=
pi
-
start_angle
;
th2
=
pi
-
start_angle
;
}
}
else
if
(
i
==
2
)
else
if
(
i
==
2
)
{
{
corner_x
=
-
spoke_w
/
2
;
corner_x
=
-
spoke_w
/
2
;
corner_y
=
-
spoke_w
/
2
;
corner_y
=
-
spoke_w
/
2
;
th1
=
-
pi
+
start_angle
;
th1
=
-
pi
+
start_angle
;
th2
=
-
pi
/
2.0
-
start_angle
;
th2
=
-
pi
/
2.0
-
start_angle
;
}
}
else
if
(
i
==
3
)
else
if
(
i
==
3
)
{
{
corner_x
=
spoke_w
/
2
;
corner_x
=
spoke_w
/
2
;
corner_y
=
-
spoke_w
/
2
;
corner_y
=
-
spoke_w
/
2
;
th1
=
-
pi
/
2.0
+
start_angle
;
th1
=
-
pi
/
2.0
+
start_angle
;
th2
=
-
start_angle
;
th2
=
-
start_angle
;
}
}
AppendCorner
(
to_int
(
x
+
corner_x
),
to_int
(
y
+
corner_y
),
STRAIGHT
,
0
);
AppendCorner
(
to_int
(
x
+
corner_x
),
to_int
(
y
+
corner_y
),
STRAIGHT
,
0
);
AppendCorner
(
to_int
(
x
+
r
*
cos
(
th1
)),
to_int
(
y
+
r
*
sin
(
th1
)),
STRAIGHT
,
0
);
AppendCorner
(
to_int
(
x
+
r
*
cos
(
th1
)),
to_int
(
y
+
r
*
sin
(
th1
)),
STRAIGHT
,
0
);
AppendCorner
(
to_int
(
x
+
r
*
cos
(
th2
)),
to_int
(
y
+
r
*
sin
(
th2
)),
ARC_CCW
,
0
);
AppendCorner
(
to_int
(
x
+
r
*
cos
(
th2
)),
to_int
(
y
+
r
*
sin
(
th2
)),
ARC_CCW
,
0
);
Close
(
STRAIGHT
);
Close
(
STRAIGHT
);
}
}
}
}
else
if
(
type
==
PAD_SQUARE
||
type
==
PAD_RECT
else
if
(
type
==
PAD_SQUARE
||
type
==
PAD_RECT
||
type
==
PAD_RRECT
||
type
==
PAD_OVAL
)
||
type
==
PAD_RRECT
||
type
==
PAD_OVAL
)
{
{
// draw 4 rectangles
// draw 4 rectangles
int
xL
=
x
-
dx
;
int
xL
=
x
-
dx
;
int
xR
=
x
-
spoke_w
/
2
;
int
xR
=
x
-
spoke_w
/
2
;
int
yB
=
y
-
dy
;
int
yB
=
y
-
dy
;
int
yT
=
y
-
spoke_w
/
2
;
int
yT
=
y
-
spoke_w
/
2
;
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
Close
(
STRAIGHT
);
Close
(
STRAIGHT
);
xL
=
x
+
spoke_w
/
2
;
xL
=
x
+
spoke_w
/
2
;
xR
=
x
+
dx
;
xR
=
x
+
dx
;
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
Close
(
STRAIGHT
);
Close
(
STRAIGHT
);
xL
=
x
-
dx
;
xL
=
x
-
dx
;
xR
=
x
-
spoke_w
/
2
;
xR
=
x
-
spoke_w
/
2
;
yB
=
y
+
spoke_w
/
2
;
yB
=
y
+
spoke_w
/
2
;
yT
=
y
+
dy
;
yT
=
y
+
dy
;
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
Close
(
STRAIGHT
);
Close
(
STRAIGHT
);
xL
=
x
+
spoke_w
/
2
;
xL
=
x
+
spoke_w
/
2
;
xR
=
x
+
dx
;
xR
=
x
+
dx
;
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yB
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xR
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
AppendCorner
(
xL
,
yT
,
STRAIGHT
,
0
);
Close
(
STRAIGHT
);
Close
(
STRAIGHT
);
}
}
}
}
return
;
return
;
}
}
void
CPolyLine
::
AppendArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xc
,
int
yc
,
int
num
)
void
CPolyLine
::
AppendArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xc
,
int
yc
,
int
num
)
{
{
// get radius
// get radius
double
r
=
sqrt
(
(
double
)(
xi
-
xc
)
*
(
xi
-
xc
)
+
(
double
)(
yi
-
yc
)
*
(
yi
-
yc
)
);
double
r
=
sqrt
(
(
double
)(
xi
-
xc
)
*
(
xi
-
xc
)
+
(
double
)(
yi
-
yc
)
*
(
yi
-
yc
)
);
// get angles of start and finish
// get angles of start and finish
double
th_i
=
atan2
(
(
double
)
yi
-
yc
,
(
double
)
xi
-
xc
);
double
th_i
=
atan2
(
(
double
)
yi
-
yc
,
(
double
)
xi
-
xc
);
double
th_f
=
atan2
(
(
double
)
yf
-
yc
,
(
double
)
xf
-
xc
);
double
th_f
=
atan2
(
(
double
)
yf
-
yc
,
(
double
)
xf
-
xc
);
double
th_d
=
(
th_f
-
th_i
)
/
(
num
-
1
);
double
th_d
=
(
th_f
-
th_i
)
/
(
num
-
1
);
double
theta
=
th_i
;
double
theta
=
th_i
;
// generate arc
// generate arc
for
(
int
ic
=
0
;
ic
<
num
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
num
;
ic
++
)
{
{
int
x
=
to_int
(
xc
+
r
*
cos
(
theta
));
int
x
=
to_int
(
xc
+
r
*
cos
(
theta
));
int
y
=
to_int
(
yc
+
r
*
sin
(
theta
));
int
y
=
to_int
(
yc
+
r
*
sin
(
theta
));
AppendCorner
(
x
,
y
,
STRAIGHT
,
0
);
AppendCorner
(
x
,
y
,
STRAIGHT
,
0
);
theta
+=
th_d
;
theta
+=
th_d
;
}
}
Close
(
STRAIGHT
);
Close
(
STRAIGHT
);
}
}
void
CPolyLine
::
ClipGpcPolygon
(
gpc_op
op
,
CPolyLine
*
clip_poly
)
void
CPolyLine
::
ClipGpcPolygon
(
gpc_op
op
,
CPolyLine
*
clip_poly
)
{
{
gpc_polygon
*
result
=
new
gpc_polygon
;
gpc_polygon
*
result
=
new
gpc_polygon
;
gpc_polygon_clip
(
op
,
m_gpc_poly
,
clip_poly
->
GetGpcPoly
(),
result
);
gpc_polygon_clip
(
op
,
m_gpc_poly
,
clip_poly
->
GetGpcPoly
(),
result
);
gpc_free_polygon
(
m_gpc_poly
);
gpc_free_polygon
(
m_gpc_poly
);
delete
m_gpc_poly
;
delete
m_gpc_poly
;
m_gpc_poly
=
result
;
m_gpc_poly
=
result
;
}
}
polygon/PolyLine.h
View file @
e126042b
// PolyLine.h ... definition of CPolyLine class
// PolyLine.h ... definition of CPolyLine class
//
//
// A polyline contains one or more contours, where each contour
// A polyline contains one or more contours, where each contour
// is defined by a list of corners and side-styles
// is defined by a list of corners and side-styles
// There may be multiple contours in a polyline.
// There may be multiple contours in a polyline.
// The last contour may be open or closed, any others must be closed.
// The last contour may be open or closed, any others must be closed.
// All of the corners and side-styles are concatenated into 2 arrays,
// All of the corners and side-styles are concatenated into 2 arrays,
// separated by setting the end_contour flag of the last corner of
// separated by setting the end_contour flag of the last corner of
// each contour.
// each contour.
//
//
// When used for copper areas, the first contour is the outer edge
// When used for copper areas, the first contour is the outer edge
// of the area, subsequent ones are "holes" in the copper.
// of the area, subsequent ones are "holes" in the copper.
//
//
// If a CDisplayList pointer is provided, the polyline can draw itself
// If a CDisplayList pointer is provided, the polyline can draw itself
#ifndef POLYLINE_H
#ifndef POLYLINE_H
#define POLYLINE_H
#define POLYLINE_H
#include <vector>
#include <vector>
#include "defs-macros.h"
#include "defs-macros.h"
#include "GenericPolygonClipperLibrary.h"
#include "GenericPolygonClipperLibrary.h"
#include "php_polygon.h"
#include "php_polygon.h"
#include "php_polygon_vertex.h"
#include "php_polygon_vertex.h"
#include "PolyLine2Kicad.h"
#include "PolyLine2Kicad.h"
#include "freepcb_ids.h"
#include "freepcb_ids.h"
#include "freepcbDisplayList.h"
#include "freepcbDisplayList.h"
#include "math_for_graphics.h"
#include "math_for_graphics.h"
class
CSegment
{
class
CSegment
{
public
:
public
:
int
xi
,
yi
,
xf
,
yf
;
int
xi
,
yi
,
xf
,
yf
;
CSegment
()
{};
CSegment
()
{};
CSegment
(
int
x0
,
int
y0
,
int
x1
,
int
y1
)
{
CSegment
(
int
x0
,
int
y0
,
int
x1
,
int
y1
)
{
xi
=
x0
;
yi
=
y0
;
xf
=
x1
;
yf
=
y1
;
}
xi
=
x0
;
yi
=
y0
;
xf
=
x1
;
yf
=
y1
;
}
};
};
class
CArc
{
class
CArc
{
public
:
public
:
enum
{
MAX_STEP
=
50
*
25400
};
// max step is 20 mils
enum
{
MAX_STEP
=
50
*
25400
};
// max step is 20 mils
enum
{
MIN_STEPS
=
18
};
// min step is 5 degrees
enum
{
MIN_STEPS
=
18
};
// min step is 5 degrees
int
style
;
int
style
;
int
xi
,
yi
,
xf
,
yf
;
int
xi
,
yi
,
xf
,
yf
;
int
n_steps
;
// number of straight-line segments in gpc_poly
int
n_steps
;
// number of straight-line segments in gpc_poly
BOOL
bFound
;
BOOL
bFound
;
};
};
class
CPolyPt
class
CPolyPt
{
{
public
:
public
:
CPolyPt
(
int
qx
=
0
,
int
qy
=
0
,
BOOL
qf
=
FALSE
)
CPolyPt
(
int
qx
=
0
,
int
qy
=
0
,
BOOL
qf
=
FALSE
)
{
x
=
qx
;
y
=
qy
;
end_contour
=
qf
;
utility
=
0
;
};
{
x
=
qx
;
y
=
qy
;
end_contour
=
qf
;
utility
=
0
;
};
int
x
;
int
x
;
int
y
;
int
y
;
BOOL
end_contour
;
BOOL
end_contour
;
int
utility
;
int
utility
;
};
};
class
CPolyLine
class
CPolyLine
{
{
public
:
public
:
enum
{
STRAIGHT
,
ARC_CW
,
ARC_CCW
};
// side styles
enum
{
STRAIGHT
,
ARC_CW
,
ARC_CCW
};
// side styles
enum
{
NO_HATCH
,
DIAGONAL_FULL
,
DIAGONAL_EDGE
};
// hatch styles
enum
{
NO_HATCH
,
DIAGONAL_FULL
,
DIAGONAL_EDGE
};
// hatch styles
enum
{
DEF_SIZE
=
50
,
DEF_ADD
=
50
};
// number of array elements to add at a time
enum
{
DEF_SIZE
=
50
,
DEF_ADD
=
50
};
// number of array elements to add at a time
// constructors/destructor
// constructors/destructor
CPolyLine
(
CDisplayList
*
dl
);
CPolyLine
(
CDisplayList
*
dl
);
CPolyLine
();
CPolyLine
();
~
CPolyLine
();
~
CPolyLine
();
// functions for modifying polyline
// functions for modifying polyline
void
Start
(
int
layer
,
int
w
,
int
sel_box
,
int
x
,
int
y
,
void
Start
(
int
layer
,
int
w
,
int
sel_box
,
int
x
,
int
y
,
int
hatch
);
int
hatch
);
void
AppendCorner
(
int
x
,
int
y
,
int
style
=
STRAIGHT
,
BOOL
bDraw
=
TRUE
);
void
AppendCorner
(
int
x
,
int
y
,
int
style
=
STRAIGHT
,
BOOL
bDraw
=
TRUE
);
void
InsertCorner
(
int
ic
,
int
x
,
int
y
);
void
InsertCorner
(
int
ic
,
int
x
,
int
y
);
void
DeleteCorner
(
int
ic
,
BOOL
bDraw
=
TRUE
);
void
DeleteCorner
(
int
ic
,
BOOL
bDraw
=
TRUE
);
void
MoveCorner
(
int
ic
,
int
x
,
int
y
);
void
MoveCorner
(
int
ic
,
int
x
,
int
y
);
void
Close
(
int
style
=
STRAIGHT
,
BOOL
bDraw
=
TRUE
);
void
Close
(
int
style
=
STRAIGHT
,
BOOL
bDraw
=
TRUE
);
void
RemoveContour
(
int
icont
);
void
RemoveContour
(
int
icont
);
// drawing functions
// drawing functions
void
HighlightSide
(
int
is
);
void
HighlightSide
(
int
is
);
void
HighlightCorner
(
int
ic
);
void
HighlightCorner
(
int
ic
);
void
StartDraggingToInsertCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
);
void
StartDraggingToInsertCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
);
void
StartDraggingToMoveCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
);
void
StartDraggingToMoveCorner
(
CDC
*
pDC
,
int
ic
,
int
x
,
int
y
);
void
CancelDraggingToInsertCorner
(
int
ic
);
void
CancelDraggingToInsertCorner
(
int
ic
);
void
CancelDraggingToMoveCorner
(
int
ic
);
void
CancelDraggingToMoveCorner
(
int
ic
);
void
Undraw
();
void
Undraw
();
void
Draw
(
CDisplayList
*
dl
=
NULL
);
void
Draw
(
CDisplayList
*
dl
=
NULL
);
void
Hatch
();
void
Hatch
();
void
MakeVisible
(
BOOL
visible
=
TRUE
);
void
MakeVisible
(
BOOL
visible
=
TRUE
);
void
MoveOrigin
(
int
x_off
,
int
y_off
);
void
MoveOrigin
(
int
x_off
,
int
y_off
);
// misc. functions
// misc. functions
CRect
GetBounds
();
CRect
GetBounds
();
CRect
GetCornerBounds
();
CRect
GetCornerBounds
();
CRect
GetCornerBounds
(
int
icont
);
CRect
GetCornerBounds
(
int
icont
);
void
Copy
(
CPolyLine
*
src
);
void
Copy
(
CPolyLine
*
src
);
BOOL
TestPointInside
(
int
x
,
int
y
);
BOOL
TestPointInside
(
int
x
,
int
y
);
BOOL
TestPointInsideContour
(
int
icont
,
int
x
,
int
y
);
BOOL
TestPointInsideContour
(
int
icont
,
int
x
,
int
y
);
int
TestIntersection
(
CPolyLine
*
poly
);
int
TestIntersection
(
CPolyLine
*
poly
);
void
AppendArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xc
,
int
yc
,
int
num
);
void
AppendArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xc
,
int
yc
,
int
num
);
// access functions
// access functions
int
GetNumCorners
();
int
GetNumCorners
();
int
GetNumSides
();
int
GetNumSides
();
int
GetClosed
();
int
GetClosed
();
int
GetNumContours
();
int
GetNumContours
();
int
GetContour
(
int
ic
);
int
GetContour
(
int
ic
);
int
GetContourStart
(
int
icont
);
int
GetContourStart
(
int
icont
);
int
GetContourEnd
(
int
icont
);
int
GetContourEnd
(
int
icont
);
int
GetContourSize
(
int
icont
);
int
GetContourSize
(
int
icont
);
int
GetX
(
int
ic
);
int
GetX
(
int
ic
);
int
GetY
(
int
ic
);
int
GetY
(
int
ic
);
int
GetEndContour
(
int
ic
);
int
GetEndContour
(
int
ic
);
int
GetUtility
(
int
ic
){
return
corner
[
ic
].
utility
;
};
int
GetUtility
(
int
ic
){
return
corner
[
ic
].
utility
;
};
void
SetUtility
(
int
ic
,
int
utility
){
corner
[
ic
].
utility
=
utility
;
};
void
SetUtility
(
int
ic
,
int
utility
){
corner
[
ic
].
utility
=
utility
;
};
int
GetW
();
int
GetW
();
int
GetSideStyle
(
int
is
);
int
GetSideStyle
(
int
is
);
id
GetId
();
id
GetId
();
int
GetSelBoxSize
();
int
GetSelBoxSize
();
CDisplayList
*
GetDisplayList
(){
return
m_dlist
;
};
CDisplayList
*
GetDisplayList
(){
return
m_dlist
;
};
int
GetHatch
(){
return
m_HatchStyle
;
}
int
GetHatch
(){
return
m_HatchStyle
;
}
void
SetHatch
(
int
hatch
){
Undraw
();
m_HatchStyle
=
hatch
;
Draw
();
};
void
SetHatch
(
int
hatch
){
Undraw
();
m_HatchStyle
=
hatch
;
Draw
();
};
void
SetX
(
int
ic
,
int
x
);
void
SetX
(
int
ic
,
int
x
);
void
SetY
(
int
ic
,
int
y
);
void
SetY
(
int
ic
,
int
y
);
void
SetEndContour
(
int
ic
,
BOOL
end_contour
);
void
SetEndContour
(
int
ic
,
BOOL
end_contour
);
// void SetLayer( int layer );
// void SetLayer( int layer );
void
SetW
(
int
w
);
void
SetW
(
int
w
);
void
SetSideStyle
(
int
is
,
int
style
);
void
SetSideStyle
(
int
is
,
int
style
);
void
SetSelBoxSize
(
int
sel_box
);
void
SetSelBoxSize
(
int
sel_box
);
void
SetDisplayList
(
CDisplayList
*
dl
);
void
SetDisplayList
(
CDisplayList
*
dl
);
// GPC functions
// GPC functions
int
MakeGpcPoly
(
int
icontour
=
0
,
std
::
vector
<
CArc
>
*
arc_array
=
NULL
);
int
MakeGpcPoly
(
int
icontour
=
0
,
std
::
vector
<
CArc
>
*
arc_array
=
NULL
);
int
FreeGpcPoly
();
int
FreeGpcPoly
();
gpc_polygon
*
GetGpcPoly
(){
return
m_gpc_poly
;
};
gpc_polygon
*
GetGpcPoly
(){
return
m_gpc_poly
;
};
int
NormalizeWithGpc
(
std
::
vector
<
CPolyLine
*>
*
pa
=
NULL
,
BOOL
bRetainArcs
=
FALSE
);
int
NormalizeWithGpc
(
std
::
vector
<
CPolyLine
*>
*
pa
=
NULL
,
BOOL
bRetainArcs
=
FALSE
);
int
RestoreArcs
(
std
::
vector
<
CArc
>
*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
=
NULL
);
int
RestoreArcs
(
std
::
vector
<
CArc
>
*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
=
NULL
);
CPolyLine
*
MakePolylineForPad
(
int
type
,
int
x
,
int
y
,
int
w
,
int
l
,
int
r
,
int
angle
);
CPolyLine
*
MakePolylineForPad
(
int
type
,
int
x
,
int
y
,
int
w
,
int
l
,
int
r
,
int
angle
);
void
AddContourForPadClearance
(
int
type
,
int
x
,
int
y
,
int
w
,
void
AddContourForPadClearance
(
int
type
,
int
x
,
int
y
,
int
w
,
int
l
,
int
r
,
int
angle
,
int
fill_clearance
,
int
l
,
int
r
,
int
angle
,
int
fill_clearance
,
int
hole_w
,
int
hole_clearance
,
BOOL
bThermal
=
FALSE
,
int
spoke_w
=
0
);
int
hole_w
,
int
hole_clearance
,
BOOL
bThermal
=
FALSE
,
int
spoke_w
=
0
);
void
ClipGpcPolygon
(
gpc_op
op
,
CPolyLine
*
poly
);
void
ClipGpcPolygon
(
gpc_op
op
,
CPolyLine
*
poly
);
// PHP functions
// PHP functions
int
MakePhpPoly
();
int
MakePhpPoly
();
void
FreePhpPoly
();
void
FreePhpPoly
();
void
ClipPhpPolygon
(
int
php_op
,
CPolyLine
*
poly
);
void
ClipPhpPolygon
(
int
php_op
,
CPolyLine
*
poly
);
private
:
private
:
CDisplayList
*
m_dlist
;
// display list
CDisplayList
*
m_dlist
;
// display list
int
m_layer
;
// layer to draw on
int
m_layer
;
// layer to draw on
int
m_Width
;
// line width
int
m_Width
;
// line width
int
m_sel_box
;
// corner selection box width/2
int
m_sel_box
;
// corner selection box width/2
public
:
public
:
std
::
vector
<
CPolyPt
>
corner
;
// array of points for corners
std
::
vector
<
CPolyPt
>
corner
;
// array of points for corners
std
::
vector
<
int
>
side_style
;
// array of styles for sides
std
::
vector
<
int
>
side_style
;
// array of styles for sides
private
:
private
:
std
::
vector
<
dl_element
*>
dl_side
;
// graphic elements
std
::
vector
<
dl_element
*>
dl_side
;
// graphic elements
std
::
vector
<
dl_element
*>
dl_side_sel
;
std
::
vector
<
dl_element
*>
dl_side_sel
;
std
::
vector
<
dl_element
*>
dl_corner_sel
;
std
::
vector
<
dl_element
*>
dl_corner_sel
;
public
:
public
:
int
m_HatchStyle
;
// hatch style, see enum above
int
m_HatchStyle
;
// hatch style, see enum above
std
::
vector
<
CSegment
>
m_HatchLines
;
// hatch lines
std
::
vector
<
CSegment
>
m_HatchLines
;
// hatch lines
private
:
private
:
gpc_polygon
*
m_gpc_poly
;
// polygon in gpc format
gpc_polygon
*
m_gpc_poly
;
// polygon in gpc format
polygon
*
m_php_poly
;
polygon
*
m_php_poly
;
BOOL
bDrawn
;
BOOL
bDrawn
;
};
};
#endif // #ifndef POLYLINE_H
#endif // #ifndef POLYLINE_H
polygon/PolyLine2Kicad.h
View file @
e126042b
// PolyLine.h ... definition of CPolyLine class
// PolyLine.h ... definition of CPolyLine class
//
//
// A polyline contains one or more contours, where each contour
// A polyline contains one or more contours, where each contour
// is defined by a list of corners and side-styles
// is defined by a list of corners and side-styles
// There may be multiple contours in a polyline.
// There may be multiple contours in a polyline.
// The last contour may be open or closed, any others must be closed.
// The last contour may be open or closed, any others must be closed.
// All of the corners and side-styles are concatenated into 2 arrays,
// All of the corners and side-styles are concatenated into 2 arrays,
// separated by setting the end_contour flag of the last corner of
// separated by setting the end_contour flag of the last corner of
// each contour.
// each contour.
//
//
// When used for copper areas, the first contour is the outer edge
// When used for copper areas, the first contour is the outer edge
// of the area, subsequent ones are "holes" in the copper.
// of the area, subsequent ones are "holes" in the copper.
//
//
// If a CDisplayList pointer is provided, the polyline can draw itself
// If a CDisplayList pointer is provided, the polyline can draw itself
#ifndef POLYLINE2KICAD_H
#ifndef POLYLINE2KICAD_H
#define POLYLINE2KICAD_H
#define POLYLINE2KICAD_H
#define PCBU_PER_MIL 10
#define PCBU_PER_MIL 10
#define MAX_LAYERS 32
#define MAX_LAYERS 32
#define NM_PER_MIL 10 // 25400
#define NM_PER_MIL 10 // 25400
// pad shapes
// pad shapes
enum
enum
{
{
PAD_NONE
=
0
,
PAD_NONE
=
0
,
PAD_ROUND
,
PAD_ROUND
,
PAD_SQUARE
,
PAD_SQUARE
,
PAD_RECT
,
PAD_RECT
,
PAD_RRECT
,
PAD_RRECT
,
PAD_OVAL
,
PAD_OVAL
,
PAD_OCTAGON
PAD_OCTAGON
};
};
/*
/*
enum
enum
{
{
// visible layers
// visible layers
LAY_SELECTION = 0,
LAY_SELECTION = 0,
LAY_BACKGND,
LAY_BACKGND,
LAY_VISIBLE_GRID,
LAY_VISIBLE_GRID,
LAY_HILITE,
LAY_HILITE,
LAY_DRC_ERROR,
LAY_DRC_ERROR,
LAY_BOARD_OUTLINE,
LAY_BOARD_OUTLINE,
LAY_RAT_LINE,
LAY_RAT_LINE,
LAY_SILK_TOP,
LAY_SILK_TOP,
LAY_SILK_BOTTOM,
LAY_SILK_BOTTOM,
LAY_SM_TOP,
LAY_SM_TOP,
LAY_SM_BOTTOM,
LAY_SM_BOTTOM,
LAY_PAD_THRU,
LAY_PAD_THRU,
LAY_TOP_COPPER,
LAY_TOP_COPPER,
LAY_BOTTOM_COPPER,
LAY_BOTTOM_COPPER,
// invisible layers
// invisible layers
LAY_MASK_TOP = -100,
LAY_MASK_TOP = -100,
LAY_MASK_BOTTOM = -101,
LAY_MASK_BOTTOM = -101,
LAY_PASTE_TOP = -102,
LAY_PASTE_TOP = -102,
LAY_PASTE_BOTTOM = -103
LAY_PASTE_BOTTOM = -103
};
};
*/
*/
#define LAY_SELECTION 0
#define LAY_SELECTION 0
#define LAY_TOP_COPPER 0
#define LAY_TOP_COPPER 0
#define CDC wxDC
#define CDC wxDC
class
wxDC
;
class
wxDC
;
#if 0
#if 0
class dl_element;
class dl_element;
class CDisplayList {
class CDisplayList {
public:
public:
void Set_visible(void*, int) {};
void Set_visible(void*, int) {};
int Get_x(void) { return 0;};
int Get_x(void) { return 0;};
int Get_y(void) { return 0;};
int Get_y(void) { return 0;};
void StopDragging(void) {};
void StopDragging(void) {};
void CancelHighLight(void) {};
void CancelHighLight(void) {};
void StartDraggingLineVertex(...) {};
void StartDraggingLineVertex(...) {};
void Add() {};
void Add() {};
};
};
#endif
#endif
class
CRect
{
class
CRect
{
public
:
public
:
int
left
,
right
,
top
,
bottom
;
int
left
,
right
,
top
,
bottom
;
};
};
class
CPoint
{
class
CPoint
{
public
:
public
:
int
x
,
y
;
int
x
,
y
;
public
:
public
:
CPoint
(
void
)
{
x
=
y
=
0
;};
CPoint
(
void
)
{
x
=
y
=
0
;};
CPoint
(
int
i
,
int
j
)
{
x
=
i
;
y
=
j
;};
CPoint
(
int
i
,
int
j
)
{
x
=
i
;
y
=
j
;};
};
};
#endif // #ifndef POLYLINE2KICAD_H
#endif // #ifndef POLYLINE2KICAD_H
polygon/cdisplaylist_stuff.cpp
View file @
e126042b
/* stuff for class CDisplayList */
/* stuff for class CDisplayList */
#include "PolyLine.h"
#include "PolyLine.h"
dl_element
*
CDisplayList
::
Add
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
dl_element
*
CDisplayList
::
Add
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
radius
,
int
orig_layer
)
int
radius
,
int
orig_layer
)
{
{
return
NULL
;
return
NULL
;
}
}
dl_element
*
CDisplayList
::
AddSelector
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
dl_element
*
CDisplayList
::
AddSelector
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
radius
)
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
radius
)
{
{
return
NULL
;
return
NULL
;
}
}
void
CDisplayList
::
Set_visible
(
dl_element
*
el
,
int
visible
)
void
CDisplayList
::
Set_visible
(
dl_element
*
el
,
int
visible
)
{
{
}
}
int
CDisplayList
::
StopDragging
()
int
CDisplayList
::
StopDragging
()
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
CancelHighLight
()
int
CDisplayList
::
CancelHighLight
()
{
{
return
0
;
return
0
;
}
}
void
CDisplayList
::
Set_id
(
dl_element
*
el
,
id
*
id
)
void
CDisplayList
::
Set_id
(
dl_element
*
el
,
id
*
id
)
{
{
}
}
id
CDisplayList
::
Remove
(
dl_element
*
element
)
id
CDisplayList
::
Remove
(
dl_element
*
element
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
Get_w
(
dl_element
*
el
)
int
CDisplayList
::
Get_w
(
dl_element
*
el
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
Get_x
(
dl_element
*
el
)
int
CDisplayList
::
Get_x
(
dl_element
*
el
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
Get_y
(
dl_element
*
el
)
int
CDisplayList
::
Get_y
(
dl_element
*
el
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
Get_xf
(
dl_element
*
el
)
int
CDisplayList
::
Get_xf
(
dl_element
*
el
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
Get_yf
(
dl_element
*
el
)
int
CDisplayList
::
Get_yf
(
dl_element
*
el
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
HighLight
(
int
gtype
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
w
,
int
orig_layer
)
int
CDisplayList
::
HighLight
(
int
gtype
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
w
,
int
orig_layer
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
StartDraggingLineVertex
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
CDisplayList
::
StartDraggingLineVertex
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xf
,
int
yf
,
int
layer1
,
int
layer2
,
int
w1
,
int
w2
,
int
layer1
,
int
layer2
,
int
w1
,
int
w2
,
int
style1
,
int
style2
,
int
style1
,
int
style2
,
int
layer_no_via
,
int
via_w
,
int
via_holew
,
int
dir
,
int
layer_no_via
,
int
via_w
,
int
via_holew
,
int
dir
,
int
crosshair
)
int
crosshair
)
{
{
return
0
;
return
0
;
}
}
int
CDisplayList
::
StartDraggingArc
(
CDC
*
pDC
,
int
style
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
CDisplayList
::
StartDraggingArc
(
CDC
*
pDC
,
int
style
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
layer
,
int
w
,
int
crosshair
)
int
layer
,
int
w
,
int
crosshair
)
{
{
return
0
;
return
0
;
}
}
polygon/freepcbDisplayList.h
View file @
e126042b
// DisplayList.h : header file for CDisplayList class
// DisplayList.h : header file for CDisplayList class
//
//
#ifndef FP_DISPLAY_LIST_H
#ifndef FP_DISPLAY_LIST_H
#define FP_DISPLAY_LIST_H
#define FP_DISPLAY_LIST_H
//#define DL_MAX_LAYERS 32
//#define DL_MAX_LAYERS 32
#define DL_MAGIC 2674
#define DL_MAGIC 2674
#define PCBU_PER_WU 25400 // conversion from PCB units to world units
#define PCBU_PER_WU 25400 // conversion from PCB units to world units
// graphics element types
// graphics element types
enum
enum
{
{
DL_NONE
=
0
,
DL_NONE
=
0
,
DL_LINE
,
// line segment with round end-caps
DL_LINE
,
// line segment with round end-caps
DL_CIRC
,
// filled circle
DL_CIRC
,
// filled circle
DL_HOLLOW_CIRC
,
// circle outline
DL_HOLLOW_CIRC
,
// circle outline
DL_DONUT
,
// annulus
DL_DONUT
,
// annulus
DL_SQUARE
,
// filled square
DL_SQUARE
,
// filled square
DL_RECT
,
// filled rectangle
DL_RECT
,
// filled rectangle
DL_RRECT
,
// filled rounded rectangle
DL_RRECT
,
// filled rounded rectangle
DL_OVAL
,
// filled oval
DL_OVAL
,
// filled oval
DL_OCTAGON
,
// filled octagon
DL_OCTAGON
,
// filled octagon
DL_HOLE
,
// hole, shown as circle
DL_HOLE
,
// hole, shown as circle
DL_HOLLOW_RECT
,
// rectangle outline
DL_HOLLOW_RECT
,
// rectangle outline
DL_RECT_X
,
// rectangle outline with X
DL_RECT_X
,
// rectangle outline with X
DL_POINT
,
// shape to highlight a point
DL_POINT
,
// shape to highlight a point
DL_ARC_CW
,
// arc with clockwise curve
DL_ARC_CW
,
// arc with clockwise curve
DL_ARC_CCW
,
// arc with counter-clockwise curve
DL_ARC_CCW
,
// arc with counter-clockwise curve
DL_X
// X
DL_X
// X
};
};
// dragging line shapes
// dragging line shapes
enum
enum
{
{
DS_NONE
=
0
,
DS_NONE
=
0
,
DS_LINE_VERTEX
,
// vertex between two lines
DS_LINE_VERTEX
,
// vertex between two lines
DS_LINE
,
// line
DS_LINE
,
// line
DS_ARC_STRAIGHT
,
// straight line (used when drawing polylines)
DS_ARC_STRAIGHT
,
// straight line (used when drawing polylines)
DS_ARC_CW
,
// clockwise arc (used when drawing polylines)
DS_ARC_CW
,
// clockwise arc (used when drawing polylines)
DS_ARC_CCW
// counterclockwise arc (used when drawing polylines)
DS_ARC_CCW
// counterclockwise arc (used when drawing polylines)
};
};
// styles of line segment when dragging line or line vertex
// styles of line segment when dragging line or line vertex
enum
enum
{
{
DSS_STRAIGHT
=
100
,
// straight line
DSS_STRAIGHT
=
100
,
// straight line
DSS_ARC_CW
,
// clockwise arc
DSS_ARC_CW
,
// clockwise arc
DSS_ARC_CCW
// counterclockwise arc
DSS_ARC_CCW
// counterclockwise arc
};
};
// inflection modes for DS_LINE and DS_LINE_VERTEX
// inflection modes for DS_LINE and DS_LINE_VERTEX
enum
enum
{
{
IM_NONE
=
0
,
IM_NONE
=
0
,
IM_90_45
,
IM_90_45
,
IM_45_90
,
IM_45_90
,
IM_90
IM_90
};
};
class
CDisplayList
;
class
CDisplayList
;
// this structure contains an element of the display list
// this structure contains an element of the display list
class
dl_element
class
dl_element
{
{
friend
class
CDisplayList
;
friend
class
CDisplayList
;
public
:
public
:
CDisplayList
*
dlist
;
CDisplayList
*
dlist
;
int
magic
;
int
magic
;
dl_element
*
prev
;
dl_element
*
prev
;
dl_element
*
next
;
dl_element
*
next
;
id
m_id
;
// identifier (see ids.h)
id
m_id
;
// identifier (see ids.h)
void
*
ptr
;
// pointer to object drawing this element
void
*
ptr
;
// pointer to object drawing this element
int
gtype
;
// type of primitive
int
gtype
;
// type of primitive
int
visible
;
// 0 to hide
int
visible
;
// 0 to hide
//private:
//private:
int
sel_vert
;
// for selection rectangles, 1 if part is vertical
int
sel_vert
;
// for selection rectangles, 1 if part is vertical
int
w
;
// width (for round or square shapes)
int
w
;
// width (for round or square shapes)
int
holew
;
// hole width (for round holes)
int
holew
;
// hole width (for round holes)
int
x_org
,
y_org
;
// x origin (for rotation, reflection, etc.)
int
x_org
,
y_org
;
// x origin (for rotation, reflection, etc.)
int
x
,
y
;
// starting or center position of element
int
x
,
y
;
// starting or center position of element
int
xf
,
yf
;
// opposite corner (for rectangle or line)
int
xf
,
yf
;
// opposite corner (for rectangle or line)
int
radius
;
// radius of corners for DL_RRECT
int
radius
;
// radius of corners for DL_RRECT
int
layer
;
// layer to draw on
int
layer
;
// layer to draw on
int
orig_layer
;
// for elements on highlight layer,
int
orig_layer
;
// for elements on highlight layer,
// the original layer, the highlight will
// the original layer, the highlight will
// only be drawn if this layer is visible
// only be drawn if this layer is visible
};
};
class
CDisplayList
class
CDisplayList
{
{
private
:
private
:
// display-list parameters for each layer
// display-list parameters for each layer
dl_element
m_start
[
MAX_LAYERS
],
m_end
[
MAX_LAYERS
];
dl_element
m_start
[
MAX_LAYERS
],
m_end
[
MAX_LAYERS
];
int
m_rgb
[
MAX_LAYERS
][
3
];
// layer colors
int
m_rgb
[
MAX_LAYERS
][
3
];
// layer colors
BOOL
m_vis
[
MAX_LAYERS
];
// layer visibility flags
BOOL
m_vis
[
MAX_LAYERS
];
// layer visibility flags
int
m_layer_in_order
[
MAX_LAYERS
];
// array of layers in draw order
int
m_layer_in_order
[
MAX_LAYERS
];
// array of layers in draw order
int
m_order_for_layer
[
MAX_LAYERS
];
// draw order for each layer
int
m_order_for_layer
[
MAX_LAYERS
];
// draw order for each layer
// window parameters
// window parameters
int
m_pcbu_per_wu
;
// i.e. nm per world unit
int
m_pcbu_per_wu
;
// i.e. nm per world unit
CRect
m_client_r
;
// client rect (pixels)
CRect
m_client_r
;
// client rect (pixels)
CRect
m_screen_r
;
// client rect (screen coords)
CRect
m_screen_r
;
// client rect (screen coords)
int
m_pane_org_x
;
// left border of drawing pane (pixels)
int
m_pane_org_x
;
// left border of drawing pane (pixels)
int
m_pane_org_y
;
// bottom border of drawing pane (pixels)
int
m_pane_org_y
;
// bottom border of drawing pane (pixels)
int
m_bottom_pane_h
;
// height of bottom pane
int
m_bottom_pane_h
;
// height of bottom pane
CDC
*
memDC
;
// pointer to memory DC
CDC
*
memDC
;
// pointer to memory DC
double
m_scale
;
// world units per pixel
double
m_scale
;
// world units per pixel
int
m_org_x
;
// world x-coord of left side of screen (world units)
int
m_org_x
;
// world x-coord of left side of screen (world units)
int
m_org_y
;
// world y-coord of bottom of screen (world units)
int
m_org_y
;
// world y-coord of bottom of screen (world units)
int
m_max_x
;
// world x_coord of right side of screen (world units)
int
m_max_x
;
// world x_coord of right side of screen (world units)
int
m_max_y
;
// world y_coord of top of screen (world units)
int
m_max_y
;
// world y_coord of top of screen (world units)
int
w_ext_x
,
w_ext_y
;
// window extents (world units)
int
w_ext_x
,
w_ext_y
;
// window extents (world units)
int
v_ext_x
,
v_ext_y
;
// viewport extents (pixels)
int
v_ext_x
,
v_ext_y
;
// viewport extents (pixels)
double
m_wu_per_pixel_x
;
// ratio w_ext_x/v_ext_x (world units per pixel)
double
m_wu_per_pixel_x
;
// ratio w_ext_x/v_ext_x (world units per pixel)
double
m_wu_per_pixel_y
;
// ratio w_ext_y/v_ext_y (world units per pixel)
double
m_wu_per_pixel_y
;
// ratio w_ext_y/v_ext_y (world units per pixel)
double
m_pcbu_per_pixel_x
;
double
m_pcbu_per_pixel_x
;
double
m_pcbu_per_pixel_y
;
double
m_pcbu_per_pixel_y
;
// general dragging parameters
// general dragging parameters
int
m_drag_angle
;
// angle of rotation of selection rectangle (starts at 0)
int
m_drag_angle
;
// angle of rotation of selection rectangle (starts at 0)
int
m_drag_side
;
// 0 = no change, 1 = switch to opposite
int
m_drag_side
;
// 0 = no change, 1 = switch to opposite
int
m_drag_vert
;
// 1 if item being dragged is a vertical part
int
m_drag_vert
;
// 1 if item being dragged is a vertical part
// parameters for dragging polyline sides and trace segments
// parameters for dragging polyline sides and trace segments
// that can be modified while dragging
// that can be modified while dragging
int
m_drag_flag
;
// 1 if dragging something
int
m_drag_flag
;
// 1 if dragging something
int
m_drag_shape
;
// shape
int
m_drag_shape
;
// shape
int
m_last_drag_shape
;
// last shape drawn
int
m_last_drag_shape
;
// last shape drawn
int
m_drag_x
;
// last cursor position for dragged shape
int
m_drag_x
;
// last cursor position for dragged shape
int
m_drag_y
;
int
m_drag_y
;
int
m_drag_xi
;
// start of rubberband drag line
int
m_drag_xi
;
// start of rubberband drag line
int
m_drag_yi
;
int
m_drag_yi
;
int
m_drag_xf
;
// end of rubberband drag line
int
m_drag_xf
;
// end of rubberband drag line
int
m_drag_yf
;
int
m_drag_yf
;
int
m_drag_layer_1
;
// line layer
int
m_drag_layer_1
;
// line layer
int
m_drag_w1
;
// line width
int
m_drag_w1
;
// line width
int
m_drag_style1
;
// line style
int
m_drag_style1
;
// line style
int
m_inflection_mode
;
// inflection mode
int
m_inflection_mode
;
// inflection mode
int
m_last_inflection_mode
;
// last mode drawn
int
m_last_inflection_mode
;
// last mode drawn
// extra parameters when dragging vertex between 2 line segments
// extra parameters when dragging vertex between 2 line segments
int
m_drag_style2
;
int
m_drag_style2
;
int
m_drag_layer_2
;
int
m_drag_layer_2
;
int
m_drag_w2
;
int
m_drag_w2
;
// parameters used to draw leading via if necessary
// parameters used to draw leading via if necessary
int
m_drag_layer_no_via
;
int
m_drag_layer_no_via
;
int
m_drag_via_w
;
int
m_drag_via_w
;
int
m_drag_via_holew
;
int
m_drag_via_holew
;
int
m_drag_via_drawn
;
int
m_drag_via_drawn
;
// arrays of lines and ratlines being dragged
// arrays of lines and ratlines being dragged
// these can be rotated and flipped while being dragged
// these can be rotated and flipped while being dragged
int
m_drag_layer
;
// layer
int
m_drag_layer
;
// layer
int
m_drag_max_lines
;
// max size of array for line segments
int
m_drag_max_lines
;
// max size of array for line segments
int
m_drag_num_lines
;
// number of line segments to drag
int
m_drag_num_lines
;
// number of line segments to drag
CPoint
*
m_drag_line_pt
;
// array of relative coords for line endpoints
CPoint
*
m_drag_line_pt
;
// array of relative coords for line endpoints
int
m_drag_max_ratlines
;
// max size of ratline array
int
m_drag_max_ratlines
;
// max size of ratline array
int
m_drag_num_ratlines
;
// number of ratlines to drag
int
m_drag_num_ratlines
;
// number of ratlines to drag
CPoint
*
m_drag_ratline_start_pt
;
// absolute coords for ratline start points
CPoint
*
m_drag_ratline_start_pt
;
// absolute coords for ratline start points
CPoint
*
m_drag_ratline_end_pt
;
// relative coords for ratline endpoints
CPoint
*
m_drag_ratline_end_pt
;
// relative coords for ratline endpoints
int
m_drag_ratline_width
;
int
m_drag_ratline_width
;
// cursor parameters
// cursor parameters
int
m_cross_hairs
;
// 0 = none, 1 = cross-hairs, 2 = diagonals
int
m_cross_hairs
;
// 0 = none, 1 = cross-hairs, 2 = diagonals
CPoint
m_cross_left
,
m_cross_right
,
m_cross_top
,
m_cross_bottom
;
// end-points
CPoint
m_cross_left
,
m_cross_right
,
m_cross_top
,
m_cross_bottom
;
// end-points
CPoint
m_cross_topleft
,
m_cross_topright
,
m_cross_botleft
,
m_cross_botright
;
CPoint
m_cross_topleft
,
m_cross_topright
,
m_cross_botleft
,
m_cross_botright
;
// grid
// grid
int
m_visual_grid_on
;
int
m_visual_grid_on
;
double
m_visual_grid_spacing
;
// in world units
double
m_visual_grid_spacing
;
// in world units
public
:
public
:
CDisplayList
(
int
pcbu_per_wu
);
CDisplayList
(
int
pcbu_per_wu
);
~
CDisplayList
();
~
CDisplayList
();
void
SetVisibleGrid
(
BOOL
on
,
double
grid
);
void
SetVisibleGrid
(
BOOL
on
,
double
grid
);
void
SetMapping
(
CRect
*
client_r
,
CRect
*
screen_r
,
int
pane_org_x
,
int
pane_bottom_h
,
double
scale
,
int
org_x
,
int
org_y
);
void
SetMapping
(
CRect
*
client_r
,
CRect
*
screen_r
,
int
pane_org_x
,
int
pane_bottom_h
,
double
scale
,
int
org_x
,
int
org_y
);
void
SetDCToWorldCoords
(
CDC
*
pDC
,
CDC
*
mDC
,
int
pcbu_org_x
,
int
pcbu_org_y
);
void
SetDCToWorldCoords
(
CDC
*
pDC
,
CDC
*
mDC
,
int
pcbu_org_x
,
int
pcbu_org_y
);
void
SetLayerRGB
(
int
layer
,
int
r
,
int
g
,
int
b
);
void
SetLayerRGB
(
int
layer
,
int
r
,
int
g
,
int
b
);
void
SetLayerVisible
(
int
layer
,
BOOL
vis
);
void
SetLayerVisible
(
int
layer
,
BOOL
vis
);
void
SetLayerDrawOrder
(
int
layer
,
int
order
)
void
SetLayerDrawOrder
(
int
layer
,
int
order
)
{
m_layer_in_order
[
order
]
=
layer
;
m_order_for_layer
[
layer
]
=
order
;
};
{
m_layer_in_order
[
order
]
=
layer
;
m_order_for_layer
[
layer
]
=
order
;
};
dl_element
*
Add
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
dl_element
*
Add
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
radius
=
0
,
int
orig_layer
=
LAY_SELECTION
);
int
radius
=
0
,
int
orig_layer
=
LAY_SELECTION
);
dl_element
*
AddSelector
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
dl_element
*
AddSelector
(
id
id
,
void
*
ptr
,
int
glayer
,
int
gtype
,
int
visible
,
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
radius
=
0
);
int
w
,
int
holew
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
xo
,
int
yo
,
int
radius
=
0
);
void
RemoveAll
();
void
RemoveAll
();
void
RemoveAllFromLayer
(
int
layer
);
void
RemoveAllFromLayer
(
int
layer
);
id
Remove
(
dl_element
*
element
);
id
Remove
(
dl_element
*
element
);
void
Draw
(
CDC
*
pDC
);
void
Draw
(
CDC
*
pDC
);
int
HighLight
(
int
gtype
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
w
,
int
orig_layer
=
LAY_SELECTION
);
int
HighLight
(
int
gtype
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
w
,
int
orig_layer
=
LAY_SELECTION
);
int
CancelHighLight
();
int
CancelHighLight
();
void
*
TestSelect
(
int
x
,
int
y
,
id
*
sel_id
,
int
*
layer
,
void
*
TestSelect
(
int
x
,
int
y
,
id
*
sel_id
,
int
*
layer
,
id
*
exclude_id
=
NULL
,
void
*
exclude_ptr
=
NULL
,
id
*
include_id
=
NULL
,
id
*
exclude_id
=
NULL
,
void
*
exclude_ptr
=
NULL
,
id
*
include_id
=
NULL
,
int
n_include_ids
=
1
);
int
n_include_ids
=
1
);
int
StartDraggingArray
(
CDC
*
pDC
,
int
x
,
int
y
,
int
vert
,
int
layer
,
int
crosshair
=
1
);
int
StartDraggingArray
(
CDC
*
pDC
,
int
x
,
int
y
,
int
vert
,
int
layer
,
int
crosshair
=
1
);
int
StartDraggingRatLine
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
layer
,
int
StartDraggingRatLine
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xf
,
int
yf
,
int
layer
,
int
w
,
int
crosshair
=
1
);
int
w
,
int
crosshair
=
1
);
int
StartDraggingRectangle
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
StartDraggingRectangle
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
vert
,
int
layer
);
int
xf
,
int
yf
,
int
vert
,
int
layer
);
int
StartDraggingLineVertex
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
StartDraggingLineVertex
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xf
,
int
yf
,
int
layer1
,
int
layer2
,
int
w1
,
int
w2
,
int
layer1
,
int
layer2
,
int
w1
,
int
w2
,
int
style1
,
int
style2
,
int
style1
,
int
style2
,
int
layer_no_via
,
int
via_w
,
int
via_holew
,
int
dir
,
int
layer_no_via
,
int
via_w
,
int
via_holew
,
int
dir
,
int
crosshair
);
int
crosshair
);
int
StartDraggingLine
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
layer1
,
int
w
,
int
StartDraggingLine
(
CDC
*
pDC
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
layer1
,
int
w
,
int
layer_no_via
,
int
via_w
,
int
via_holew
,
int
layer_no_via
,
int
via_w
,
int
via_holew
,
int
crosshair
,
int
style
,
int
inflection_mode
);
int
crosshair
,
int
style
,
int
inflection_mode
);
int
StartDraggingArc
(
CDC
*
pDC
,
int
style
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
StartDraggingArc
(
CDC
*
pDC
,
int
style
,
int
x
,
int
y
,
int
xi
,
int
yi
,
int
layer
,
int
w
,
int
crosshair
);
int
layer
,
int
w
,
int
crosshair
);
void
SetDragArcStyle
(
int
style
);
void
SetDragArcStyle
(
int
style
);
void
Drag
(
CDC
*
pDC
,
int
x
,
int
y
);
void
Drag
(
CDC
*
pDC
,
int
x
,
int
y
);
int
StopDragging
();
int
StopDragging
();
void
ChangeRoutingLayer
(
CDC
*
pDC
,
int
layer1
,
int
layer2
,
int
w
);
void
ChangeRoutingLayer
(
CDC
*
pDC
,
int
layer1
,
int
layer2
,
int
w
);
void
IncrementDragAngle
(
CDC
*
pDC
);
void
IncrementDragAngle
(
CDC
*
pDC
);
int
MakeDragLineArray
(
int
num_lines
);
int
MakeDragLineArray
(
int
num_lines
);
int
MakeDragRatlineArray
(
int
num_ratlines
,
int
width
);
int
MakeDragRatlineArray
(
int
num_ratlines
,
int
width
);
int
AddDragLine
(
CPoint
pi
,
CPoint
pf
);
int
AddDragLine
(
CPoint
pi
,
CPoint
pf
);
int
AddDragRatline
(
CPoint
pi
,
CPoint
pf
);
int
AddDragRatline
(
CPoint
pi
,
CPoint
pf
);
int
GetDragAngle
();
int
GetDragAngle
();
void
FlipDragSide
(
CDC
*
pDC
);
void
FlipDragSide
(
CDC
*
pDC
);
int
GetDragSide
();
int
GetDragSide
();
void
SetUpCrosshairs
(
int
type
,
int
x
,
int
y
);
void
SetUpCrosshairs
(
int
type
,
int
x
,
int
y
);
void
SetInflectionMode
(
int
mode
){
m_inflection_mode
=
mode
;
};
void
SetInflectionMode
(
int
mode
){
m_inflection_mode
=
mode
;
};
CPoint
ScreenToPCB
(
CPoint
point
);
CPoint
ScreenToPCB
(
CPoint
point
);
CPoint
PCBToScreen
(
CPoint
point
);
CPoint
PCBToScreen
(
CPoint
point
);
CPoint
WindowToPCB
(
CPoint
point
);
CPoint
WindowToPCB
(
CPoint
point
);
// set element parameters
// set element parameters
void
Set_gtype
(
dl_element
*
el
,
int
gtype
);
void
Set_gtype
(
dl_element
*
el
,
int
gtype
);
void
Set_visible
(
dl_element
*
el
,
int
visible
);
void
Set_visible
(
dl_element
*
el
,
int
visible
);
void
Set_sel_vert
(
dl_element
*
el
,
int
sel_vert
);
void
Set_sel_vert
(
dl_element
*
el
,
int
sel_vert
);
void
Set_w
(
dl_element
*
el
,
int
w
);
void
Set_w
(
dl_element
*
el
,
int
w
);
void
Set_holew
(
dl_element
*
el
,
int
holew
);
void
Set_holew
(
dl_element
*
el
,
int
holew
);
void
Set_x_org
(
dl_element
*
el
,
int
x_org
);
void
Set_x_org
(
dl_element
*
el
,
int
x_org
);
void
Set_y_org
(
dl_element
*
el
,
int
y_org
);
void
Set_y_org
(
dl_element
*
el
,
int
y_org
);
void
Set_x
(
dl_element
*
el
,
int
x
);
void
Set_x
(
dl_element
*
el
,
int
x
);
void
Set_y
(
dl_element
*
el
,
int
y
);
void
Set_y
(
dl_element
*
el
,
int
y
);
void
Set_xf
(
dl_element
*
el
,
int
xf
);
void
Set_xf
(
dl_element
*
el
,
int
xf
);
void
Set_yf
(
dl_element
*
el
,
int
yf
);
void
Set_yf
(
dl_element
*
el
,
int
yf
);
void
Set_id
(
dl_element
*
el
,
id
*
id
);
void
Set_id
(
dl_element
*
el
,
id
*
id
);
void
Set_layer
(
dl_element
*
el
,
int
layer
);
void
Set_layer
(
dl_element
*
el
,
int
layer
);
void
Set_radius
(
dl_element
*
el
,
int
radius
);
void
Set_radius
(
dl_element
*
el
,
int
radius
);
void
Move
(
dl_element
*
el
,
int
dx
,
int
dy
);
void
Move
(
dl_element
*
el
,
int
dx
,
int
dy
);
// get element parameters
// get element parameters
void
*
Get_ptr
(
dl_element
*
el
);
void
*
Get_ptr
(
dl_element
*
el
);
int
Get_gtype
(
dl_element
*
el
);
int
Get_gtype
(
dl_element
*
el
);
int
Get_visible
(
dl_element
*
el
);
int
Get_visible
(
dl_element
*
el
);
int
Get_sel_vert
(
dl_element
*
el
);
int
Get_sel_vert
(
dl_element
*
el
);
int
Get_w
(
dl_element
*
el
);
int
Get_w
(
dl_element
*
el
);
int
Get_holew
(
dl_element
*
el
);
int
Get_holew
(
dl_element
*
el
);
int
Get_x_org
(
dl_element
*
el
);
int
Get_x_org
(
dl_element
*
el
);
int
Get_y_org
(
dl_element
*
el
);
int
Get_y_org
(
dl_element
*
el
);
int
Get_x
(
dl_element
*
el
);
int
Get_x
(
dl_element
*
el
);
int
Get_y
(
dl_element
*
el
);
int
Get_y
(
dl_element
*
el
);
int
Get_xf
(
dl_element
*
el
);
int
Get_xf
(
dl_element
*
el
);
int
Get_yf
(
dl_element
*
el
);
int
Get_yf
(
dl_element
*
el
);
int
Get_radius
(
dl_element
*
el
);
int
Get_radius
(
dl_element
*
el
);
int
Get_layer
(
dl_element
*
el
);
int
Get_layer
(
dl_element
*
el
);
id
Get_id
(
dl_element
*
el
);
id
Get_id
(
dl_element
*
el
);
};
};
#endif // #ifndef FP_DISPLAY_LIST_H
#endif // #ifndef FP_DISPLAY_LIST_H
polygon/freepcb_ids.h
View file @
e126042b
// definition of ID structure used by FreePCB
// definition of ID structure used by FreePCB
//
//
#pragma once
#pragma once
// struct id : this structure is used to identify PCB design elements
// struct id : this structure is used to identify PCB design elements
// such as instances of parts or nets, and their subelements
// such as instances of parts or nets, and their subelements
// Each element will have its own id.
// Each element will have its own id.
// An id is attached to each item of the Display List so that it can
// An id is attached to each item of the Display List so that it can
// be linked back to the PCB design element which drew it.
// be linked back to the PCB design element which drew it.
// These are mainly used to identify items selected by clicking the mouse
// These are mainly used to identify items selected by clicking the mouse
//
//
// In general:
// In general:
// id.type = type of PCB element (e.g. part, net, text)
// id.type = type of PCB element (e.g. part, net, text)
// id.st = subelement type (e.g. part pad, net connection)
// id.st = subelement type (e.g. part pad, net connection)
// id.i = subelement index (zero-based)
// id.i = subelement index (zero-based)
// id.sst = subelement of subelement (e.g. net connection segment)
// id.sst = subelement of subelement (e.g. net connection segment)
// id.ii = subsubelement index (zero-based)
// id.ii = subsubelement index (zero-based)
//
//
// For example, the id for segment 0 of connection 4 of net 12 would be
// For example, the id for segment 0 of connection 4 of net 12 would be
// id = { ID_NET, 12, ID_CONNECT, 4, ID_SEG, 0 };
// id = { ID_NET, 12, ID_CONNECT, 4, ID_SEG, 0 };
//
//
//
//
class
id
{
class
id
{
public
:
public
:
// constructor
// constructor
id
(
int
qt
=
0
,
int
qst
=
0
,
int
qis
=
0
,
int
qsst
=
0
,
int
qiis
=
0
)
id
(
int
qt
=
0
,
int
qst
=
0
,
int
qis
=
0
,
int
qsst
=
0
,
int
qiis
=
0
)
{
type
=
qt
;
st
=
qst
;
i
=
qis
;
sst
=
qsst
;
ii
=
qiis
;
}
{
type
=
qt
;
st
=
qst
;
i
=
qis
;
sst
=
qsst
;
ii
=
qiis
;
}
// operators
// operators
friend
int
operator
==
(
id
id1
,
id
id2
)
friend
int
operator
==
(
id
id1
,
id
id2
)
{
return
(
id1
.
type
==
id2
.
type
{
return
(
id1
.
type
==
id2
.
type
&&
id1
.
st
==
id2
.
st
&&
id1
.
st
==
id2
.
st
&&
id1
.
sst
==
id2
.
sst
&&
id1
.
sst
==
id2
.
sst
&&
id1
.
i
==
id2
.
i
&&
id1
.
i
==
id2
.
i
&&
id1
.
ii
==
id2
.
ii
);
&&
id1
.
ii
==
id2
.
ii
);
}
}
// member functions
// member functions
void
Clear
()
void
Clear
()
{
type
=
0
;
st
=
0
;
i
=
0
;
sst
=
0
;
ii
=
0
;
}
{
type
=
0
;
st
=
0
;
i
=
0
;
sst
=
0
;
ii
=
0
;
}
void
Set
(
int
qt
,
int
qst
=
0
,
int
qis
=
0
,
int
qsst
=
0
,
int
qiis
=
0
)
void
Set
(
int
qt
,
int
qst
=
0
,
int
qis
=
0
,
int
qsst
=
0
,
int
qiis
=
0
)
{
type
=
qt
;
st
=
qst
;
i
=
qis
;
sst
=
qsst
;
ii
=
qiis
;
}
{
type
=
qt
;
st
=
qst
;
i
=
qis
;
sst
=
qsst
;
ii
=
qiis
;
}
// member variables
// member variables
unsigned
int
type
;
// type of element
unsigned
int
type
;
// type of element
unsigned
int
st
;
// type of subelement
unsigned
int
st
;
// type of subelement
unsigned
int
i
;
// index of subelement
unsigned
int
i
;
// index of subelement
unsigned
int
sst
;
// type of subsubelement
unsigned
int
sst
;
// type of subsubelement
unsigned
int
ii
;
// index of subsubelement
unsigned
int
ii
;
// index of subsubelement
};
};
// these are constants used in ids
// these are constants used in ids
// root types
// root types
enum
{
enum
{
ID_NONE
=
0
,
// an undefined type or st (or an error)
ID_NONE
=
0
,
// an undefined type or st (or an error)
ID_BOARD
,
// board outline
ID_BOARD
,
// board outline
ID_PART
,
// part
ID_PART
,
// part
ID_NET
,
// net
ID_NET
,
// net
ID_TEXT
,
// free-standing text
ID_TEXT
,
// free-standing text
ID_DRC
,
// DRC error
ID_DRC
,
// DRC error
ID_SM_CUTOUT
,
// cutout for solder mask
ID_SM_CUTOUT
,
// cutout for solder mask
ID_MULTI
// if multiple selections
ID_MULTI
// if multiple selections
};
};
// subtypes of ID_PART
// subtypes of ID_PART
enum
{
enum
{
ID_PAD
=
1
,
// pad_stack in a part
ID_PAD
=
1
,
// pad_stack in a part
ID_SEL_PAD
,
// selection rectangle for pad_stack in a part
ID_SEL_PAD
,
// selection rectangle for pad_stack in a part
ID_OUTLINE
,
// part outline
ID_OUTLINE
,
// part outline
ID_REF_TXT
,
// text showing ref num for part
ID_REF_TXT
,
// text showing ref num for part
ID_ORIG
,
// part origin
ID_ORIG
,
// part origin
ID_SEL_RECT
,
// selection rectangle for part
ID_SEL_RECT
,
// selection rectangle for part
ID_SEL_REF_TXT
// selection rectangle for ref text
ID_SEL_REF_TXT
// selection rectangle for ref text
};
};
// subtypes of ID_TEXT
// subtypes of ID_TEXT
enum
{
enum
{
ID_SEL_TXT
=
1
,
// selection rectangle
ID_SEL_TXT
=
1
,
// selection rectangle
ID_STROKE
// stroke for text
ID_STROKE
// stroke for text
};
};
// subtypes of ID_NET
// subtypes of ID_NET
enum
{
enum
{
ID_ENTIRE_NET
=
0
,
ID_ENTIRE_NET
=
0
,
ID_CONNECT
,
// connection
ID_CONNECT
,
// connection
ID_AREA
// copper area
ID_AREA
// copper area
};
};
// subtypes of ID_BOARD
// subtypes of ID_BOARD
enum
{
enum
{
ID_BOARD_OUTLINE
=
1
,
ID_BOARD_OUTLINE
=
1
,
};
};
// subsubtypes of ID_NET.ID_CONNECT
// subsubtypes of ID_NET.ID_CONNECT
enum
{
enum
{
ID_ENTIRE_CONNECT
=
0
,
ID_ENTIRE_CONNECT
=
0
,
ID_SEG
,
ID_SEG
,
ID_SEL_SEG
,
ID_SEL_SEG
,
ID_VERTEX
,
ID_VERTEX
,
ID_SEL_VERTEX
,
ID_SEL_VERTEX
,
ID_VIA
ID_VIA
};
};
// subsubtypes of ID_NET.ID_AREA, ID_BOARD.ID_BOARD_OUTLINE, ID_SM_CUTOUT
// subsubtypes of ID_NET.ID_AREA, ID_BOARD.ID_BOARD_OUTLINE, ID_SM_CUTOUT
enum
{
enum
{
ID_SIDE
=
1
,
ID_SIDE
=
1
,
ID_SEL_SIDE
,
ID_SEL_SIDE
,
ID_SEL_CORNER
,
ID_SEL_CORNER
,
ID_HATCH
,
ID_HATCH
,
ID_PIN_X
,
// only used by ID_AREA
ID_PIN_X
,
// only used by ID_AREA
ID_STUB_X
// only used by ID_AREA
ID_STUB_X
// only used by ID_AREA
};
};
// subtypes of ID_DRC
// subtypes of ID_DRC
// for subsubtypes, use types in DesignRules.h
// for subsubtypes, use types in DesignRules.h
enum
{
enum
{
ID_DRE
=
1
,
ID_DRE
=
1
,
ID_SEL_DRE
ID_SEL_DRE
};
};
polygon/math_for_graphics.cpp
View file @
e126042b
// math for graphics utility routines, from FreePCB
// math for graphics utility routines, from FreePCB
using
namespace
std
;
using
namespace
std
;
#include <vector>
#include <vector>
#include <math.h>
#include <math.h>
#include <float.h>
#include <float.h>
#include <limits.h>
#include <limits.h>
#include "defs-macros.h"
#include "defs-macros.h"
#include "PolyLine2Kicad.h"
#include "PolyLine2Kicad.h"
#include "freepcb_ids.h"
#include "freepcb_ids.h"
#include "PolyLine.h"
#include "PolyLine.h"
// function to find inflection-pont to create a "dogleg" of two straight-line segments
// function to find inflection-pont to create a "dogleg" of two straight-line segments
// where one segment is vertical or horizontal and the other is at 45 degrees or 90 degrees
// where one segment is vertical or horizontal and the other is at 45 degrees or 90 degrees
// enter with:
// enter with:
// pi = start point
// pi = start point
// pf = end point
// pf = end point
// mode = IM_90_45 or IM_45_90 or IM_90
// mode = IM_90_45 or IM_45_90 or IM_90
//
//
CPoint
GetInflectionPoint
(
CPoint
pi
,
CPoint
pf
,
int
mode
)
CPoint
GetInflectionPoint
(
CPoint
pi
,
CPoint
pf
,
int
mode
)
{
{
CPoint
p
=
pi
;
CPoint
p
=
pi
;
if
(
mode
==
IM_NONE
)
if
(
mode
==
IM_NONE
)
return
p
;
return
p
;
int
dx
=
pf
.
x
-
pi
.
x
;
int
dx
=
pf
.
x
-
pi
.
x
;
int
dy
=
pf
.
y
-
pi
.
y
;
int
dy
=
pf
.
y
-
pi
.
y
;
if
(
dx
==
0
||
dy
==
0
||
abs
(
dx
)
==
abs
(
dy
)
)
if
(
dx
==
0
||
dy
==
0
||
abs
(
dx
)
==
abs
(
dy
)
)
{
{
// only one segment needed
// only one segment needed
}
}
else
else
{
{
if
(
abs
(
dy
)
>
abs
(
dx
)
)
if
(
abs
(
dy
)
>
abs
(
dx
)
)
{
{
// vertical > horizontal
// vertical > horizontal
if
(
mode
==
IM_90
)
if
(
mode
==
IM_90
)
{
{
p
.
x
=
pi
.
x
;
p
.
x
=
pi
.
x
;
p
.
y
=
pf
.
y
;
p
.
y
=
pf
.
y
;
}
}
else
if
(
mode
==
IM_45_90
||
mode
==
IM_90_45
)
else
if
(
mode
==
IM_45_90
||
mode
==
IM_90_45
)
{
{
int
vert
;
// length of vertical line needed
int
vert
;
// length of vertical line needed
if
(
dy
>
0
)
if
(
dy
>
0
)
vert
=
dy
-
abs
(
dx
);
// positive
vert
=
dy
-
abs
(
dx
);
// positive
else
else
vert
=
dy
+
abs
(
dx
);
// negative
vert
=
dy
+
abs
(
dx
);
// negative
if
(
mode
==
IM_90_45
)
if
(
mode
==
IM_90_45
)
p
.
y
=
pi
.
y
+
vert
;
p
.
y
=
pi
.
y
+
vert
;
else
if
(
mode
==
IM_45_90
)
else
if
(
mode
==
IM_45_90
)
{
{
p
.
y
=
pf
.
y
-
vert
;
p
.
y
=
pf
.
y
-
vert
;
p
.
x
=
pf
.
x
;
p
.
x
=
pf
.
x
;
}
}
}
}
else
else
ASSERT
(
0
);
ASSERT
(
0
);
}
}
else
else
{
{
// horizontal > vertical
// horizontal > vertical
if
(
mode
==
IM_90
)
if
(
mode
==
IM_90
)
{
{
p
.
x
=
pf
.
x
;
p
.
x
=
pf
.
x
;
p
.
y
=
pi
.
y
;
p
.
y
=
pi
.
y
;
}
}
else
if
(
mode
==
IM_45_90
||
mode
==
IM_90_45
)
else
if
(
mode
==
IM_45_90
||
mode
==
IM_90_45
)
{
{
int
hor
;
// length of horizontal line needed
int
hor
;
// length of horizontal line needed
if
(
dx
>
0
)
if
(
dx
>
0
)
hor
=
dx
-
abs
(
dy
);
// positive
hor
=
dx
-
abs
(
dy
);
// positive
else
else
hor
=
dx
+
abs
(
dy
);
// negative
hor
=
dx
+
abs
(
dy
);
// negative
if
(
mode
==
IM_90_45
)
if
(
mode
==
IM_90_45
)
p
.
x
=
pi
.
x
+
hor
;
p
.
x
=
pi
.
x
+
hor
;
else
if
(
mode
==
IM_45_90
)
else
if
(
mode
==
IM_45_90
)
{
{
p
.
x
=
pf
.
x
-
hor
;
p
.
x
=
pf
.
x
-
hor
;
p
.
y
=
pf
.
y
;
p
.
y
=
pf
.
y
;
}
}
}
}
else
else
ASSERT
(
0
);
ASSERT
(
0
);
}
}
}
}
return
p
;
return
p
;
}
}
//
//
// function to rotate a point clockwise about another point
// function to rotate a point clockwise about another point
// currently, angle must be 0, 90, 180 or 270
// currently, angle must be 0, 90, 180 or 270
//
//
void
RotatePoint
(
CPoint
*
p
,
int
angle
,
CPoint
org
)
void
RotatePoint
(
CPoint
*
p
,
int
angle
,
CPoint
org
)
{
{
if
(
angle
==
90
)
if
(
angle
==
90
)
{
{
int
tempy
=
org
.
y
+
(
org
.
x
-
p
->
x
);
int
tempy
=
org
.
y
+
(
org
.
x
-
p
->
x
);
p
->
x
=
org
.
x
+
(
p
->
y
-
org
.
y
);
p
->
x
=
org
.
x
+
(
p
->
y
-
org
.
y
);
p
->
y
=
tempy
;
p
->
y
=
tempy
;
}
}
else
if
(
angle
>
90
)
else
if
(
angle
>
90
)
{
{
for
(
int
i
=
0
;
i
<
(
angle
/
90
);
i
++
)
for
(
int
i
=
0
;
i
<
(
angle
/
90
);
i
++
)
RotatePoint
(
p
,
90
,
org
);
RotatePoint
(
p
,
90
,
org
);
}
}
}
}
// function to rotate a rectangle clockwise about a point
// function to rotate a rectangle clockwise about a point
// angle must be 0, 90, 180 or 270
// angle must be 0, 90, 180 or 270
// on exit, r->top > r.bottom, r.right > r.left
// on exit, r->top > r.bottom, r.right > r.left
//
//
void
RotateRect
(
CRect
*
r
,
int
angle
,
CPoint
org
)
void
RotateRect
(
CRect
*
r
,
int
angle
,
CPoint
org
)
{
{
CRect
tr
;
CRect
tr
;
if
(
angle
==
90
)
if
(
angle
==
90
)
{
{
tr
.
left
=
org
.
x
+
(
r
->
bottom
-
org
.
y
);
tr
.
left
=
org
.
x
+
(
r
->
bottom
-
org
.
y
);
tr
.
right
=
org
.
x
+
(
r
->
top
-
org
.
y
);
tr
.
right
=
org
.
x
+
(
r
->
top
-
org
.
y
);
tr
.
top
=
org
.
y
+
(
org
.
x
-
r
->
right
);
tr
.
top
=
org
.
y
+
(
org
.
x
-
r
->
right
);
tr
.
bottom
=
org
.
y
+
(
org
.
x
-
r
->
left
);
tr
.
bottom
=
org
.
y
+
(
org
.
x
-
r
->
left
);
if
(
tr
.
left
>
tr
.
right
)
if
(
tr
.
left
>
tr
.
right
)
{
{
int
temp
=
tr
.
right
;
int
temp
=
tr
.
right
;
tr
.
left
=
tr
.
right
;
tr
.
left
=
tr
.
right
;
tr
.
left
=
temp
;
tr
.
left
=
temp
;
}
}
if
(
tr
.
left
>
tr
.
right
)
if
(
tr
.
left
>
tr
.
right
)
{
{
int
temp
=
tr
.
right
;
int
temp
=
tr
.
right
;
tr
.
left
=
tr
.
right
;
tr
.
left
=
tr
.
right
;
tr
.
left
=
temp
;
tr
.
left
=
temp
;
}
}
if
(
tr
.
bottom
>
tr
.
top
)
if
(
tr
.
bottom
>
tr
.
top
)
{
{
int
temp
=
tr
.
bottom
;
int
temp
=
tr
.
bottom
;
tr
.
bottom
=
tr
.
top
;
tr
.
bottom
=
tr
.
top
;
tr
.
top
=
temp
;
tr
.
top
=
temp
;
}
}
}
}
else
if
(
angle
>
90
)
else
if
(
angle
>
90
)
{
{
tr
=
*
r
;
tr
=
*
r
;
for
(
int
i
=
0
;
i
<
(
angle
/
90
);
i
++
)
for
(
int
i
=
0
;
i
<
(
angle
/
90
);
i
++
)
RotateRect
(
&
tr
,
90
,
org
);
RotateRect
(
&
tr
,
90
,
org
);
}
}
*
r
=
tr
;
*
r
=
tr
;
}
}
// test for hit on line segment
// test for hit on line segment
// i.e. cursor within a given distance from segment
// i.e. cursor within a given distance from segment
// enter with: x,y = cursor coords
// enter with: x,y = cursor coords
// (xi,yi) and (xf,yf) are the end-points of the line segment
// (xi,yi) and (xf,yf) are the end-points of the line segment
// dist = maximum distance for hit
// dist = maximum distance for hit
//
//
int
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
)
int
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
)
{
{
double
dd
;
double
dd
;
// test for vertical or horizontal segment
// test for vertical or horizontal segment
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
1
;
return
1
;
}
}
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
1
;
return
1
;
}
}
else
else
{
{
// 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
)
)
)
return
1
;
return
1
;
}
}
else
else
{
{
// line segment more horizontal than vertical
// line segment more horizontal than vertical
if
(
dd
<
dist
&&
(
(
xf
>
xi
&&
xp
<
xf
&&
xp
>
xi
)
||
(
xf
<
xi
&&
xp
>
xf
&&
xp
<
xi
)
)
)
if
(
dd
<
dist
&&
(
(
xf
>
xi
&&
xp
<
xf
&&
xp
>
xi
)
||
(
xf
<
xi
&&
xp
>
xf
&&
xp
<
xi
)
)
)
return
1
;
return
1
;
}
}
}
}
return
0
;
// no hit
return
0
;
// no hit
}
}
// find intersection between y = a + bx and y = c + dx;
// find intersection between y = a + bx and y = c + dx;
//
//
int
FindLineIntersection
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x
,
double
*
y
)
int
FindLineIntersection
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x
,
double
*
y
)
{
{
*
x
=
(
c
-
a
)
/
(
b
-
d
);
*
x
=
(
c
-
a
)
/
(
b
-
d
);
*
y
=
a
+
b
*
(
*
x
);
*
y
=
a
+
b
*
(
*
x
);
return
0
;
return
0
;
}
}
// 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
;
xxf
=
xi
;
xxf
=
xi
;
yyi
=
yf
;
yyi
=
yf
;
yyf
=
yi
;
yyf
=
yi
;
}
}
else
else
{
{
xxi
=
xi
;
xxi
=
xi
;
xxf
=
xf
;
xxf
=
xf
;
yyi
=
yi
;
yyi
=
yi
;
yyf
=
yf
;
yyf
=
yf
;
}
}
// find center and radii of ellipse
// find center and radii of ellipse
double
xo
,
yo
;
double
xo
,
yo
;
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
.
X
=
xo
;
el
->
Center
.
Y
=
yo
;
el
->
Center
.
Y
=
yo
;
el
->
xrad
=
abs
(
xf
-
xi
);
el
->
xrad
=
abs
(
xf
-
xi
);
el
->
yrad
=
abs
(
yf
-
yi
);
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
// returns number of intersections found (max of 2)
// returns number of intersections found (max of 2)
// 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
)
{
{
// two identical arcs intersect
// two identical arcs intersect
if
(
style
==
style2
&&
xi
==
xi2
&&
yi
==
yi2
&&
xf
==
xf2
&&
yf
==
yf2
)
if
(
style
==
style2
&&
xi
==
xi2
&&
yi
==
yi2
&&
xf
==
xf2
&&
yf
==
yf2
)
{
{
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
;
}
}
}
}
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
;
xr
[
0
]
=
x
;
yr
[
0
]
=
y
;
yr
[
0
]
=
y
;
iret
=
1
;
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
++
;
}
}
}
}
}
}
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
++
;
}
}
}
}
}
}
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)
// return 0 if no intersection
// return 0 if no intersection
// returns 1 or 2 if intersections found
// returns 1 or 2 if intersections found
// sets coords of intersections in *x1, *y1, *x2, *y2
// sets coords of intersections in *x1, *y1, *x2, *y2
// 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
,
yy
;
double
xx
,
yy
;
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
)
{
{
// non-vertical segment, get intersection
// non-vertical segment, get intersection
if
(
style
==
CPolyLine
::
STRAIGHT
||
yf
==
yi
)
if
(
style
==
CPolyLine
::
STRAIGHT
||
yf
==
yi
)
{
{
// 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
)
{
{
// horizontal line
// horizontal line
if
(
(
xx
>=
xi
&&
xx
>
xf
)
||
(
xx
<=
xi
&&
xx
<
xf
)
)
if
(
(
xx
>=
xi
&&
xx
>
xf
)
||
(
xx
<=
xi
&&
xx
<
xf
)
)
return
0
;
return
0
;
}
}
else
else
{
{
// oblique line
// oblique line
if
(
(
xx
>=
xi
&&
xx
>
xf
)
||
(
xx
<=
xi
&&
xx
<
xf
)
if
(
(
xx
>=
xi
&&
xx
>
xf
)
||
(
xx
<=
xi
&&
xx
<
xf
)
||
(
yy
>
yi
&&
yy
>
yf
)
||
(
yy
<
yi
&&
yy
<
yf
)
)
||
(
yy
>
yi
&&
yy
>
yf
)
||
(
yy
<
yi
&&
yy
<
yf
)
)
return
0
;
return
0
;
}
}
}
}
else
if
(
style
==
CPolyLine
::
ARC_CW
||
style
==
CPolyLine
::
ARC_CCW
)
else
if
(
style
==
CPolyLine
::
ARC_CW
||
style
==
CPolyLine
::
ARC_CCW
)
{
{
// 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
;
xxf
=
xi
;
xxf
=
xi
;
yyi
=
yf
;
yyi
=
yf
;
yyf
=
yi
;
yyf
=
yi
;
}
}
else
else
{
{
xxi
=
xi
;
xxi
=
xi
;
xxf
=
xf
;
xxf
=
xf
;
yyi
=
yi
;
yyi
=
yi
;
yyf
=
yf
;
yyf
=
yf
;
}
}
// find center and radii of ellipse
// find center and radii of ellipse
double
xo
,
yo
,
rx
,
ry
;
double
xo
,
yo
,
rx
,
ry
;
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
)
);
rx
=
fabs
(
(
double
)(
xxi
-
xxf
)
);
ry
=
fabs
(
(
double
)(
yyi
-
yyf
)
);
ry
=
fabs
(
(
double
)(
yyi
-
yyf
)
);
bool
test
;
bool
test
;
double
xx1
,
xx2
,
yy1
,
yy2
,
aa
;
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
;
xx1
=
a
;
xx1
=
a
;
xx2
=
a
;
xx2
=
a
;
}
}
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
ASSERT
(
0
);
ASSERT
(
0
);
}
}
else
else
{
{
// vertical line segment
// vertical line segment
if
(
bVert
)
if
(
bVert
)
return
0
;
return
0
;
xx
=
xi
;
xx
=
xi
;
yy
=
a
+
b
*
xx
;
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
;
}
}
// Test for intersection of line segments
// Test for intersection of line segments
// If lines are parallel, returns false
// If lines are parallel, returns false
// If true, returns intersection coords in x, y
// If true, returns intersection coords in x, y
// 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)
// and coords on nearest point in one of the segments in (x,y)
// and coords on nearest point in one of the segments in (x,y)
//
//
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
)
{
{
// both segments are vertical, can't intersect
// both segments are vertical, can't intersect
}
}
else
if
(
y1i
==
y1f
&&
y2i
==
y2f
)
else
if
(
y1i
==
y1f
&&
y2i
==
y2f
)
{
{
// both segments are horizontal, can't intersect
// both segments are horizontal, can't intersect
}
}
else
if
(
x1i
==
x1f
&&
y2i
==
y2f
)
else
if
(
x1i
==
x1f
&&
y2i
==
y2f
)
{
{
// first seg. vertical, second horizontal, see if they cross
// first seg. vertical, second horizontal, see if they cross
if
(
InRange
(
x1i
,
x2i
,
x2f
)
if
(
InRange
(
x1i
,
x2i
,
x2f
)
&&
InRange
(
y2i
,
y1i
,
y1f
)
)
&&
InRange
(
y2i
,
y1i
,
y1f
)
)
{
{
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
;
}
}
}
}
else
if
(
y1i
==
y1f
&&
x2i
==
x2f
)
else
if
(
y1i
==
y1f
&&
x2i
==
x2f
)
{
{
// first seg. horizontal, second vertical, see if they cross
// first seg. horizontal, second vertical, see if they cross
if
(
InRange
(
y1i
,
y2i
,
y2f
)
if
(
InRange
(
y1i
,
y2i
,
y2f
)
&&
InRange
(
x2i
,
x1i
,
x1f
)
)
&&
InRange
(
x2i
,
x1i
,
x1f
)
)
{
{
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
;
}
}
}
}
else
if
(
x1i
==
x1f
)
else
if
(
x1i
==
x1f
)
{
{
// 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
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
&
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
=
x1
;
*
x
=
x1
;
if
(
y
)
if
(
y
)
*
y
=
y1
;
*
y
=
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
}
}
else
if
(
y1i
==
y1f
)
else
if
(
y1i
==
y1f
)
{
{
// 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
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x1i
,
y1i
,
x1f
,
y1f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
&
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
=
x1
;
*
x
=
x1
;
if
(
y
)
if
(
y
)
*
y
=
y1
;
*
y
=
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
}
}
else
if
(
x2i
==
x2f
)
else
if
(
x2i
==
x2f
)
{
{
// 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
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
&
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
=
x1
;
*
x
=
x1
;
if
(
y
)
if
(
y
)
*
y
=
y1
;
*
y
=
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
}
}
else
if
(
y2i
==
y2f
)
else
if
(
y2i
==
y2f
)
{
{
// 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
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
&
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
=
x1
;
*
x
=
x1
;
if
(
y
)
if
(
y
)
*
y
=
y1
;
*
y
=
y1
;
if
(
d
)
if
(
d
)
*
d
=
0.0
;
*
d
=
0.0
;
return
true
;
return
true
;
}
}
}
}
}
}
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
;
double
x1
,
y1
,
x2
,
y2
;
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
int
test
=
FindLineSegmentIntersection
(
a
,
b
,
x2i
,
y2i
,
x2f
,
y2f
,
CPolyLine
::
STRAIGHT
,
&
x1
,
&
y1
,
&
x2
,
&
y2
);
&
x1
,
&
y1
,
&
x2
,
&
y2
);
// both segments oblique
// both segments oblique
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
=
x1
;
*
x
=
x1
;
if
(
y
)
if
(
y
)
*
y
=
y1
;
*
y
=
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
xx
=
x1i
;
double
yy
=
y1i
;
double
yy
=
y1i
;
double
dd
=
GetPointToLineSegmentDistance
(
x1f
,
y1f
,
x2i
,
y2i
,
x2f
,
y2f
);
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
=
xx
;
*
x
=
xx
;
if
(
y
)
if
(
y
)
*
y
=
yy
;
*
y
=
yy
;
if
(
d
)
if
(
d
)
*
d
=
dist
;
*
d
=
dist
;
return
false
;
return
false
;
}
}
// quicksort algorithm
// quicksort algorithm
// sorts array numbers[], also moves elements of another array index[]
// sorts array numbers[], also moves elements of another array index[]
//
//
#define Q3WAY
#define Q3WAY
void
quickSort
(
int
numbers
[],
int
index
[],
int
array_size
)
void
quickSort
(
int
numbers
[],
int
index
[],
int
array_size
)
{
{
#ifdef Q3WAY
#ifdef Q3WAY
q_sort_3way
(
numbers
,
index
,
0
,
array_size
-
1
);
q_sort_3way
(
numbers
,
index
,
0
,
array_size
-
1
);
#else
#else
q_sort
(
numbers
,
index
,
0
,
array_size
-
1
);
q_sort
(
numbers
,
index
,
0
,
array_size
-
1
);
#endif
#endif
}
}
// standard quicksort
// standard quicksort
//
//
void
q_sort
(
int
numbers
[],
int
index
[],
int
left
,
int
right
)
void
q_sort
(
int
numbers
[],
int
index
[],
int
left
,
int
right
)
{
{
int
pivot
,
pivot_index
,
l_hold
,
r_hold
;
int
pivot
,
pivot_index
,
l_hold
,
r_hold
;
l_hold
=
left
;
l_hold
=
left
;
r_hold
=
right
;
r_hold
=
right
;
pivot
=
numbers
[
left
];
pivot
=
numbers
[
left
];
pivot_index
=
index
[
left
];
pivot_index
=
index
[
left
];
while
(
left
<
right
)
while
(
left
<
right
)
{
{
while
((
numbers
[
right
]
>=
pivot
)
&&
(
left
<
right
))
while
((
numbers
[
right
]
>=
pivot
)
&&
(
left
<
right
))
right
--
;
right
--
;
if
(
left
!=
right
)
if
(
left
!=
right
)
{
{
numbers
[
left
]
=
numbers
[
right
];
numbers
[
left
]
=
numbers
[
right
];
index
[
left
]
=
index
[
right
];
index
[
left
]
=
index
[
right
];
left
++
;
left
++
;
}
}
while
((
numbers
[
left
]
<=
pivot
)
&&
(
left
<
right
))
while
((
numbers
[
left
]
<=
pivot
)
&&
(
left
<
right
))
left
++
;
left
++
;
if
(
left
!=
right
)
if
(
left
!=
right
)
{
{
numbers
[
right
]
=
numbers
[
left
];
numbers
[
right
]
=
numbers
[
left
];
index
[
right
]
=
index
[
left
];
index
[
right
]
=
index
[
left
];
right
--
;
right
--
;
}
}
}
}
numbers
[
left
]
=
pivot
;
numbers
[
left
]
=
pivot
;
index
[
left
]
=
pivot_index
;
index
[
left
]
=
pivot_index
;
pivot
=
left
;
pivot
=
left
;
left
=
l_hold
;
left
=
l_hold
;
right
=
r_hold
;
right
=
r_hold
;
if
(
left
<
pivot
)
if
(
left
<
pivot
)
q_sort
(
numbers
,
index
,
left
,
pivot
-
1
);
q_sort
(
numbers
,
index
,
left
,
pivot
-
1
);
if
(
right
>
pivot
)
if
(
right
>
pivot
)
q_sort
(
numbers
,
index
,
pivot
+
1
,
right
);
q_sort
(
numbers
,
index
,
pivot
+
1
,
right
);
}
}
// 3-way quicksort...useful where there are duplicate values
// 3-way quicksort...useful where there are duplicate values
//
//
void
q_sort_3way
(
int
a
[],
int
b
[],
int
l
,
int
r
)
void
q_sort_3way
(
int
a
[],
int
b
[],
int
l
,
int
r
)
{
{
#define EXCH(i,j) {int temp=a[i]; a[i]=a[j]; a[j]=temp; temp=b[i]; b[i]=b[j]; b[j]=temp;}
#define EXCH(i,j) {int temp=a[i]; a[i]=a[j]; a[j]=temp; temp=b[i]; b[i]=b[j]; b[j]=temp;}
int
i
=
l
-
1
;
int
i
=
l
-
1
;
int
j
=
r
;
int
j
=
r
;
int
p
=
l
-
1
;
int
p
=
l
-
1
;
int
q
=
r
;
int
q
=
r
;
int
v
=
a
[
r
];
int
v
=
a
[
r
];
if
(
r
<=
l
)
if
(
r
<=
l
)
return
;
return
;
for
(;;)
for
(;;)
{
{
while
(
a
[
++
i
]
<
v
);
while
(
a
[
++
i
]
<
v
);
while
(
v
<
a
[
--
j
]
)
while
(
v
<
a
[
--
j
]
)
if
(
j
==
1
)
if
(
j
==
1
)
break
;
break
;
if
(
i
>=
j
)
if
(
i
>=
j
)
break
;
break
;
EXCH
(
i
,
j
);
EXCH
(
i
,
j
);
if
(
a
[
i
]
==
v
)
if
(
a
[
i
]
==
v
)
{
{
p
++
;
p
++
;
EXCH
(
p
,
i
);
EXCH
(
p
,
i
);
}
}
if
(
v
==
a
[
j
]
)
if
(
v
==
a
[
j
]
)
{
{
q
--
;
q
--
;
EXCH
(
j
,
q
);
EXCH
(
j
,
q
);
}
}
}
}
EXCH
(
i
,
r
);
EXCH
(
i
,
r
);
j
=
i
-
1
;
j
=
i
-
1
;
i
=
i
+
1
;
i
=
i
+
1
;
for
(
int
k
=
l
;
k
<
p
;
k
++
,
j
--
)
for
(
int
k
=
l
;
k
<
p
;
k
++
,
j
--
)
EXCH
(
k
,
j
);
EXCH
(
k
,
j
);
for
(
int
k
=
r
-
1
;
k
>
q
;
k
--
,
i
++
)
for
(
int
k
=
r
-
1
;
k
>
q
;
k
--
,
i
++
)
EXCH
(
i
,
k
);
EXCH
(
i
,
k
);
q_sort_3way
(
a
,
b
,
l
,
j
);
q_sort_3way
(
a
,
b
,
l
,
j
);
q_sort_3way
(
a
,
b
,
i
,
r
);
q_sort_3way
(
a
,
b
,
i
,
r
);
}
}
// solves quadratic equation
// solves quadratic equation
// i.e. ax**2 + bx + c = 0
// i.e. ax**2 + bx + c = 0
// 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
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
);
root
=
sqrt
(
root
);
*
x1
=
(
-
b
+
root
)
/
(
2.0
*
a
);
*
x1
=
(
-
b
+
root
)
/
(
2.0
*
a
);
*
x2
=
(
-
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
);
}
}
#if 0
#if 0
// draw a straight line or an arc between xi,yi and xf,yf
// draw a straight line or an arc between xi,yi and xf,yf
//
//
void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, bool bMeta )
void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, bool bMeta )
{
{
int xi, yi, xf, yf;
int xi, yi, xf, yf;
if( shape == DL_LINE || xxi == xxf || yyi == yyf )
if( shape == DL_LINE || xxi == xxf || yyi == yyf )
{
{
// draw straight line
// draw straight line
pDC->MoveTo( xxi, yyi );
pDC->MoveTo( xxi, yyi );
pDC->LineTo( xxf, yyf );
pDC->LineTo( xxf, yyf );
}
}
else if( shape == DL_ARC_CCW || shape == DL_ARC_CW )
else if( shape == DL_ARC_CCW || shape == DL_ARC_CW )
{
{
// set endpoints so we can always draw counter-clockwise arc
// set endpoints so we can always draw counter-clockwise arc
if( shape == DL_ARC_CW )
if( shape == DL_ARC_CW )
{
{
xi = xxf;
xi = xxf;
yi = yyf;
yi = yyf;
xf = xxi;
xf = xxi;
yf = yyi;
yf = yyi;
}
}
else
else
{
{
xi = xxi;
xi = xxi;
yi = yyi;
yi = yyi;
xf = xxf;
xf = xxf;
yf = yyf;
yf = yyf;
}
}
pDC->MoveTo( xi, yi );
pDC->MoveTo( xi, yi );
if( xf > xi && yf > yi )
if( xf > xi && yf > yi )
{
{
// quadrant 1
// quadrant 1
int w = (xf-xi)*2;
int w = (xf-xi)*2;
int h = (yf-yi)*2;
int h = (yf-yi)*2;
if( !bMeta )
if( !bMeta )
pDC->Arc( xf-w, yi+h, xf, yi,
pDC->Arc( xf-w, yi+h, xf, yi,
xi, yi, xf, yf );
xi, yi, xf, yf );
else
else
pDC->Arc( xf-w, yi, xf, yi+h,
pDC->Arc( xf-w, yi, xf, yi+h,
xf, yf, xi, yi );
xf, yf, xi, yi );
}
}
else if( xf < xi && yf > yi )
else if( xf < xi && yf > yi )
{
{
// quadrant 2
// quadrant 2
int w = -(xf-xi)*2;
int w = -(xf-xi)*2;
int h = (yf-yi)*2;
int h = (yf-yi)*2;
if( !bMeta )
if( !bMeta )
pDC->Arc( xi-w, yf, xi, yf-h,
pDC->Arc( xi-w, yf, xi, yf-h,
xi, yi, xf, yf );
xi, yi, xf, yf );
else
else
pDC->Arc( xi-w, yf-h, xi, yf,
pDC->Arc( xi-w, yf-h, xi, yf,
xf, yf, xi, yi );
xf, yf, xi, yi );
}
}
else if( xf < xi && yf < yi )
else if( xf < xi && yf < yi )
{
{
// quadrant 3
// quadrant 3
int w = -(xf-xi)*2;
int w = -(xf-xi)*2;
int h = -(yf-yi)*2;
int h = -(yf-yi)*2;
if( !bMeta )
if( !bMeta )
pDC->Arc( xf, yi, xf+w, yi-h,
pDC->Arc( xf, yi, xf+w, yi-h,
xi, yi, xf, yf );
xi, yi, xf, yf );
else
else
pDC->Arc( xf, yi-h, xf+w, yi,
pDC->Arc( xf, yi-h, xf+w, yi,
xf, yf, xi, yi );
xf, yf, xi, yi );
}
}
else if( xf > xi && yf < yi )
else if( xf > xi && yf < yi )
{
{
// quadrant 4
// quadrant 4
int w = (xf-xi)*2;
int w = (xf-xi)*2;
int h = -(yf-yi)*2;
int h = -(yf-yi)*2;
if( !bMeta )
if( !bMeta )
pDC->Arc( xi, yf+h, xi+w, yf,
pDC->Arc( xi, yf+h, xi+w, yf,
xi, yi, xf, yf );
xi, yi, xf, yf );
else
else
pDC->Arc( xi, yf, xi+w, yf+h,
pDC->Arc( xi, yf, xi+w, yf+h,
xf, yf, xi, yi );
xf, yf, xi, yi );
}
}
pDC->MoveTo( xxf, yyf );
pDC->MoveTo( xxf, yyf );
}
}
else
else
ASSERT(0); // oops
ASSERT(0); // oops
}
}
#endif
#endif
// Get arrays of circles, rects and line segments to represent pad
// Get arrays of circles, rects and line segments to represent pad
// for purposes of drawing pad or calculating clearances
// for purposes of drawing pad or calculating clearances
// margins of circles and line segments represent pad outline
// margins of circles and line segments represent pad outline
// circles and rects are used to find points inside pad
// circles and rects are used to find points inside pad
//
//
void
GetPadElements
(
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
radius
,
int
angle
,
void
GetPadElements
(
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
radius
,
int
angle
,
int
*
nr
,
my_rect
r
[],
int
*
nc
,
my_circle
c
[],
int
*
ns
,
my_seg
s
[]
)
int
*
nr
,
my_rect
r
[],
int
*
nc
,
my_circle
c
[],
int
*
ns
,
my_seg
s
[]
)
{
{
*
nc
=
0
;
*
nc
=
0
;
*
nr
=
0
;
*
nr
=
0
;
*
ns
=
0
;
*
ns
=
0
;
if
(
type
==
PAD_ROUND
)
if
(
type
==
PAD_ROUND
)
{
{
*
nc
=
1
;
*
nc
=
1
;
c
[
0
]
=
my_circle
(
x
,
y
,
wid
/
2
);
c
[
0
]
=
my_circle
(
x
,
y
,
wid
/
2
);
return
;
return
;
}
}
if
(
type
==
PAD_SQUARE
)
if
(
type
==
PAD_SQUARE
)
{
{
*
nr
=
1
;
*
nr
=
1
;
r
[
0
]
=
my_rect
(
x
-
wid
/
2
,
y
-
wid
/
2
,
x
+
wid
/
2
,
y
+
wid
/
2
);
r
[
0
]
=
my_rect
(
x
-
wid
/
2
,
y
-
wid
/
2
,
x
+
wid
/
2
,
y
+
wid
/
2
);
*
ns
=
4
;
*
ns
=
4
;
s
[
0
]
=
my_seg
(
x
-
wid
/
2
,
y
+
wid
/
2
,
x
+
wid
/
2
,
y
+
wid
/
2
);
// top
s
[
0
]
=
my_seg
(
x
-
wid
/
2
,
y
+
wid
/
2
,
x
+
wid
/
2
,
y
+
wid
/
2
);
// top
s
[
1
]
=
my_seg
(
x
-
wid
/
2
,
y
-
wid
/
2
,
x
+
wid
/
2
,
y
-
wid
/
2
);
// bottom
s
[
1
]
=
my_seg
(
x
-
wid
/
2
,
y
-
wid
/
2
,
x
+
wid
/
2
,
y
-
wid
/
2
);
// bottom
s
[
2
]
=
my_seg
(
x
-
wid
/
2
,
y
-
wid
/
2
,
x
-
wid
/
2
,
y
+
wid
/
2
);
// left
s
[
2
]
=
my_seg
(
x
-
wid
/
2
,
y
-
wid
/
2
,
x
-
wid
/
2
,
y
+
wid
/
2
);
// left
s
[
3
]
=
my_seg
(
x
+
wid
/
2
,
y
-
wid
/
2
,
x
+
wid
/
2
,
y
+
wid
/
2
);
// right
s
[
3
]
=
my_seg
(
x
+
wid
/
2
,
y
-
wid
/
2
,
x
+
wid
/
2
,
y
+
wid
/
2
);
// right
return
;
return
;
}
}
if
(
type
==
PAD_OCTAGON
)
if
(
type
==
PAD_OCTAGON
)
{
{
const
double
pi
=
3.14159265359
;
const
double
pi
=
3.14159265359
;
*
nc
=
1
;
// circle represents inside of polygon
*
nc
=
1
;
// circle represents inside of polygon
c
[
0
]
=
my_circle
(
x
,
y
,
wid
/
2
);
c
[
0
]
=
my_circle
(
x
,
y
,
wid
/
2
);
*
ns
=
8
;
// now create sides of polygon
*
ns
=
8
;
// now create sides of polygon
double
theta
=
pi
/
8.0
;
double
theta
=
pi
/
8.0
;
double
radius
=
0.5
*
(
double
)
wid
/
cos
(
theta
);
double
radius
=
0.5
*
(
double
)
wid
/
cos
(
theta
);
double
last_x
=
x
+
radius
*
cos
(
theta
);
double
last_x
=
x
+
radius
*
cos
(
theta
);
double
last_y
=
y
+
radius
*
sin
(
theta
);
double
last_y
=
y
+
radius
*
sin
(
theta
);
for
(
int
is
=
0
;
is
<
8
;
is
++
)
for
(
int
is
=
0
;
is
<
8
;
is
++
)
{
{
theta
+=
pi
/
4.0
;
theta
+=
pi
/
4.0
;
double
dx
=
x
+
radius
*
cos
(
theta
);
double
dx
=
x
+
radius
*
cos
(
theta
);
double
dy
=
y
+
radius
*
sin
(
theta
);
double
dy
=
y
+
radius
*
sin
(
theta
);
s
[
is
]
=
my_seg
(
last_x
,
last_y
,
x
,
y
);
s
[
is
]
=
my_seg
(
last_x
,
last_y
,
x
,
y
);
last_x
=
dx
;
last_x
=
dx
;
last_y
=
dy
;
last_y
=
dy
;
}
}
return
;
return
;
}
}
//
//
int
h
;
int
h
;
int
v
;
int
v
;
if
(
angle
==
90
||
angle
==
270
)
if
(
angle
==
90
||
angle
==
270
)
{
{
h
=
wid
;
h
=
wid
;
v
=
len
;
v
=
len
;
}
}
else
else
{
{
v
=
wid
;
v
=
wid
;
h
=
len
;
h
=
len
;
}
}
if
(
type
==
PAD_RECT
)
if
(
type
==
PAD_RECT
)
{
{
*
nr
=
1
;
*
nr
=
1
;
r
[
0
]
=
my_rect
(
x
-
h
/
2
,
y
-
v
/
2
,
x
+
h
/
2
,
y
+
v
/
2
);
r
[
0
]
=
my_rect
(
x
-
h
/
2
,
y
-
v
/
2
,
x
+
h
/
2
,
y
+
v
/
2
);
*
ns
=
4
;
*
ns
=
4
;
s
[
0
]
=
my_seg
(
x
-
h
/
2
,
y
+
v
/
2
,
x
+
h
/
2
,
y
+
v
/
2
);
// top
s
[
0
]
=
my_seg
(
x
-
h
/
2
,
y
+
v
/
2
,
x
+
h
/
2
,
y
+
v
/
2
);
// top
s
[
1
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
,
x
+
h
/
2
,
y
-
v
/
2
);
// bottom
s
[
1
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
,
x
+
h
/
2
,
y
-
v
/
2
);
// bottom
s
[
2
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
,
x
-
h
/
2
,
y
+
v
/
2
);
// left
s
[
2
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
,
x
-
h
/
2
,
y
+
v
/
2
);
// left
s
[
3
]
=
my_seg
(
x
+
h
/
2
,
y
-
v
/
2
,
x
+
h
/
2
,
y
+
v
/
2
);
// right
s
[
3
]
=
my_seg
(
x
+
h
/
2
,
y
-
v
/
2
,
x
+
h
/
2
,
y
+
v
/
2
);
// right
return
;
return
;
}
}
if
(
type
==
PAD_RRECT
)
if
(
type
==
PAD_RRECT
)
{
{
*
nc
=
4
;
*
nc
=
4
;
c
[
0
]
=
my_circle
(
x
-
h
/
2
+
radius
,
y
-
v
/
2
+
radius
,
radius
);
// bottom left circle
c
[
0
]
=
my_circle
(
x
-
h
/
2
+
radius
,
y
-
v
/
2
+
radius
,
radius
);
// bottom left circle
c
[
1
]
=
my_circle
(
x
+
h
/
2
-
radius
,
y
-
v
/
2
+
radius
,
radius
);
// bottom right circle
c
[
1
]
=
my_circle
(
x
+
h
/
2
-
radius
,
y
-
v
/
2
+
radius
,
radius
);
// bottom right circle
c
[
2
]
=
my_circle
(
x
-
h
/
2
+
radius
,
y
+
v
/
2
-
radius
,
radius
);
// top left circle
c
[
2
]
=
my_circle
(
x
-
h
/
2
+
radius
,
y
+
v
/
2
-
radius
,
radius
);
// top left circle
c
[
3
]
=
my_circle
(
x
+
h
/
2
-
radius
,
y
+
v
/
2
-
radius
,
radius
);
// top right circle
c
[
3
]
=
my_circle
(
x
+
h
/
2
-
radius
,
y
+
v
/
2
-
radius
,
radius
);
// top right circle
*
ns
=
4
;
*
ns
=
4
;
s
[
0
]
=
my_seg
(
x
-
h
/
2
+
radius
,
y
+
v
/
2
,
x
+
h
/
2
-
radius
,
y
+
v
/
2
);
// top
s
[
0
]
=
my_seg
(
x
-
h
/
2
+
radius
,
y
+
v
/
2
,
x
+
h
/
2
-
radius
,
y
+
v
/
2
);
// top
s
[
1
]
=
my_seg
(
x
-
h
/
2
+
radius
,
y
-
v
/
2
,
x
+
h
/
2
-
radius
,
y
+
v
/
2
);
// bottom
s
[
1
]
=
my_seg
(
x
-
h
/
2
+
radius
,
y
-
v
/
2
,
x
+
h
/
2
-
radius
,
y
+
v
/
2
);
// bottom
s
[
2
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
+
radius
,
x
-
h
/
2
,
y
+
v
/
2
-
radius
);
// left
s
[
2
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
+
radius
,
x
-
h
/
2
,
y
+
v
/
2
-
radius
);
// left
s
[
3
]
=
my_seg
(
x
+
h
/
2
,
y
-
v
/
2
+
radius
,
x
+
h
/
2
,
y
+
v
/
2
-
radius
);
// right
s
[
3
]
=
my_seg
(
x
+
h
/
2
,
y
-
v
/
2
+
radius
,
x
+
h
/
2
,
y
+
v
/
2
-
radius
);
// right
return
;
return
;
}
}
if
(
type
==
PAD_OVAL
)
if
(
type
==
PAD_OVAL
)
{
{
if
(
h
>
v
)
if
(
h
>
v
)
{
{
// horizontal
// horizontal
*
nc
=
2
;
*
nc
=
2
;
c
[
0
]
=
my_circle
(
x
-
h
/
2
+
v
/
2
,
y
,
v
/
2
);
// left circle
c
[
0
]
=
my_circle
(
x
-
h
/
2
+
v
/
2
,
y
,
v
/
2
);
// left circle
c
[
1
]
=
my_circle
(
x
+
h
/
2
-
v
/
2
,
y
,
v
/
2
);
// right circle
c
[
1
]
=
my_circle
(
x
+
h
/
2
-
v
/
2
,
y
,
v
/
2
);
// right circle
*
nr
=
1
;
*
nr
=
1
;
r
[
0
]
=
my_rect
(
x
-
h
/
2
+
v
/
2
,
y
-
v
/
2
,
x
+
h
/
2
-
v
/
2
,
y
+
v
/
2
);
r
[
0
]
=
my_rect
(
x
-
h
/
2
+
v
/
2
,
y
-
v
/
2
,
x
+
h
/
2
-
v
/
2
,
y
+
v
/
2
);
*
ns
=
2
;
*
ns
=
2
;
s
[
0
]
=
my_seg
(
x
-
h
/
2
+
v
/
2
,
y
+
v
/
2
,
x
+
h
/
2
-
v
/
2
,
y
+
v
/
2
);
// top
s
[
0
]
=
my_seg
(
x
-
h
/
2
+
v
/
2
,
y
+
v
/
2
,
x
+
h
/
2
-
v
/
2
,
y
+
v
/
2
);
// top
s
[
1
]
=
my_seg
(
x
-
h
/
2
+
v
/
2
,
y
-
v
/
2
,
x
+
h
/
2
-
v
/
2
,
y
-
v
/
2
);
// bottom
s
[
1
]
=
my_seg
(
x
-
h
/
2
+
v
/
2
,
y
-
v
/
2
,
x
+
h
/
2
-
v
/
2
,
y
-
v
/
2
);
// bottom
}
}
else
else
{
{
// vertical
// vertical
*
nc
=
2
;
*
nc
=
2
;
c
[
0
]
=
my_circle
(
x
,
y
+
v
/
2
-
h
/
2
,
h
/
2
);
// top circle
c
[
0
]
=
my_circle
(
x
,
y
+
v
/
2
-
h
/
2
,
h
/
2
);
// top circle
c
[
1
]
=
my_circle
(
x
,
y
-
v
/
2
+
h
/
2
,
h
/
2
);
// bottom circle
c
[
1
]
=
my_circle
(
x
,
y
-
v
/
2
+
h
/
2
,
h
/
2
);
// bottom circle
*
nr
=
1
;
*
nr
=
1
;
r
[
0
]
=
my_rect
(
x
-
h
/
2
,
y
-
v
/
2
+
h
/
2
,
x
+
h
/
2
,
y
+
v
/
2
-
h
/
2
);
r
[
0
]
=
my_rect
(
x
-
h
/
2
,
y
-
v
/
2
+
h
/
2
,
x
+
h
/
2
,
y
+
v
/
2
-
h
/
2
);
*
ns
=
2
;
*
ns
=
2
;
s
[
0
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
+
h
/
2
,
x
-
h
/
2
,
y
+
v
/
2
-
h
/
2
);
// left
s
[
0
]
=
my_seg
(
x
-
h
/
2
,
y
-
v
/
2
+
h
/
2
,
x
-
h
/
2
,
y
+
v
/
2
-
h
/
2
);
// left
s
[
1
]
=
my_seg
(
x
+
h
/
2
,
y
-
v
/
2
+
h
/
2
,
x
+
h
/
2
,
y
+
v
/
2
-
h
/
2
);
// left
s
[
1
]
=
my_seg
(
x
+
h
/
2
,
y
-
v
/
2
+
h
/
2
,
x
+
h
/
2
,
y
+
v
/
2
-
h
/
2
);
// left
}
}
return
;
return
;
}
}
ASSERT
(
0
);
ASSERT
(
0
);
}
}
// Find distance from a staright line segment to a pad
// Find distance from a staright line segment to a pad
//
//
int
GetClearanceBetweenSegmentAndPad
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
w
,
int
GetClearanceBetweenSegmentAndPad
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
w
,
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
radius
,
int
angle
)
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
radius
,
int
angle
)
{
{
if
(
type
==
PAD_NONE
)
if
(
type
==
PAD_NONE
)
return
INT_MAX
;
return
INT_MAX
;
else
else
{
{
int
nc
,
nr
,
ns
;
int
nc
,
nr
,
ns
;
my_circle
c
[
4
];
my_circle
c
[
4
];
my_rect
r
[
2
];
my_rect
r
[
2
];
my_seg
s
[
8
];
my_seg
s
[
8
];
GetPadElements
(
type
,
x
,
y
,
wid
,
len
,
radius
,
angle
,
GetPadElements
(
type
,
x
,
y
,
wid
,
len
,
radius
,
angle
,
&
nr
,
r
,
&
nc
,
c
,
&
ns
,
s
);
&
nr
,
r
,
&
nc
,
c
,
&
ns
,
s
);
// first test for endpoints of line segment in rectangle
// first test for endpoints of line segment in rectangle
for
(
int
ir
=
0
;
ir
<
nr
;
ir
++
)
for
(
int
ir
=
0
;
ir
<
nr
;
ir
++
)
{
{
if
(
x1
>=
r
[
ir
].
xlo
&&
x1
<=
r
[
ir
].
xhi
&&
y1
>=
r
[
ir
].
ylo
&&
y1
<=
r
[
ir
].
yhi
)
if
(
x1
>=
r
[
ir
].
xlo
&&
x1
<=
r
[
ir
].
xhi
&&
y1
>=
r
[
ir
].
ylo
&&
y1
<=
r
[
ir
].
yhi
)
return
0
;
return
0
;
if
(
x2
>=
r
[
ir
].
xlo
&&
x2
<=
r
[
ir
].
xhi
&&
y2
>=
r
[
ir
].
ylo
&&
y2
<=
r
[
ir
].
yhi
)
if
(
x2
>=
r
[
ir
].
xlo
&&
x2
<=
r
[
ir
].
xhi
&&
y2
>=
r
[
ir
].
ylo
&&
y2
<=
r
[
ir
].
yhi
)
return
0
;
return
0
;
}
}
// now get distance from elements of pad outline
// now get distance from elements of pad outline
int
dist
=
INT_MAX
;
int
dist
=
INT_MAX
;
for
(
int
ic
=
0
;
ic
<
nc
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
nc
;
ic
++
)
{
{
int
d
=
GetPointToLineSegmentDistance
(
c
[
ic
].
x
,
c
[
ic
].
y
,
x1
,
y1
,
x2
,
y2
)
-
c
[
ic
].
r
-
w
/
2
;
int
d
=
GetPointToLineSegmentDistance
(
c
[
ic
].
x
,
c
[
ic
].
y
,
x1
,
y1
,
x2
,
y2
)
-
c
[
ic
].
r
-
w
/
2
;
dist
=
min
(
dist
,
d
);
dist
=
min
(
dist
,
d
);
}
}
for
(
int
is
=
0
;
is
<
ns
;
is
++
)
for
(
int
is
=
0
;
is
<
ns
;
is
++
)
{
{
double
d
;
double
d
;
TestForIntersectionOfStraightLineSegments
(
s
[
is
].
xi
,
s
[
is
].
yi
,
s
[
is
].
xf
,
s
[
is
].
yf
,
TestForIntersectionOfStraightLineSegments
(
s
[
is
].
xi
,
s
[
is
].
yi
,
s
[
is
].
xf
,
s
[
is
].
yf
,
x1
,
y1
,
x2
,
y2
,
NULL
,
NULL
,
&
d
);
x1
,
y1
,
x2
,
y2
,
NULL
,
NULL
,
&
d
);
d
-=
w
/
2
;
d
-=
w
/
2
;
dist
=
min
(
dist
,
d
);
dist
=
min
(
dist
,
d
);
}
}
return
max
(
0
,
dist
);
return
max
(
0
,
dist
);
}
}
}
}
// Get clearance between 2 segments
// Get clearance between 2 segments
// Returns point in segment closest to other segment in x, y
// Returns point in segment closest to other segment in x, y
// 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
,
dd
-
w1
/
2
-
w2
/
2
);
int
d
=
max
(
0
,
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
=
xr
[
0
];
*
x
=
xr
[
0
];
if
(
y
)
if
(
y
)
*
y
=
yr
[
0
];
*
y
=
yr
[
0
];
return
0.0
;
return
0.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
,
yi
,
xf
,
yf
;
int
xi
,
yi
,
xf
,
yf
;
if
(
style2
==
CPolyLine
::
STRAIGHT
)
if
(
style2
==
CPolyLine
::
STRAIGHT
)
{
{
// style1 = arc, style2 = straight
// style1 = arc, style2 = straight
MakeEllipseFromArc
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
&
el1
);
MakeEllipseFromArc
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
&
el1
);
xi
=
x2i
;
xi
=
x2i
;
yi
=
y2i
;
yi
=
y2i
;
xf
=
x2f
;
xf
=
x2f
;
yf
=
y2f
;
yf
=
y2f
;
bArcs
=
false
;
bArcs
=
false
;
}
}
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
;
}
}
else
else
{
{
// style1 = arc, style2 = arc
// style1 = arc, style2 = arc
MakeEllipseFromArc
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
&
el1
);
MakeEllipseFromArc
(
x1i
,
y1i
,
x1f
,
y1f
,
style1
,
&
el1
);
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
)
ASSERT
(
0
);
ASSERT
(
0
);
if
(
bArcs
&&
el2
.
theta2
>
el2
.
theta1
)
if
(
bArcs
&&
el2
.
theta2
>
el2
.
theta1
)
ASSERT
(
0
);
ASSERT
(
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_start
=
el1
.
theta1
;
double
s_end
=
el1
.
theta2
;
double
s_end
=
el1
.
theta2
;
double
s_start2
=
th1
;
double
s_start2
=
th1
;
double
s_end2
=
th2
;
double
s_end2
=
th2
;
double
dmin
=
DBL_MAX
;
double
dmin
=
DBL_MAX
;
double
xmin
,
ymin
,
smin
,
smin2
;
double
xmin
,
ymin
,
smin
,
smin2
;
int
nsteps
=
NSTEPS
;
int
nsteps
=
NSTEPS
;
int
nsteps2
=
NSTEPS
;
int
nsteps2
=
NSTEPS
;
double
step
=
(
s_start
-
s_end
)
/
(
nsteps
-
1
);
double
step
=
(
s_start
-
s_end
)
/
(
nsteps
-
1
);
double
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
double
step2
=
(
s_start2
-
s_end2
)
/
(
nsteps2
-
1
);
while
(
(
step
*
max
(
el1
.
xrad
,
el1
.
yrad
))
>
0.1
*
NM_PER_MIL
while
(
(
step
*
max
(
el1
.
xrad
,
el1
.
yrad
))
>
0.1
*
NM_PER_MIL
&&
(
step2
*
len2
)
>
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
)
if
(
i
<
nsteps
-
1
)
s
=
s_start
-
i
*
step
;
s
=
s_start
-
i
*
step
;
else
else
s
=
s_end
;
s
=
s_end
;
double
x
=
el1
.
Center
.
X
+
el1
.
xrad
*
cos
(
s
);
double
x
=
el1
.
Center
.
X
+
el1
.
xrad
*
cos
(
s
);
double
y
=
el1
.
Center
.
Y
+
el1
.
yrad
*
sin
(
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
)
if
(
i2
<
nsteps2
-
1
)
s2
=
s_start2
-
i2
*
step2
;
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
(
x
,
y
,
x2
,
y2
);
double
d
=
Distance
(
x
,
y
,
x2
,
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
=
xmin
;
*
x
=
xmin
;
if
(
y
)
if
(
y
)
*
y
=
ymin
;
*
y
=
ymin
;
return
max
(
0
,
dmin
-
w1
/
2
-
w2
/
2
);
// allow for widths
return
max
(
0
,
dmin
-
w1
/
2
-
w2
/
2
);
// allow for widths
}
}
// Find clearance between pads
// Find clearance between pads
// For each pad:
// For each pad:
// type = PAD_ROUND, PAD_SQUARE, etc.
// type = PAD_ROUND, PAD_SQUARE, etc.
// x, y = center position
// x, y = center position
// w, l = width and length
// w, l = width and length
// r = corner radius
// r = corner radius
// angle = 0 or 90 (if 0, pad length is along x-axis)
// angle = 0 or 90 (if 0, pad length is along x-axis)
//
//
int
GetClearanceBetweenPads
(
int
type1
,
int
x1
,
int
y1
,
int
w1
,
int
l1
,
int
r1
,
int
angle1
,
int
GetClearanceBetweenPads
(
int
type1
,
int
x1
,
int
y1
,
int
w1
,
int
l1
,
int
r1
,
int
angle1
,
int
type2
,
int
x2
,
int
y2
,
int
w2
,
int
l2
,
int
r2
,
int
angle2
)
int
type2
,
int
x2
,
int
y2
,
int
w2
,
int
l2
,
int
r2
,
int
angle2
)
{
{
if
(
type1
==
PAD_NONE
)
if
(
type1
==
PAD_NONE
)
return
INT_MAX
;
return
INT_MAX
;
if
(
type2
==
PAD_NONE
)
if
(
type2
==
PAD_NONE
)
return
INT_MAX
;
return
INT_MAX
;
int
dist
=
INT_MAX
;
int
dist
=
INT_MAX
;
int
nr
,
nc
,
ns
,
nrr
,
ncc
,
nss
;
int
nr
,
nc
,
ns
,
nrr
,
ncc
,
nss
;
my_rect
r
[
2
],
rr
[
2
];
my_rect
r
[
2
],
rr
[
2
];
my_circle
c
[
4
],
cc
[
4
];
my_circle
c
[
4
],
cc
[
4
];
my_seg
s
[
8
],
ss
[
8
];
my_seg
s
[
8
],
ss
[
8
];
GetPadElements
(
type1
,
x1
,
y1
,
w1
,
l1
,
r1
,
angle1
,
GetPadElements
(
type1
,
x1
,
y1
,
w1
,
l1
,
r1
,
angle1
,
&
nr
,
r
,
&
nc
,
c
,
&
ns
,
s
);
&
nr
,
r
,
&
nc
,
c
,
&
ns
,
s
);
GetPadElements
(
type2
,
x2
,
y2
,
w2
,
l2
,
r2
,
angle2
,
GetPadElements
(
type2
,
x2
,
y2
,
w2
,
l2
,
r2
,
angle2
,
&
nrr
,
rr
,
&
ncc
,
cc
,
&
nss
,
ss
);
&
nrr
,
rr
,
&
ncc
,
cc
,
&
nss
,
ss
);
// now find distance from every element of pad1 to every element of pad2
// now find distance from every element of pad1 to every element of pad2
for
(
int
ic
=
0
;
ic
<
nc
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
nc
;
ic
++
)
{
{
for
(
int
icc
=
0
;
icc
<
ncc
;
icc
++
)
for
(
int
icc
=
0
;
icc
<
ncc
;
icc
++
)
{
{
int
d
=
Distance
(
c
[
ic
].
x
,
c
[
ic
].
y
,
cc
[
icc
].
x
,
cc
[
icc
].
y
)
int
d
=
Distance
(
c
[
ic
].
x
,
c
[
ic
].
y
,
cc
[
icc
].
x
,
cc
[
icc
].
y
)
-
c
[
ic
].
r
-
cc
[
icc
].
r
;
-
c
[
ic
].
r
-
cc
[
icc
].
r
;
dist
=
min
(
dist
,
d
);
dist
=
min
(
dist
,
d
);
}
}
for
(
int
iss
=
0
;
iss
<
nss
;
iss
++
)
for
(
int
iss
=
0
;
iss
<
nss
;
iss
++
)
{
{
int
d
=
GetPointToLineSegmentDistance
(
c
[
ic
].
x
,
c
[
ic
].
y
,
int
d
=
GetPointToLineSegmentDistance
(
c
[
ic
].
x
,
c
[
ic
].
y
,
ss
[
iss
].
xi
,
ss
[
iss
].
yi
,
ss
[
iss
].
xf
,
ss
[
iss
].
yf
)
-
c
[
ic
].
r
;
ss
[
iss
].
xi
,
ss
[
iss
].
yi
,
ss
[
iss
].
xf
,
ss
[
iss
].
yf
)
-
c
[
ic
].
r
;
dist
=
min
(
dist
,
d
);
dist
=
min
(
dist
,
d
);
}
}
}
}
for
(
int
is
=
0
;
is
<
ns
;
is
++
)
for
(
int
is
=
0
;
is
<
ns
;
is
++
)
{
{
for
(
int
icc
=
0
;
icc
<
ncc
;
icc
++
)
for
(
int
icc
=
0
;
icc
<
ncc
;
icc
++
)
{
{
int
d
=
GetPointToLineSegmentDistance
(
cc
[
icc
].
x
,
cc
[
icc
].
y
,
int
d
=
GetPointToLineSegmentDistance
(
cc
[
icc
].
x
,
cc
[
icc
].
y
,
s
[
is
].
xi
,
s
[
is
].
yi
,
s
[
is
].
xf
,
s
[
is
].
yf
)
-
cc
[
icc
].
r
;
s
[
is
].
xi
,
s
[
is
].
yi
,
s
[
is
].
xf
,
s
[
is
].
yf
)
-
cc
[
icc
].
r
;
dist
=
min
(
dist
,
d
);
dist
=
min
(
dist
,
d
);
}
}
for
(
int
iss
=
0
;
iss
<
nss
;
iss
++
)
for
(
int
iss
=
0
;
iss
<
nss
;
iss
++
)
{
{
double
d
;
double
d
;
TestForIntersectionOfStraightLineSegments
(
s
[
is
].
xi
,
s
[
is
].
yi
,
s
[
is
].
xf
,
s
[
is
].
yf
,
TestForIntersectionOfStraightLineSegments
(
s
[
is
].
xi
,
s
[
is
].
yi
,
s
[
is
].
xf
,
s
[
is
].
yf
,
ss
[
iss
].
xi
,
ss
[
iss
].
yi
,
ss
[
iss
].
xf
,
ss
[
iss
].
yf
,
NULL
,
NULL
,
&
d
);
ss
[
iss
].
xi
,
ss
[
iss
].
yi
,
ss
[
iss
].
xf
,
ss
[
iss
].
yf
,
NULL
,
NULL
,
&
d
);
dist
=
min
(
dist
,
d
);
dist
=
min
(
dist
,
d
);
}
}
}
}
return
max
(
dist
,
0
);
return
max
(
dist
,
0
);
}
}
// Get min. distance from (x,y) to line y = a + bx
// Get min. distance from (x,y) to line y = a + bx
// 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
,
xp
,
yp
);
return
Distance
(
x
,
y
,
xp
,
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
)
/***********************************************************************************/
/***********************************************************************************/
/** Function GetPointToLineSegmentDistance
/** Function GetPointToLineSegmentDistance
* Get distance between line segment and point
* Get distance between line segment and point
* @param x,y = point
* @param x,y = point
* @param xi,yi and xf,yf = the end-points of the line segment
* @param xi,yi and xf,yf = the end-points of the line segment
* @return the distance
* @return the distance
*/
*/
{
{
// test for vertical or horizontal segment
// test for vertical or horizontal segment
if
(
xf
==
xi
)
if
(
xf
==
xi
)
{
{
// vertical line segment
// vertical line segment
if
(
InRange
(
y
,
yi
,
yf
)
)
if
(
InRange
(
y
,
yi
,
yf
)
)
return
abs
(
x
-
xi
);
return
abs
(
x
-
xi
);
else
else
return
min
(
Distance
(
x
,
y
,
xi
,
yi
),
Distance
(
x
,
y
,
xf
,
yf
)
);
return
min
(
Distance
(
x
,
y
,
xi
,
yi
),
Distance
(
x
,
y
,
xf
,
yf
)
);
}
}
else
if
(
yf
==
yi
)
else
if
(
yf
==
yi
)
{
{
// horizontal line segment
// horizontal line segment
if
(
InRange
(
x
,
xi
,
xf
)
)
if
(
InRange
(
x
,
xi
,
xf
)
)
return
abs
(
y
-
yi
);
return
abs
(
y
-
yi
);
else
else
return
min
(
Distance
(
x
,
y
,
xi
,
yi
),
Distance
(
x
,
y
,
xf
,
yf
)
);
return
min
(
Distance
(
x
,
y
,
xi
,
yi
),
Distance
(
x
,
y
,
xf
,
yf
)
);
}
}
else
else
{
{
// 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
,
xp
,
yp
);
return
Distance
(
x
,
y
,
xp
,
yp
);
else
else
return
min
(
Distance
(
x
,
y
,
xi
,
yi
),
Distance
(
x
,
y
,
xf
,
yf
)
);
return
min
(
Distance
(
x
,
y
,
xi
,
yi
),
Distance
(
x
,
y
,
xf
,
yf
)
);
}
}
}
}
// 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
;
}
}
else
else
{
{
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
d
;
d
=
sqrt
(
(
double
)(
x1
-
x2
)
*
(
x1
-
x2
)
+
(
double
)(
y1
-
y2
)
*
(
y1
-
y2
)
);
d
=
sqrt
(
(
double
)(
x1
-
x2
)
*
(
x1
-
x2
)
+
(
double
)(
y1
-
y2
)
*
(
y1
-
y2
)
);
if
(
d
>
INT_MAX
||
d
<
INT_MIN
)
if
(
d
>
INT_MAX
||
d
<
INT_MIN
)
ASSERT
(
0
);
ASSERT
(
0
);
return
(
int
)
d
;
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
)
ASSERT
(
0
);
ASSERT
(
0
);
if
(
el2
->
theta2
>
el2
->
theta1
)
if
(
el2
->
theta2
>
el2
->
theta1
)
ASSERT
(
0
);
ASSERT
(
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
xscale
=
1.0
/
el1
->
xrad
;
double
yscale
=
1.0
/
el1
->
yrad
;
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
,
th_prev
;
double
d_prev
,
th_prev
;
double
th_interp
;
double
th_interp
;
double
th1
;
double
th1
;
int
n
=
0
;
int
n
=
0
;
for
(
int
i
=
0
;
i
<
NSTEPS
;
i
++
)
for
(
int
i
=
0
;
i
<
NSTEPS
;
i
++
)
{
{
double
theta
;
double
theta
;
if
(
i
<
NSTEPS
-
1
)
if
(
i
<
NSTEPS
-
1
)
theta
=
el2
->
theta1
-
i
*
step
;
theta
=
el2
->
theta1
-
i
*
step
;
else
else
theta
=
el2
->
theta2
;
theta
=
el2
->
theta2
;
double
x
=
xo
+
xr
*
cos
(
theta
);
double
x
=
xo
+
xr
*
cos
(
theta
);
double
y
=
yo
+
yr
*
sin
(
theta
);
double
y
=
yo
+
yr
*
sin
(
theta
);
double
d
=
1.0
-
sqrt
(
x
*
x
+
y
*
y
);
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
)
ASSERT
(
0
);
ASSERT
(
0
);
}
}
}
}
}
}
d_prev
=
d
;
d_prev
=
d
;
th_prev
=
theta
;
th_prev
=
theta
;
}
}
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
)
ASSERT
(
0
);
ASSERT
(
0
);
if
(
el2
->
theta2
>
el2
->
theta1
)
if
(
el2
->
theta2
>
el2
->
theta1
)
ASSERT
(
0
);
ASSERT
(
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
,
ymin
,
thmin
,
thmin2
;
double
xmin
,
ymin
,
thmin
,
thmin2
;
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
while
(
(
step
*
max
(
el1
->
xrad
,
el1
->
yrad
))
>
1.0
*
NM_PER_MIL
&&
(
step2
*
max
(
el2
->
xrad
,
el2
->
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
)
if
(
i
<
nsteps
-
1
)
theta
=
th_start
-
i
*
step
;
theta
=
th_start
-
i
*
step
;
else
else
theta
=
th_end
;
theta
=
th_end
;
double
x
=
el1
->
Center
.
X
+
el1
->
xrad
*
cos
(
theta
);
double
x
=
el1
->
Center
.
X
+
el1
->
xrad
*
cos
(
theta
);
double
y
=
el1
->
Center
.
Y
+
el1
->
yrad
*
sin
(
theta
);
double
y
=
el1
->
Center
.
Y
+
el1
->
yrad
*
sin
(
theta
);
step2
=
(
th_start2
-
th_end2
)
/
(
nsteps2
-
1
);
step2
=
(
th_start2
-
th_end2
)
/
(
nsteps2
-
1
);
for
(
int
i2
=
0
;
i2
<
nsteps2
;
i2
++
)
for
(
int
i2
=
0
;
i2
<
nsteps2
;
i2
++
)
{
{
double
theta2
;
double
theta2
;
if
(
i2
<
nsteps2
-
1
)
if
(
i2
<
nsteps2
-
1
)
theta2
=
th_start2
-
i2
*
step2
;
theta2
=
th_start2
-
i2
*
step2
;
else
else
theta2
=
th_end2
;
theta2
=
th_end2
;
double
x2
=
el2
->
Center
.
X
+
el2
->
xrad
*
cos
(
theta2
);
double
x2
=
el2
->
Center
.
X
+
el2
->
xrad
*
cos
(
theta2
);
double
y2
=
el2
->
Center
.
Y
+
el2
->
yrad
*
sin
(
theta2
);
double
y2
=
el2
->
Center
.
Y
+
el2
->
yrad
*
sin
(
theta2
);
double
d
=
Distance
(
x
,
y
,
x2
,
y2
);
double
d
=
Distance
(
x
,
y
,
x2
,
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
;
}
}
polygon/math_for_graphics.h
View file @
e126042b
// math stuff for graphics, from FreePCB
// math stuff for graphics, from FreePCB
typedef
struct
PointTag
typedef
struct
PointTag
{
{
double
X
,
Y
;
double
X
,
Y
;
}
Point
;
}
Point
;
typedef
struct
EllipseTag
typedef
struct
EllipseTag
{
{
Point
Center
;
/* ellipse center */
Point
Center
;
/* ellipse center */
// double MaxRad,MinRad; /* major and minor axis */
// double MaxRad,MinRad; /* major and minor axis */
// double Phi; /* major axis rotation */
// double Phi; /* major axis rotation */
double
xrad
,
yrad
;
// radii on x and y
double
xrad
,
yrad
;
// radii on x and y
double
theta1
,
theta2
;
// start and end angle for arc
double
theta1
,
theta2
;
// start and end angle for arc
}
EllipseKH
;
}
EllipseKH
;
const
CPoint
zero
(
0
,
0
);
const
CPoint
zero
(
0
,
0
);
class
my_circle
{
class
my_circle
{
public
:
public
:
my_circle
(){};
my_circle
(){};
my_circle
(
int
xx
,
int
yy
,
int
rr
)
my_circle
(
int
xx
,
int
yy
,
int
rr
)
{
{
x
=
xx
;
x
=
xx
;
y
=
yy
;
y
=
yy
;
r
=
rr
;
r
=
rr
;
};
};
int
x
,
y
,
r
;
int
x
,
y
,
r
;
};
};
class
my_rect
{
class
my_rect
{
public
:
public
:
my_rect
(){};
my_rect
(){};
my_rect
(
int
xi
,
int
yi
,
int
xf
,
int
yf
)
my_rect
(
int
xi
,
int
yi
,
int
xf
,
int
yf
)
{
{
xlo
=
min
(
xi
,
xf
);
xlo
=
min
(
xi
,
xf
);
xhi
=
max
(
xi
,
xf
);
xhi
=
max
(
xi
,
xf
);
ylo
=
min
(
yi
,
yf
);
ylo
=
min
(
yi
,
yf
);
yhi
=
max
(
yi
,
yf
);
yhi
=
max
(
yi
,
yf
);
};
};
int
xlo
,
ylo
,
xhi
,
yhi
;
int
xlo
,
ylo
,
xhi
,
yhi
;
};
};
class
my_seg
{
class
my_seg
{
public
:
public
:
my_seg
(){};
my_seg
(){};
my_seg
(
int
xxi
,
int
yyi
,
int
xxf
,
int
yyf
)
my_seg
(
int
xxi
,
int
yyi
,
int
xxf
,
int
yyf
)
{
{
xi
=
xxi
;
xi
=
xxi
;
yi
=
yyi
;
yi
=
yyi
;
xf
=
xxf
;
xf
=
xxf
;
yf
=
yyf
;
yf
=
yyf
;
};
};
int
xi
,
yi
,
xf
,
yf
;
int
xi
,
yi
,
xf
,
yf
;
};
};
// math stuff for graphics
// math stuff for graphics
BOOL
Quadratic
(
double
a
,
double
b
,
double
c
,
double
*
x1
,
double
*
x2
);
BOOL
Quadratic
(
double
a
,
double
b
,
double
c
,
double
*
x1
,
double
*
x2
);
void
DrawArc
(
CDC
*
pDC
,
int
shape
,
int
xxi
,
int
yyi
,
int
xxf
,
int
yyf
,
BOOL
bMeta
=
FALSE
);
void
DrawArc
(
CDC
*
pDC
,
int
shape
,
int
xxi
,
int
yyi
,
int
xxf
,
int
yyf
,
BOOL
bMeta
=
FALSE
);
void
RotatePoint
(
CPoint
*
p
,
int
angle
,
CPoint
org
);
void
RotatePoint
(
CPoint
*
p
,
int
angle
,
CPoint
org
);
void
RotateRect
(
CRect
*
r
,
int
angle
,
CPoint
org
);
void
RotateRect
(
CRect
*
r
,
int
angle
,
CPoint
org
);
int
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
);
int
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
);
int
FindLineIntersection
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x
,
double
*
y
);
int
FindLineIntersection
(
double
a
,
double
b
,
double
c
,
double
d
,
double
*
x
,
double
*
y
);
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
*
dist
=
NULL
);
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
,
double
*
dist
=
NULL
);
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
[]
=
NULL
,
double
y
[]
=
NULL
);
double
x
[]
=
NULL
,
double
y
[]
=
NULL
);
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
);
BOOL
FindVerticalLineEllipseIntersections
(
double
a
,
double
b
,
double
x
,
double
*
y1
,
double
*
y2
);
BOOL
FindVerticalLineEllipseIntersections
(
double
a
,
double
b
,
double
x
,
double
*
y1
,
double
*
y2
);
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
=
NULL
,
int
*
y
=
NULL
,
double
*
dist
=
NULL
);
int
*
x
=
NULL
,
int
*
y
=
NULL
,
double
*
dist
=
NULL
);
void
GetPadElements
(
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
radius
,
int
angle
,
void
GetPadElements
(
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
radius
,
int
angle
,
int
*
nr
,
my_rect
r
[],
int
*
nc
,
my_circle
c
[],
int
*
ns
,
my_seg
s
[]
);
int
*
nr
,
my_rect
r
[],
int
*
nc
,
my_circle
c
[],
int
*
ns
,
my_seg
s
[]
);
int
GetClearanceBetweenPads
(
int
type1
,
int
x1
,
int
y1
,
int
w1
,
int
l1
,
int
r1
,
int
angle1
,
int
GetClearanceBetweenPads
(
int
type1
,
int
x1
,
int
y1
,
int
w1
,
int
l1
,
int
r1
,
int
angle1
,
int
type2
,
int
x2
,
int
y2
,
int
w2
,
int
l2
,
int
r2
,
int
angle2
);
int
type2
,
int
x2
,
int
y2
,
int
w2
,
int
l2
,
int
r2
,
int
angle2
);
int
GetClearanceBetweenSegmentAndPad
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
w
,
int
GetClearanceBetweenSegmentAndPad
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
w
,
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
type
,
int
x
,
int
y
,
int
wid
,
int
len
,
int
radius
,
int
angle
);
int
radius
,
int
angle
);
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
);
/** Function GetPointToLineSegmentDistance
/** Function GetPointToLineSegmentDistance
* Get distance between line segment and point
* Get distance between line segment and point
* @param x,y = point
* @param x,y = point
* @param xi,yi and xf,yf = the end-points of the line segment
* @param xi,yi and xf,yf = the end-points of the line segment
* @return the distance
* @return the distance
*/
*/
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
);
double
GetPointToLineDistance
(
double
a
,
double
b
,
int
x
,
int
y
,
double
*
xp
=
NULL
,
double
*
yp
=
NULL
);
double
GetPointToLineDistance
(
double
a
,
double
b
,
int
x
,
int
y
,
double
*
xp
=
NULL
,
double
*
yp
=
NULL
);
BOOL
InRange
(
double
x
,
double
xi
,
double
xf
);
BOOL
InRange
(
double
x
,
double
xi
,
double
xf
);
double
Distance
(
int
x1
,
int
y1
,
int
x2
,
int
y2
);
double
Distance
(
int
x1
,
int
y1
,
int
x2
,
int
y2
);
int
GetArcIntersections
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
int
GetArcIntersections
(
EllipseKH
*
el1
,
EllipseKH
*
el2
,
double
*
x1
=
NULL
,
double
*
y1
=
NULL
,
double
*
x1
=
NULL
,
double
*
y1
=
NULL
,
double
*
x2
=
NULL
,
double
*
y2
=
NULL
);
double
*
x2
=
NULL
,
double
*
y2
=
NULL
);
CPoint
GetInflectionPoint
(
CPoint
pi
,
CPoint
pf
,
int
mode
);
CPoint
GetInflectionPoint
(
CPoint
pi
,
CPoint
pf
,
int
mode
);
// quicksort (2-way or 3-way)
// quicksort (2-way or 3-way)
void
quickSort
(
int
numbers
[],
int
index
[],
int
array_size
);
void
quickSort
(
int
numbers
[],
int
index
[],
int
array_size
);
void
q_sort
(
int
numbers
[],
int
index
[],
int
left
,
int
right
);
void
q_sort
(
int
numbers
[],
int
index
[],
int
left
,
int
right
);
void
q_sort_3way
(
int
a
[],
int
b
[],
int
left
,
int
right
);
void
q_sort_3way
(
int
a
[],
int
b
[],
int
left
,
int
right
);
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