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
d536f9d9
Commit
d536f9d9
authored
Sep 20, 2010
by
jean-pierre charras
Browse files
Options
Browse Files
Download
Plain Diff
DRC code cleaning, and added DRC tests for trapezoidal pads. Needs more tests.
parents
e149951b
f1df65c5
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1369 additions
and
1141 deletions
+1369
-1141
CMakeLists.txt
pcbnew/CMakeLists.txt
+1
-0
class_pad.cpp
pcbnew/class_pad.cpp
+7
-18
class_pad.h
pcbnew/class_pad.h
+15
-3
class_pad_draw_functions.cpp
pcbnew/class_pad_draw_functions.cpp
+55
-36
dialog_drc.cpp
pcbnew/dialog_drc.cpp
+1
-8
dialog_pad_properties.cpp
pcbnew/dialog_pad_properties.cpp
+3
-5
drc.cpp
pcbnew/drc.cpp
+18
-1004
drc_clearance_test_functions.cpp
pcbnew/drc_clearance_test_functions.cpp
+1112
-0
drc_stuff.h
pcbnew/drc_stuff.h
+18
-21
math_for_graphics.cpp
polygon/math_for_graphics.cpp
+19
-18
math_for_graphics.h
polygon/math_for_graphics.h
+24
-3
polygon_test_point_inside.cpp
polygon/polygon_test_point_inside.cpp
+71
-16
polygon_test_point_inside.h
polygon/polygon_test_point_inside.h
+25
-9
No files found.
pcbnew/CMakeLists.txt
View file @
d536f9d9
...
...
@@ -96,6 +96,7 @@ set(PCBNEW_SRCS
dist.cpp
dragsegm.cpp
drc.cpp
drc_clearance_test_functions.cpp
drc_marker_functions.cpp
edgemod.cpp
edit.cpp
...
...
pcbnew/class_pad.cpp
View file @
d536f9d9
...
...
@@ -764,17 +764,15 @@ bool D_PAD::IsOnLayer( int aLayer ) const
*/
bool
D_PAD
::
HitTest
(
const
wxPoint
&
ref_pos
)
{
int
deltaX
,
deltaY
;
int
dx
,
dy
;
double
dist
;
wxPoint
shape_pos
=
ReturnShapePos
();
deltaX
=
ref_pos
.
x
-
shape_pos
.
x
;
deltaY
=
ref_pos
.
y
-
shape_pos
.
y
;
wxPoint
delta
=
ref_pos
-
shape_pos
;
/* Quick test: a test point must be inside the circle. */
if
(
(
abs
(
delta
X
)
>
m_ShapeMaxRadius
)
||
(
abs
(
deltaY
)
>
m_ShapeMaxRadius
)
)
if
(
(
abs
(
delta
.
x
)
>
m_ShapeMaxRadius
)
||
(
abs
(
delta
.
y
)
>
m_ShapeMaxRadius
)
)
return
false
;
dx
=
m_Size
.
x
>>
1
;
// dx also is the radius for rounded pads
...
...
@@ -783,7 +781,7 @@ bool D_PAD::HitTest( const wxPoint& ref_pos )
switch
(
m_PadShape
&
0x7F
)
{
case
PAD_CIRCLE
:
dist
=
hypot
(
delta
X
,
deltaY
);
dist
=
hypot
(
delta
.
x
,
delta
.
y
);
if
(
wxRound
(
dist
)
<=
dx
)
return
true
;
break
;
...
...
@@ -792,22 +790,13 @@ bool D_PAD::HitTest( const wxPoint& ref_pos )
{
wxPoint
poly
[
4
];
BuildPadPolygon
(
poly
,
wxSize
(
0
,
0
),
0
);
// Build the same polygon with CPolyPt corners,
// to use TestPointInsidePolygon
static
std
::
vector
<
CPolyPt
>
polysList
;
// Is static to avoid memory reallocation
polysList
.
clear
();
for
(
int
ii
=
0
;
ii
<
4
;
ii
++
)
{
CPolyPt
corner
(
poly
[
ii
].
x
,
poly
[
ii
].
y
);
polysList
.
push_back
(
corner
);
}
RotatePoint
(
&
deltaX
,
&
deltaY
,
-
m_Orient
);
return
TestPointInsidePolygon
(
polysList
,
0
,
3
,
deltaX
,
deltaY
);
RotatePoint
(
&
delta
,
-
m_Orient
);
return
TestPointInsidePolygon
(
poly
,
4
,
delta
);
}
default
:
RotatePoint
(
&
delta
X
,
&
deltaY
,
-
m_Orient
);
if
(
(
abs
(
delta
X
)
<=
dx
)
&&
(
abs
(
deltaY
)
<=
dy
)
)
RotatePoint
(
&
delta
,
-
m_Orient
);
if
(
(
abs
(
delta
.
x
)
<=
dx
)
&&
(
abs
(
delta
.
y
)
<=
dy
)
)
return
true
;
break
;
}
...
...
pcbnew/class_pad.h
View file @
d536f9d9
...
...
@@ -148,7 +148,7 @@ public:
* Function GetShape
* @return the shape of this pad.
*/
int
GetShape
()
{
return
m_PadShape
&
0xFF
;
}
int
GetShape
()
const
{
return
m_PadShape
&
0xFF
;
}
/**
* Function GetPosition
...
...
@@ -239,14 +239,26 @@ public:
void
DrawShape
(
EDA_Rect
*
aClipBox
,
wxDC
*
aDC
,
PAD_DRAWINFO
&
aDrawInfo
);
/** function BuildPadPolygon
* Has meaning only for polygonal pads (trapez
io
d and rectangular)
* Has meaning only for polygonal pads (trapez
oi
d and rectangular)
* Build the Corner list of the polygonal shape,
* depending on shape, extra size (clearance ...) and orientation
* @param aCoord[4] = a buffer to fill.
* @param aInflateValue = wxSize: the clearance or margin value. value > 0: inflate, < 0 deflate
* @param aRotation = full rotation of the polygon
*/
void
BuildPadPolygon
(
wxPoint
aCoord
[
4
],
wxSize
aInflateValue
,
int
aRotation
);
void
BuildPadPolygon
(
wxPoint
aCoord
[
4
],
wxSize
aInflateValue
,
int
aRotation
)
const
;
/** function BuildSegmentFromOvalShape
* Has meaning only for OVAL (and ROUND) pads
* Build an equivalent segment having the same shape as the OVAL shape,
* Useful in draw function and in DRC and HitTest functions,
* because segments are already well handled by track tests
* @param aSegStart = the starting point of the equivalent segment, relative to the shape position.
* @param aSegEnd = the ending point of the equivalent segment, relative to the shape position
* @param aRotation = full rotation of the segment
* @return the width of the segment
*/
int
BuildSegmentFromOvalShape
(
wxPoint
&
aSegStart
,
wxPoint
&
aSegEnd
,
int
aRotation
)
const
;
// others
void
SetPadName
(
const
wxString
&
name
);
// Change pad name
...
...
pcbnew/class_pad_draw_functions.cpp
View file @
d536f9d9
...
...
@@ -357,9 +357,9 @@ void D_PAD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDraw_mode,
void
D_PAD
::
DrawShape
(
EDA_Rect
*
aClipBox
,
wxDC
*
aDC
,
PAD_DRAWINFO
&
aDrawInfo
)
{
wxPoint
coord
[
4
];
int
rotdx
,
delta_cx
,
delta_cy
;
int
delta_cx
,
delta_cy
;
int
angle
=
m_Orient
;
int
seg_width
;
GRSetDrawMode
(
aDC
,
aDrawInfo
.
m_DrawMode
);
...
...
@@ -392,44 +392,30 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
break
;
case
PAD_OVAL
:
if
(
halfsize
.
x
>
halfsize
.
y
)
/* horizontal */
{
delta_cx
=
halfsize
.
x
-
halfsize
.
y
;
delta_cy
=
0
;
rotdx
=
m_Size
.
y
+
(
aDrawInfo
.
m_Mask_margin
.
y
*
2
);
}
else
/* vertical */
{
delta_cx
=
0
;
delta_cy
=
halfsize
.
y
-
halfsize
.
x
;
rotdx
=
m_Size
.
x
+
(
aDrawInfo
.
m_Mask_margin
.
x
*
2
);
}
RotatePoint
(
&
delta_cx
,
&
delta_cy
,
angle
);
{
wxPoint
segStart
,
segEnd
;
seg_width
=
BuildSegmentFromOvalShape
(
segStart
,
segEnd
,
angle
);
segStart
+=
shape_pos
;
segEnd
+=
shape_pos
;
if
(
aDrawInfo
.
m_ShowPadFilled
)
{
GRFillCSegm
(
aClipBox
,
aDC
,
shape_pos
.
x
+
delta_cx
,
shape_pos
.
y
+
delta_cy
,
shape_pos
.
x
-
delta_cx
,
shape_pos
.
y
-
delta_cy
,
rotdx
,
aDrawInfo
.
m_Color
);
GRFillCSegm
(
aClipBox
,
aDC
,
segStart
.
x
,
segStart
.
y
,
segEnd
.
x
,
segEnd
.
y
,
seg_width
,
aDrawInfo
.
m_Color
);
}
else
{
GRCSegm
(
aClipBox
,
aDC
,
shape_pos
.
x
+
delta_cx
,
shape_pos
.
y
+
delta_cy
,
shape_pos
.
x
-
delta_cx
,
shape_pos
.
y
-
delta_cy
,
rotdx
,
m_PadSketchModePenSize
,
aDrawInfo
.
m_Color
);
GRCSegm
(
aClipBox
,
aDC
,
segStart
.
x
,
segStart
.
y
,
segEnd
.
x
,
segEnd
.
y
,
seg_width
,
m_PadSketchModePenSize
,
aDrawInfo
.
m_Color
);
}
/* Draw the isolation line. */
if
(
aDrawInfo
.
m_PadClearance
)
{
rotdx
=
rotdx
+
2
*
aDrawInfo
.
m_PadClearance
;
GRCSegm
(
aClipBox
,
aDC
,
shape_pos
.
x
+
delta_cx
,
shape_pos
.
y
+
delta_cy
,
shape_pos
.
x
-
delta_cx
,
shape_pos
.
y
-
delta_cy
,
rotdx
,
aDrawInfo
.
m_Color
);
seg_width
+=
2
*
aDrawInfo
.
m_PadClearance
;
GRCSegm
(
aClipBox
,
aDC
,
segStart
.
x
,
segStart
.
y
,
segEnd
.
x
,
segEnd
.
y
,
seg_width
,
aDrawInfo
.
m_Color
);
}
}
break
;
case
PAD_RECT
:
...
...
@@ -486,9 +472,6 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
#else
if
(
aDrawInfo
.
m_Scale
*
hole
>
1
)
/* draw hole if its size is enough */
#endif
GRFilledCircle
(
aClipBox
,
aDC
,
holepos
.
x
,
holepos
.
y
,
hole
,
0
,
aDrawInfo
.
m_Color
,
aDrawInfo
.
m_HoleColor
);
break
;
...
...
@@ -501,18 +484,18 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
{
delta_cx
=
halfsize
.
x
-
halfsize
.
y
;
delta_cy
=
0
;
rotdx
=
m_Drill
.
y
;
seg_width
=
m_Drill
.
y
;
}
else
/* vertical */
{
delta_cx
=
0
;
delta_cy
=
halfsize
.
y
-
halfsize
.
x
;
rotdx
=
m_Drill
.
x
;
seg_width
=
m_Drill
.
x
;
}
RotatePoint
(
&
delta_cx
,
&
delta_cy
,
angle
);
GRFillCSegm
(
aClipBox
,
aDC
,
holepos
.
x
+
delta_cx
,
holepos
.
y
+
delta_cy
,
holepos
.
x
-
delta_cx
,
holepos
.
y
-
delta_cy
,
rotdx
,
holepos
.
x
-
delta_cx
,
holepos
.
y
-
delta_cy
,
seg_width
,
aDrawInfo
.
m_HoleColor
);
break
;
...
...
@@ -637,6 +620,42 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
}
}
/** function BuildSegmentFromOvalShape
* Has meaning only for OVAL (and ROUND) pads.
* Build an equivalent segment having the same shape as the OVAL shape,
* aSegStart and aSegEnd are the ending points of the equivalent segment of the shape
* aRotation is the asked rotation of the segment (usually m_Orient)
*/
int
D_PAD
::
BuildSegmentFromOvalShape
(
wxPoint
&
aSegStart
,
wxPoint
&
aSegEnd
,
int
aRotation
)
const
{
int
width
;
if
(
m_Size
.
y
<
m_Size
.
x
)
// Build an horizontal equiv segment
{
int
delta
=
(
m_Size
.
x
-
m_Size
.
y
)
/
2
;
aSegStart
.
x
=
-
delta
;
aSegStart
.
y
=
0
;
aSegEnd
.
x
=
delta
;
aSegEnd
.
y
=
0
;
width
=
m_Size
.
y
;
}
else
// Vertical oval: build a vertical equiv segment
{
int
delta
=
(
m_Size
.
y
-
m_Size
.
x
)
/
2
;
aSegStart
.
x
=
0
;
aSegStart
.
y
=
-
delta
;
aSegEnd
.
x
=
0
;
aSegEnd
.
y
=
delta
;
width
=
m_Size
.
x
;
}
if
(
aRotation
)
{
RotatePoint
(
&
aSegStart
,
aRotation
);
RotatePoint
(
&
aSegEnd
,
aRotation
);
}
return
width
;
}
/** function BuildPadPolygon
* Has meaning only for polygonal pads (trapeziod and rectangular)
...
...
@@ -646,7 +665,7 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
* @param aInflateValue = wxSize: the clearance or margin value. value > 0: inflate, < 0 deflate
* @param aRotation = full rotation of the polygon, usually m_Orient
*/
void
D_PAD
::
BuildPadPolygon
(
wxPoint
aCoord
[
4
],
wxSize
aInflateValue
,
int
aRotation
)
void
D_PAD
::
BuildPadPolygon
(
wxPoint
aCoord
[
4
],
wxSize
aInflateValue
,
int
aRotation
)
const
{
if
(
(
GetShape
()
!=
PAD_RECT
)
&&
(
GetShape
()
!=
PAD_TRAPEZOID
)
)
return
;
...
...
pcbnew/dialog_drc.cpp
View file @
d536f9d9
...
...
@@ -44,21 +44,17 @@ bool DIALOG_DRC_CONTROL::Show( bool show )
{
bool
ret
;
D
(
printf
(
"%s %d
\n
"
,
__func__
,
show
);)
if
(
show
)
{
ret
=
DIALOG_DRC_CONTROL_BASE
::
Show
(
show
);
if
(
s_LastPos
.
x
!=
-
1
)
{
D
(
printf
(
"setting window pos to (%d,%d)
\n
"
,
s_LastPos
.
x
,
s_LastPos
.
y
);)
//SetPosition( s_LastPos );
SetSize
(
s_LastPos
.
x
,
s_LastPos
.
y
,
s_LastSize
.
x
,
s_LastSize
.
y
,
0
);
}
else
{
D
(
printf
(
"not setting window pos (%d,%d)
\n
"
,
s_LastPos
.
x
,
s_LastPos
.
y
);)
// Do nothing: last position not yet saved.
}
}
else
...
...
@@ -66,9 +62,6 @@ bool DIALOG_DRC_CONTROL::Show( bool show )
// Save the dialog's position before hiding
s_LastPos
=
GetPosition
();
s_LastSize
=
GetSize
();
D
(
printf
(
"saving window pos as (%d,%d)
\n
"
,
s_LastPos
.
x
,
s_LastPos
.
y
);)
ret
=
DIALOG_DRC_CONTROL_BASE
::
Show
(
show
);
}
...
...
pcbnew/dialog_pad_properties.cpp
View file @
d536f9d9
...
...
@@ -195,8 +195,7 @@ void DIALOG_PAD_PROPERTIES::initValues()
{
SetFocus
();
// Required under wxGTK if we want to demiss the dialog with the ESC key
int
tmp
;
int
internalUnits
=
m_Parent
->
m_InternalUnits
;
int
internalUnits
=
m_Parent
->
m_InternalUnits
;
wxString
msg
;
m_isFlipped
=
false
;
if
(
m_CurrentPad
)
...
...
@@ -298,7 +297,7 @@ void DIALOG_PAD_PROPERTIES::initValues()
SetPadLayersList
(
m_dummyPad
->
m_Masque_Layer
);
msg
.
Clear
();
msg
<<
tmp
;
msg
<<
m_dummyPad
->
m_Orient
;
m_PadOrientCtrl
->
SetValue
(
msg
);
// Pad Orient
...
...
@@ -350,11 +349,10 @@ void DIALOG_PAD_PROPERTIES::initValues()
m_PadOrientCtrl
->
SetValue
(
msg
);
// Selection du type
tmp
=
m_dummyPad
->
m_Attribut
;
m_PadType
->
SetSelection
(
0
);
for
(
int
ii
=
0
;
ii
<
NBTYPES
;
ii
++
)
{
if
(
CodeType
[
ii
]
==
tmp
)
if
(
CodeType
[
ii
]
==
m_dummyPad
->
m_Attribut
)
{
m_PadType
->
SetSelection
(
ii
);
break
;
...
...
pcbnew/drc.cpp
View file @
d536f9d9
This diff is collapsed.
Click to expand it.
pcbnew/drc_clearance_test_functions.cpp
0 → 100644
View file @
d536f9d9
This diff is collapsed.
Click to expand it.
pcbnew/drc_stuff.h
View file @
d536f9d9
...
...
@@ -173,10 +173,10 @@ private:
/* variables used in checkLine to test DRC segm to segm:
* define the area relative to the ref segment that does not contains anu other segment
*/
int
m_xcliplo
;
int
m_ycliplo
;
int
m_xcliphi
;
int
m_ycliphi
;
int
m_xcliplo
;
int
m_ycliplo
;
int
m_xcliphi
;
int
m_ycliphi
;
WinEDA_PcbFrame
*
m_mainWindow
;
BOARD
*
m_pcb
;
...
...
@@ -329,30 +329,27 @@ private:
/**
* Function checkMarginToCircle
* @todo this translation is no good, fix this:
* calculates the distance from a circle (via or round end of track) to the
* segment of reference on the right hand side.
*
* @param cx The x coordinate of the circle's center
* @param cy The y coordinate of the circle's center
* @param radius A "keep out" radius centered over the circle
* @param length The length of the segment (i.e. coordinate of end)
* Helper function checkMarginToCircle
* Check the distance from a point to
* a segment. the segment is expected starting at 0,0, and on the X axis
* (used to test DRC between a segment and a round pad, via or round end of a track
* @param aCentre The coordinate of the circle's center
* @param aRadius A "keep out" radius centered over the circle
* @param aLength The length of the segment (i.e. coordinate of end, becuase it is on the X axis)
* @return bool - true if distance >= radius, else
* false when distance <
r
adius
* false when distance <
aR
adius
*/
static
bool
checkMarginToCircle
(
int
cx
,
int
cy
,
int
radius
,
int
l
ength
);
static
bool
checkMarginToCircle
(
wxPoint
aCentre
,
int
aRadius
,
int
aL
ength
);
/**
* Function checkLine
* tests to see if one track is in contact with another track.
*
* Cette routine controle si la ligne (x1,y1 x2,y2) a une partie s'inscrivant
* dans le cadre (xcliplo,ycliplo xcliphi,ycliphi) (variables globales,
* locales a ce fichier)
* (helper function used in drc calculations to see if one track is in contact with another track).
* Test if a line intersects a bounding box (a rectangle)
* The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi
* return true if the line from aSegStart to aSegEnd is outside the bounding box
*/
bool
checkLine
(
int
x1
,
int
y1
,
int
x2
,
int
y2
);
bool
checkLine
(
wxPoint
aSegStart
,
wxPoint
aSegEnd
);
//-----</single tests>---------------------------------------------
...
...
polygon/math_for_graphics.cpp
View file @
d536f9d9
// math for graphics utility routines, from FreePCB
// math for graphics utility routines
and RC
, from FreePCB
#include <vector>
...
...
@@ -13,13 +13,14 @@
using
namespace
std
;
// test for hit on line segment
// i.e. cursor within a given distance from segment
// enter with: x,y = cursor coords
// (xi,yi) and (xf,yf) are the end-points of the line segment
// dist = maximum distance for hit
//
int
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
)
/** function TestLineHit
* test for hit on line segment i.e. a point within a given distance from segment
* @param x, y = cursor coords
* @param xi,yi and xf,yf = the end-points of the line segment
* @param dist = maximum distance for hit
* return true if dist < distance between the point and the segment
*/
bool
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
)
{
double
dd
;
...
...
@@ -29,14 +30,14 @@ int TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
// vertical segment
dd
=
fabs
(
(
double
)(
x
-
xi
)
);
if
(
dd
<
dist
&&
(
(
yf
>
yi
&&
y
<
yf
&&
y
>
yi
)
||
(
yf
<
yi
&&
y
>
yf
&&
y
<
yi
)
)
)
return
1
;
return
true
;
}
else
if
(
yf
==
yi
)
{
// horizontal segment
dd
=
fabs
(
(
double
)(
y
-
yi
)
);
if
(
dd
<
dist
&&
(
(
xf
>
xi
&&
x
<
xf
&&
x
>
xi
)
||
(
xf
<
xi
&&
x
>
xf
&&
x
<
xi
)
)
)
return
1
;
return
true
;
}
else
{
...
...
@@ -62,10 +63,10 @@ int TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
{
// line segment more horizontal than vertical
if
(
dd
<
dist
&&
(
(
xf
>
xi
&&
xp
<
xf
&&
xp
>
xi
)
||
(
xf
<
xi
&&
xp
>
xf
&&
xp
<
xi
)
)
)
return
1
;
return
true
;
}
}
return
0
;
// no hit
return
false
;
// no hit
}
...
...
@@ -482,12 +483,12 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
return
1
;
}
/
/ Test for intersection of line s
egments
// If lines are parallel, returns false
// If true, returns intersection coords in x, y
// 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
)
/
/
/
** function TestForIntersectionOfStraightLineS
egments
* Test for intersection of line segments
* If lines are parallel, returns false
* If true, returns also intersection coords in x, y
* if false, returns min. distance in dist (may be 0.0 if parallel
)
*
/
bool
TestForIntersectionOfStraightLineSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
*
x
,
int
*
y
,
double
*
d
)
...
...
polygon/math_for_graphics.h
View file @
d536f9d9
...
...
@@ -13,8 +13,6 @@ typedef struct PointTag
typedef
struct
EllipseTag
{
PointT
Center
;
/* ellipse center */
// double MaxRad,MinRad; /* major and minor axis */
// double Phi; /* major axis rotation */
double
xrad
,
yrad
;
// radii on x and y
double
theta1
,
theta2
;
// start and end angle for arc
}
EllipseKH
;
...
...
@@ -22,7 +20,16 @@ typedef struct EllipseTag
// math stuff for graphics
bool
Quadratic
(
double
a
,
double
b
,
double
c
,
double
*
x1
,
double
*
x2
);
int
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
);
/** function TestLineHit
* test for hit on line segment i.e. a point within a given distance from segment
* @param xi,yi and xf,yf = the end-points of the line segment
* @param dist = maximum distance for hit
* @param x, y = point to test coords
* @return true if hit (i.e dist < distance between the point and the segment, false if not.
*/
bool
TestLineHit
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
x
,
int
y
,
double
dist
);
int
FindLineSegmentIntersection
(
double
a
,
double
b
,
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
double
*
x1
,
double
*
y1
,
double
*
x2
,
double
*
y2
,
double
*
dist
=
NULL
);
int
FindSegmentIntersections
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
style
,
...
...
@@ -30,9 +37,23 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
double
x
[]
=
NULL
,
double
y
[]
=
NULL
);
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
);
/** function TestForIntersectionOfStraightLineSegments
* Test for intersection of line segments
* If lines are parallel, returns false
* If true, returns also intersection coords in x, y
* 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)
* @param x1i, y1i, x1f, y1f = integer coordinates of the first segment
* @param x2i, y2i, x2f, y2f = integer coordinates of the other segment
* @param x, y = pointers on 2 integer to store the intersection coordinates (can be NULL)
* @param dist = pointeur on a double to store the dist.
* @return true if intersect.
*/
bool
TestForIntersectionOfStraightLineSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
*
x
=
NULL
,
int
*
y
=
NULL
,
double
*
dist
=
NULL
);
int
GetClearanceBetweenSegments
(
int
x1i
,
int
y1i
,
int
x1f
,
int
y1f
,
int
style1
,
int
w1
,
int
x2i
,
int
y2i
,
int
x2f
,
int
y2f
,
int
style2
,
int
w2
,
int
max_cl
,
int
*
x
,
int
*
y
);
...
...
polygon/polygon_test_point_inside.cpp
View file @
d536f9d9
/////////////////////////////////////////////////////////////////////////////
// Name: polygon_test_point_inside.cpp
/////////////////////////////////////////////////////////////////////////////
/**
* @file polygon_test_point_inside.cpp
*/
#include <math.h>
#include <vector>
#include "PolyLine.h"
using
namespace
std
;
/* this algo uses the the Jordan curve theorem to find if a point is inside or outside a polygon:
* It run a semi-infinite line horizontally (increasing x, fixed y)
* out from the test point, and count how many edges it crosses.
* At each crossing, the ray switches between inside and outside.
* If odd count, the test point is inside the polygon
* This is called the Jordan curve theorem, or sometimes referred to as the "even-odd" test.
* Take care to starting and ending points of segments outlines, when the horizontal line crosses a segment outline
* Take care to starting and ending points of segments outlines, when the horizontal line crosses a segment outline
* exactly on an ending point:
* Because the starting point of a segment is also the ending point of the previous, only one must be used.
* And we do no use twice the same segment, so we do NOT use both starting and ending points of these 2 segments.
...
...
@@ -30,16 +27,19 @@ using namespace std;
#define INSIDE true
bool
TestPointInsidePolygon
(
std
::
vector
<
CPolyPt
>
aPolysList
,
int
istart
,
int
iend
,
int
refx
,
int
refy
)
int
aIdxstart
,
int
aIdxend
,
int
aRefx
,
int
aRefy
)
/** Function TestPointInsidePolygon
* test if a point is inside or outside a polygon.
* the polygon must have only lines (not arcs) for outlines.
* Use TestPointInside or TestPointInsideContour for more complex polygons
* @param aPolysList: the list of polygons
* @param
i
start: the starting point of a given polygon in m_FilledPolysList.
* @param
i
end: the ending point of the polygon in m_FilledPolysList.
* @param
refx,r
efy: the point coordinate to test
* @param
aIdx
start: the starting point of a given polygon in m_FilledPolysList.
* @param
aIdx
end: the ending point of the polygon in m_FilledPolysList.
* @param
aRefx, aR
efy: the point coordinate to test
* @return true if the point is inside, false for outside
*/
{
...
...
@@ -48,7 +48,62 @@ bool TestPointInsidePolygon( std::vector <CPolyPt> aPolysList,
int
count
=
0
;
// find all intersection points of line with polyline sides
for
(
ics
=
istart
,
ice
=
iend
;
ics
<=
iend
;
ice
=
ics
++
)
for
(
ics
=
aIdxstart
,
ice
=
aIdxend
;
ics
<=
aIdxend
;
ice
=
ics
++
)
{
int
seg_startX
=
aPolysList
[
ics
].
x
;
int
seg_startY
=
aPolysList
[
ics
].
y
;
int
seg_endX
=
aPolysList
[
ice
].
x
;
int
seg_endY
=
aPolysList
[
ice
].
y
;
/* Trivial cases: skip if ref above or below the segment to test */
if
(
(
seg_startY
>
aRefy
)
&&
(
seg_endY
>
aRefy
)
)
continue
;
// segment below ref point, or one of its ends has the same Y pos as the ref point: skip
// So we eliminate one end point of 2 consecutive segments.
// Note: also we skip horizontal segments if ref point is on this horizontal line
// So reference points on horizontal segments outlines always are seen as outside the polygon
if
(
(
seg_startY
<=
aRefy
)
&&
(
seg_endY
<=
aRefy
)
)
continue
;
/* refy is between seg_startY and seg_endY.
* note: here: horizontal segments (seg_startY == seg_endY) are skipped,
* either by the first test or by the second test
* see if an horizontal semi infinite line from refx is intersecting the segment
*/
// calculate the x position of the intersection of this segment and the semi infinite line
// this is more easier if we move the X,Y axis origin to the segment start point:
seg_endX
-=
seg_startX
;
seg_endY
-=
seg_startY
;
double
newrefx
=
(
double
)
(
aRefx
-
seg_startX
);
double
newrefy
=
(
double
)
(
aRefy
-
seg_startY
);
// Now calculate the x intersection coordinate of the line from (0,0) to (seg_endX,seg_endY)
// with the horizontal line at the new refy position
// the line slope = seg_endY/seg_endX;
// and the x pos relative to the new origin is intersec_x = refy/slope
// Note: because horizontal segments are skipped, 1/slope exists (seg_end_y never == O)
double
intersec_x
=
newrefy
*
seg_endX
/
seg_endY
;
if
(
newrefx
<
intersec_x
)
// Intersection found with the semi-infinite line from refx to infinite
count
++
;
}
return
count
&
1
?
INSIDE
:
OUTSIDE
;
}
/* Function TestPointInsidePolygon (overlaid)
* same as previous, but use wxPoint and aCount corners
*/
bool
TestPointInsidePolygon
(
wxPoint
*
aPolysList
,
int
aCount
,
wxPoint
aRefPoint
)
{
// count intersection points to right of (refx,refy). If odd number, point (refx,refy) is inside polyline
int
ics
,
ice
;
int
count
=
0
;
// find all intersection points of line with polyline sides
for
(
ics
=
0
,
ice
=
aCount
-
1
;
ics
<
aCount
;
ice
=
ics
++
)
{
int
seg_startX
=
aPolysList
[
ics
].
x
;
int
seg_startY
=
aPolysList
[
ics
].
y
;
...
...
@@ -56,14 +111,14 @@ bool TestPointInsidePolygon( std::vector <CPolyPt> aPolysList,
int
seg_endY
=
aPolysList
[
ice
].
y
;
/* Trivial cases: skip if ref above or below the segment to test */
if
(
(
seg_startY
>
refy
)
&&
(
seg_endY
>
ref
y
)
)
if
(
(
seg_startY
>
aRefPoint
.
y
)
&&
(
seg_endY
>
aRefPoint
.
y
)
)
continue
;
// segment below ref point, or one of its ends has the same Y pos as the ref point: skip
// So we eliminate one end point of 2 consecutive segments.
// Note: also we skip horizontal segments if ref point is on this horizontal line
// So reference points on horizontal segments outlines always are seen as outside the polygon
if
(
(
seg_startY
<=
refy
)
&&
(
seg_endY
<=
ref
y
)
)
if
(
(
seg_startY
<=
aRefPoint
.
y
)
&&
(
seg_endY
<=
aRefPoint
.
y
)
)
continue
;
/* refy is between seg_startY and seg_endY.
...
...
@@ -76,8 +131,8 @@ bool TestPointInsidePolygon( std::vector <CPolyPt> aPolysList,
// this is more easier if we move the X,Y axis origin to the segment start point:
seg_endX
-=
seg_startX
;
seg_endY
-=
seg_startY
;
double
newrefx
=
(
double
)
(
ref
x
-
seg_startX
);
double
newrefy
=
(
double
)
(
ref
y
-
seg_startY
);
double
newrefx
=
(
double
)
(
aRefPoint
.
x
-
seg_startX
);
double
newrefy
=
(
double
)
(
aRefPoint
.
y
-
seg_startY
);
// Now calculate the x intersection coordinate of the line from (0,0) to (seg_endX,seg_endY)
// with the horizontal line at the new refy position
...
...
polygon/polygon_test_point_inside.h
View file @
d536f9d9
...
...
@@ -2,18 +2,34 @@
// Name: polygon_test_point_inside.h
/////////////////////////////////////////////////////////////////////////////
using
namespace
std
;
#ifndef __WXWINDOWS__
// define here wxPoint if we want to compile outside wxWidgets
class
wxPoint
{
public
:
int
x
,
y
;
};
#endif
/** Function TestPointInsidePolygon
* test if a point is inside or outside a polygon.
* @param aPolysList: the list of polygons
* @param
i
start: the starting point of a given polygon in m_FilledPolysList.
* @param
i
end: the ending point of the polygon in m_FilledPolysList.
* @param
refx, r
efy: the point coordinate to test
* @param
aIdx
start: the starting point of a given polygon in m_FilledPolysList.
* @param
aIdx
end: the ending point of the polygon in m_FilledPolysList.
* @param
aRefx, aR
efy: the point coordinate to test
* @return true if the point is inside, false for outside
*/
bool
TestPointInsidePolygon
(
std
::
vector
<
CPolyPt
>
aPolysList
,
int
istart
,
int
iend
,
int
refx
,
int
refy
);
int
aIdxstart
,
int
aIdxend
,
int
aRefx
,
int
aRefy
);
/** Function TestPointInsidePolygon (overlaid)
* same as previous, but mainly use wxPoint
* @param aPolysList: the list of polygons
* @param aCount: corners count in aPolysList.
* @param aRefPoint: the point coordinate to test
* @return true if the point is inside, false for outside
*/
bool
TestPointInsidePolygon
(
wxPoint
*
aPolysList
,
int
aCount
,
wxPoint
aRefPoint
);
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