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
d48f6e00
Commit
d48f6e00
authored
Jul 31, 2010
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Plain Diff
merge from testing
parents
1f18ff28
e2d4b16b
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
890 additions
and
502 deletions
+890
-502
CMakeLists.txt
CMakeLists.txt
+2
-2
iterator_geometry_to_set.hpp
include/boost/polygon/detail/iterator_geometry_to_set.hpp
+7
-7
polygon_45_formation.hpp
include/boost/polygon/detail/polygon_45_formation.hpp
+10
-4
polygon_45_set_view.hpp
include/boost/polygon/detail/polygon_45_set_view.hpp
+2
-2
polygon_90_set_view.hpp
include/boost/polygon/detail/polygon_90_set_view.hpp
+2
-2
polygon_90_touch.hpp
include/boost/polygon/detail/polygon_90_touch.hpp
+1
-1
polygon_arbitrary_formation.hpp
include/boost/polygon/detail/polygon_arbitrary_formation.hpp
+44
-19
polygon_formation.hpp
include/boost/polygon/detail/polygon_formation.hpp
+1
-1
polygon_set_view.hpp
include/boost/polygon/detail/polygon_set_view.hpp
+2
-2
scan_arbitrary.hpp
include/boost/polygon/detail/scan_arbitrary.hpp
+300
-300
point_data.hpp
include/boost/polygon/point_data.hpp
+15
-3
polygon_45_data.hpp
include/boost/polygon/polygon_45_data.hpp
+1
-1
polygon_45_set_data.hpp
include/boost/polygon/polygon_45_set_data.hpp
+3
-3
polygon_45_set_traits.hpp
include/boost/polygon/polygon_45_set_traits.hpp
+1
-1
polygon_45_with_holes_data.hpp
include/boost/polygon/polygon_45_with_holes_data.hpp
+3
-1
polygon_90_set_data.hpp
include/boost/polygon/polygon_90_set_data.hpp
+303
-1
polygon_data.hpp
include/boost/polygon/polygon_data.hpp
+1
-1
polygon_set_data.hpp
include/boost/polygon/polygon_set_data.hpp
+189
-49
polygon_set_traits.hpp
include/boost/polygon/polygon_set_traits.hpp
+1
-1
polygon_with_holes_data.hpp
include/boost/polygon/polygon_with_holes_data.hpp
+1
-1
zones_convert_brd_items_to_polygons_with_Boost.cpp
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
+1
-100
No files found.
CMakeLists.txt
View file @
d48f6e00
...
...
@@ -19,10 +19,10 @@ option(KICAD_MINIZIP "enable/disable building minizip (default ON)" ON)
option
(
wxUSE_UNICODE
"enable/disable building unicode (default OFF)"
)
option
(
KICAD_GOST
"enable/disable building using GOST notation for multiple gates per package (default OFF)"
)
option
(
USE_WX_ZOOM
"Use wxDC to perform zooming (default OFF).
Warning, this is experimental"
)
option
(
USE_WX_ZOOM
"Use wxDC to perform zooming (default OFF). Warning, this is experimental"
)
option
(
USE_WX_GRAPHICS_CONTEXT
"Use wxGraphicsContext for rendering (default OFF).
Warning, this is experimental"
)
"Use wxGraphicsContext for rendering (default OFF). Warning, this is experimental"
)
option
(
USE_BOOST_POLYGON_LIBRARY
"Use boost polygon library instead of Kbool to calculate filled areas in zones (default OFF). Warning, this is experimental"
)
...
...
include/boost/polygon/detail/iterator_geometry_to_set.hpp
View file @
d48f6e00
...
...
@@ -29,7 +29,7 @@ private:
public
:
iterator_geometry_to_set
()
:
rectangle_
(),
vertex_
(),
corner_
(
4
),
orient_
(),
is_hole_
()
{}
iterator_geometry_to_set
(
const
rectangle_type
&
rectangle
,
direction_1d
dir
,
orientation_2d
orient
=
HORIZONTAL
,
bool
is_hole
=
false
)
:
orientation_2d
orient
=
HORIZONTAL
,
bool
is_hole
=
false
,
bool
=
false
,
direction_1d
=
CLOCKWISE
)
:
rectangle_
(),
vertex_
(),
corner_
(
0
),
orient_
(
orient
),
is_hole_
(
is_hole
)
{
assign
(
rectangle_
,
rectangle
);
if
(
dir
==
HIGH
)
corner_
=
4
;
...
...
@@ -93,7 +93,7 @@ private:
int
polygon_index
;
public
:
iterator_geometry_to_set
()
:
vertex_
(),
itrb
(),
itre
(),
last_vertex_
(),
is_hole_
(),
multiplier_
(),
first_pt
(),
second_pt
(),
pts
(),
use_wrap
(),
orient_
(),
polygon_index
(
-
1
)
{}
iterator_geometry_to_set
(
const
polygon_type
&
polygon
,
direction_1d
dir
,
orientation_2d
orient
=
HORIZONTAL
,
bool
is_hole
=
false
)
:
iterator_geometry_to_set
(
const
polygon_type
&
polygon
,
direction_1d
dir
,
orientation_2d
orient
=
HORIZONTAL
,
bool
is_hole
=
false
,
bool
winding_override
=
false
,
direction_1d
w
=
CLOCKWISE
)
:
vertex_
(),
itrb
(),
itre
(),
last_vertex_
(),
is_hole_
(
is_hole
),
multiplier_
(),
first_pt
(),
second_pt
(),
pts
(),
use_wrap
(),
orient_
(
orient
),
polygon_index
(
0
)
{
...
...
@@ -103,7 +103,9 @@ public:
if
(
itrb
==
itre
||
dir
==
HIGH
||
size
(
polygon
)
<
4
)
{
polygon_index
=
-
1
;
}
else
{
direction_1d
wdir
=
winding
(
polygon
);
direction_1d
wdir
=
w
;
if
(
!
winding_override
)
wdir
=
winding
(
polygon
);
multiplier_
=
wdir
==
LOW
?
-
1
:
1
;
if
(
is_hole_
)
multiplier_
*=
-
1
;
first_pt
=
pts
[
0
]
=
*
itrb
;
...
...
@@ -182,9 +184,7 @@ public:
vertex_
.
second
.
first
=
pts
[
1
].
get
(
orient_
);
if
(
pts
[
1
]
==
pts
[
2
])
{
vertex_
.
second
.
second
=
0
;
return
;
}
if
(
pts
[
0
].
get
(
HORIZONTAL
)
!=
pts
[
1
].
get
(
HORIZONTAL
))
{
}
else
if
(
pts
[
0
].
get
(
HORIZONTAL
)
!=
pts
[
1
].
get
(
HORIZONTAL
))
{
vertex_
.
second
.
second
=
-
1
;
}
else
if
(
pts
[
0
].
get
(
VERTICAL
)
!=
pts
[
1
].
get
(
VERTICAL
))
{
vertex_
.
second
.
second
=
1
;
...
...
@@ -214,7 +214,7 @@ private:
public
:
iterator_geometry_to_set
()
:
itrb
(),
itre
(),
itrhib
(),
itrhie
(),
itrhb
(),
itrhe
(),
orient_
(),
is_hole_
(),
started_holes
()
{}
iterator_geometry_to_set
(
const
polygon_with_holes_type
&
polygon
,
direction_1d
dir
,
orientation_2d
orient
=
HORIZONTAL
,
bool
is_hole
=
false
)
:
orientation_2d
orient
=
HORIZONTAL
,
bool
is_hole
=
false
,
bool
=
false
,
direction_1d
=
CLOCKWISE
)
:
itrb
(),
itre
(),
itrhib
(),
itrhie
(),
itrhb
(),
itrhe
(),
orient_
(
orient
),
is_hole_
(
is_hole
),
started_holes
()
{
itre
=
iterator_geometry_to_set
<
polygon_90_concept
,
polygon_with_holes_type
>
(
polygon
,
HIGH
,
orient
,
is_hole_
);
itrhe
=
end_holes
(
polygon
);
...
...
include/boost/polygon/detail/polygon_45_formation.hpp
View file @
d48f6e00
...
...
@@ -251,12 +251,14 @@ namespace boost { namespace polygon{
return
;
}
Unit
firstY
=
(
*
iter
).
y
();
Unit
firstX
=
(
*
iter
).
x
();
++
iter
;
if
(
iter
==
tailp_
->
points
.
end
())
{
tailp_
->
points
.
push_front
(
point
);
return
;
}
if
(
iter
->
y
()
==
point
.
y
()
&&
firstY
==
point
.
y
())
{
if
((
iter
->
y
()
==
point
.
y
()
&&
firstY
==
point
.
y
())
||
(
iter
->
x
()
==
point
.
x
()
&&
firstX
==
point
.
x
())){
--
iter
;
*
iter
=
point
;
}
else
{
...
...
@@ -274,12 +276,14 @@ namespace boost { namespace polygon{
return
;
}
Unit
firstY
=
(
*
iter
).
y
();
Unit
firstX
=
(
*
iter
).
x
();
++
iter
;
if
(
iter
==
tailp_
->
points
.
rend
())
{
tailp_
->
points
.
push_back
(
point
);
return
;
}
if
(
iter
->
y
()
==
point
.
y
()
&&
firstY
==
point
.
y
())
{
if
((
iter
->
y
()
==
point
.
y
()
&&
firstY
==
point
.
y
())
||
(
iter
->
x
()
==
point
.
x
()
&&
firstX
==
point
.
x
())){
--
iter
;
*
iter
=
point
;
}
else
{
...
...
@@ -474,7 +478,7 @@ namespace boost { namespace polygon{
ct
counts
[
4
];
};
typedef
Vertex45CountT
<
int
>
Vertex45Count
;
typedef
Vertex45CountT
<
signed
char
>
Vertex45Count
;
// inline std::ostream& operator<< (std::ostream& o, const Vertex45Count& c) {
// o << c[0] << ", " << c[1] << ", ";
...
...
@@ -492,7 +496,8 @@ namespace boost { namespace polygon{
inline
Vertex45CompactT
(
const
Point
&
point
,
int
riseIn
,
int
countIn
)
:
pt
(
point
),
count
()
{
count
[
riseIn
+
1
]
=
countIn
;
}
inline
Vertex45CompactT
(
const
Vertex45T
&
vertex
)
:
pt
(
vertex
.
pt
),
count
()
{
template
<
typename
ct2
>
inline
Vertex45CompactT
(
const
typename
boolean_op_45
<
Unit
>::
template
Vertex45T
<
ct2
>&
vertex
)
:
pt
(
vertex
.
pt
),
count
()
{
count
[
vertex
.
rise
+
1
]
=
vertex
.
count
;
}
inline
Vertex45CompactT
(
const
Vertex45CompactT
&
vertex
)
:
pt
(
vertex
.
pt
),
count
(
vertex
.
count
)
{}
...
...
@@ -2244,6 +2249,7 @@ namespace boost { namespace polygon{
struct
geometry_concept
<
PolyLine45PolygonData
<
T
>
>
{
typedef
polygon_45_with_holes_concept
type
;
};
template
<
typename
T
>
struct
geometry_concept
<
PolyLine45HoleData
<
T
>
>
{
typedef
polygon_45_concept
type
;
};
}
}
#endif
include/boost/polygon/detail/polygon_45_set_view.hpp
View file @
d48f6e00
...
...
@@ -124,13 +124,13 @@ namespace boost { namespace polygon{
};
template
<
typename
ltype
,
typename
rtype
,
int
op_type
>
typename
polygon_45_set_
view
<
ltype
,
rtype
,
op_type
>::
iterator_type
typename
polygon_45_set_
traits
<
polygon_45_set_view
<
ltype
,
rtype
,
op_type
>
>::
iterator_type
polygon_45_set_traits
<
polygon_45_set_view
<
ltype
,
rtype
,
op_type
>
>::
begin
(
const
polygon_45_set_view
<
ltype
,
rtype
,
op_type
>&
polygon_45_set
)
{
return
polygon_45_set
.
begin
();
}
template
<
typename
ltype
,
typename
rtype
,
int
op_type
>
typename
polygon_45_set_
view
<
ltype
,
rtype
,
op_type
>::
iterator_type
typename
polygon_45_set_
traits
<
polygon_45_set_view
<
ltype
,
rtype
,
op_type
>
>::
iterator_type
polygon_45_set_traits
<
polygon_45_set_view
<
ltype
,
rtype
,
op_type
>
>::
end
(
const
polygon_45_set_view
<
ltype
,
rtype
,
op_type
>&
polygon_45_set
)
{
return
polygon_45_set
.
end
();
...
...
include/boost/polygon/detail/polygon_90_set_view.hpp
View file @
d48f6e00
...
...
@@ -140,13 +140,13 @@ namespace boost { namespace polygon{
};
template
<
typename
ltype
,
typename
rtype
,
typename
op_type
>
typename
polygon_90_set_
view
<
ltype
,
rtype
,
op_type
>::
iterator_type
typename
polygon_90_set_
traits
<
polygon_90_set_view
<
ltype
,
rtype
,
op_type
>
>::
iterator_type
polygon_90_set_traits
<
polygon_90_set_view
<
ltype
,
rtype
,
op_type
>
>::
begin
(
const
polygon_90_set_view
<
ltype
,
rtype
,
op_type
>&
polygon_set
)
{
return
polygon_set
.
begin
();
}
template
<
typename
ltype
,
typename
rtype
,
typename
op_type
>
typename
polygon_90_set_
view
<
ltype
,
rtype
,
op_type
>::
iterator_type
typename
polygon_90_set_
traits
<
polygon_90_set_view
<
ltype
,
rtype
,
op_type
>
>::
iterator_type
polygon_90_set_traits
<
polygon_90_set_view
<
ltype
,
rtype
,
op_type
>
>::
end
(
const
polygon_90_set_view
<
ltype
,
rtype
,
op_type
>&
polygon_set
)
{
return
polygon_set
.
end
();
...
...
include/boost/polygon/detail/polygon_90_touch.hpp
View file @
d48f6e00
...
...
@@ -42,7 +42,7 @@ namespace boost { namespace polygon{
ivlIds_
.
second
=
that
.
ivlIds_
.
second
;
incremented_
=
that
.
incremented_
;
return
*
this
;
}
;
}
inline
bool
operator
==
(
const
iterator
&
that
)
{
return
itr_
==
that
.
itr_
;
}
inline
bool
operator
!=
(
const
iterator
&
that
)
{
return
itr_
!=
that
.
itr_
;
}
inline
iterator
&
operator
++
()
{
...
...
include/boost/polygon/detail/polygon_arbitrary_formation.hpp
View file @
d48f6e00
...
...
@@ -388,7 +388,8 @@ namespace boost { namespace polygon{
struct
compute_intersection_pack
{
typedef
typename
high_precision_type
<
Unit
>::
type
high_precision
;
high_precision
y_high
,
dx1
,
dy1
,
dx2
,
dy2
,
x11
,
x21
,
y11
,
y21
,
x_num
,
y_num
,
x_den
,
y_den
,
x
,
y
;
static
inline
bool
compute_lazy_intersection
(
Point
&
intersection
,
const
half_edge
&
he1
,
const
half_edge
&
he2
,
bool
projected
=
false
)
{
static
inline
bool
compute_lazy_intersection
(
Point
&
intersection
,
const
half_edge
&
he1
,
const
half_edge
&
he2
,
bool
projected
=
false
,
bool
round_closest
=
false
)
{
long
double
y_high
,
dx1
,
dy1
,
dx2
,
dy2
,
x11
,
x21
,
y11
,
y21
,
x_num
,
y_num
,
x_den
,
y_den
,
x
,
y
;
typedef
rectangle_data
<
Unit
>
Rectangle
;
Rectangle
rect1
,
rect2
;
...
...
@@ -445,6 +446,10 @@ namespace boost { namespace polygon{
//std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl;
//Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
//Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
if
(
round_closest
)
{
x
=
x
+
0.5
;
y
=
y
+
0.5
;
}
Unit
x_unit
=
(
Unit
)(
x
);
Unit
y_unit
=
(
Unit
)(
y
);
//truncate downward if it went up due to negative number
...
...
@@ -463,12 +468,17 @@ namespace boost { namespace polygon{
(
long
double
)
(
std
::
numeric_limits
<
Unit
>::
min
)(),
(
long
double
)(
std
::
numeric_limits
<
Unit
>::
max
)(),
(
long
double
)
(
std
::
numeric_limits
<
Unit
>::
max
)()
);
return
contains
(
inf_rect
,
intersection
,
true
);
if
(
contains
(
inf_rect
,
intersection
,
true
))
{
intersection
=
result
;
return
true
;
}
else
return
false
;
}
intersection
=
result
;
return
true
;
}
inline
bool
compute_intersection
(
Point
&
intersection
,
const
half_edge
&
he1
,
const
half_edge
&
he2
,
bool
projected
=
false
)
{
inline
bool
compute_intersection
(
Point
&
intersection
,
const
half_edge
&
he1
,
const
half_edge
&
he2
,
bool
projected
=
false
,
bool
round_closest
=
false
)
{
if
(
!
projected
&&
!
intersects
(
he1
,
he2
))
return
false
;
bool
lazy_success
=
compute_lazy_intersection
(
intersection
,
he1
,
he2
,
projected
);
...
...
@@ -536,6 +546,10 @@ namespace boost { namespace polygon{
//std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl;
//Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
//Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
if
(
round_closest
)
{
x
=
x
+
(
high_precision
)
0.5
;
y
=
y
+
(
high_precision
)
0.5
;
}
Unit
x_unit
=
convert_high_precision_type
<
Unit
>
(
x
);
Unit
y_unit
=
convert_high_precision_type
<
Unit
>
(
y
);
//truncate downward if it went up due to negative number
...
...
@@ -549,6 +563,17 @@ namespace boost { namespace polygon{
Point
result
(
x_unit
,
y_unit
);
if
(
!
contains
(
rect1
,
result
,
true
))
return
false
;
if
(
!
contains
(
rect2
,
result
,
true
))
return
false
;
if
(
projected
)
{
rectangle_data
<
long
double
>
inf_rect
((
long
double
)(
std
::
numeric_limits
<
Unit
>::
min
)(),
(
long
double
)
(
std
::
numeric_limits
<
Unit
>::
min
)(),
(
long
double
)(
std
::
numeric_limits
<
Unit
>::
max
)(),
(
long
double
)
(
std
::
numeric_limits
<
Unit
>::
max
)()
);
if
(
contains
(
inf_rect
,
intersection
,
true
))
{
intersection
=
result
;
return
true
;
}
else
return
false
;
}
intersection
=
result
;
return
true
;
}
...
...
@@ -872,7 +897,7 @@ namespace boost { namespace polygon{
inline
active_tail_arbitrary
(
const
vertex_half_edge
&
vertex
,
active_tail_arbitrary
*
otherTailp
=
0
)
:
tailp_
(),
otherTailp_
(),
holesList_
(),
head_
()
{
tailp_
=
new
poly_line_arbitrary
;
tailp_
->
points
.
push_back
(
vertex
.
pt
);
bool
headArray
[
4
]
=
{
false
,
true
,
true
,
true
};
//
bool headArray[4] = {false, true, true, true};
bool
inverted
=
vertex
.
count
==
-
1
;
head_
=
(
!
vertex
.
is_vertical
)
^
inverted
;
otherTailp_
=
otherTailp
;
...
...
@@ -1172,7 +1197,7 @@ namespace boost { namespace polygon{
inline
less_half_edge_count
()
:
pt_
()
{}
inline
less_half_edge_count
(
Point
point
)
:
pt_
(
point
)
{}
inline
bool
operator
()
(
const
std
::
pair
<
Point
,
int
>&
elm1
,
const
std
::
pair
<
Point
,
int
>&
elm2
)
const
{
return
less_slope
(
pt_
.
get
(
HORIZONTAL
),
pt_
.
get
(
VERTICAL
),
elm1
.
first
,
elm2
.
first
);
return
scanline_base
<
Unit
>::
less_slope
(
pt_
.
get
(
HORIZONTAL
),
pt_
.
get
(
VERTICAL
),
elm1
.
first
,
elm2
.
first
);
}
};
...
...
@@ -1196,7 +1221,7 @@ namespace boost { namespace polygon{
Unit
dx2
=
elm2
.
first
.
first
.
first
.
get
(
HORIZONTAL
)
-
elm2
.
first
.
first
.
second
.
get
(
HORIZONTAL
);
Unit
dy1
=
elm1
.
first
.
first
.
first
.
get
(
VERTICAL
)
-
elm1
.
first
.
first
.
second
.
get
(
VERTICAL
);
Unit
dy2
=
elm2
.
first
.
first
.
first
.
get
(
VERTICAL
)
-
elm2
.
first
.
first
.
second
.
get
(
VERTICAL
);
return
less_slope
(
dx1
,
dy1
,
dx2
,
dy2
);
return
scanline_base
<
Unit
>::
less_slope
(
dx1
,
dy1
,
dx2
,
dy2
);
}
};
...
...
@@ -1356,7 +1381,7 @@ namespace boost { namespace polygon{
bool
have_vertical_tail_from_below
=
false
;
if
(
c_size
&&
is_vertical
(
counts_from_scanline
.
back
().
first
.
first
))
{
scanline_base
<
Unit
>::
is_vertical
(
counts_from_scanline
.
back
().
first
.
first
))
{
have_vertical_tail_from_below
=
true
;
}
//assert size = size_less_1 + 1
...
...
@@ -1704,7 +1729,7 @@ namespace boost { namespace polygon{
//std::cout << "checking whether ot handle hole\n";
if
(
currentIter
==
inputEnd
||
currentIter
->
pt
.
get
(
HORIZONTAL
)
!=
x_
||
on_above_or_below
(
currentIter
->
pt
,
half_edge
(
iter
->
first
.
pt
,
iter
->
first
.
other_pt
))
!=
-
1
)
{
scanline_base
<
Unit
>::
on_above_or_below
(
currentIter
->
pt
,
half_edge
(
iter
->
first
.
pt
,
iter
->
first
.
other_pt
))
!=
-
1
)
{
//(high_precision)(currentIter->pt.get(VERTICAL)) >= iter->first.evalAtX(x_)) {
//std::cout << "handle hole here\n";
...
...
@@ -2041,26 +2066,26 @@ namespace boost { namespace polygon{
he2
.
first
=
Point
(
0
,
0
);
he2
.
second
=
Point
(
10
,
20
);
Point
result
;
bool
b
=
compute_intersection
(
result
,
he1
,
he2
);
bool
b
=
scanline_base
<
Unit
>::
compute_intersection
(
result
,
he1
,
he2
);
if
(
!
b
||
result
!=
Point
(
0
,
0
))
return
false
;
he1
.
first
=
Point
(
0
,
10
);
b
=
compute_intersection
(
result
,
he1
,
he2
);
b
=
scanline_base
<
Unit
>::
compute_intersection
(
result
,
he1
,
he2
);
if
(
!
b
||
result
!=
Point
(
5
,
10
))
return
false
;
he1
.
first
=
Point
(
0
,
11
);
b
=
compute_intersection
(
result
,
he1
,
he2
);
b
=
scanline_base
<
Unit
>::
compute_intersection
(
result
,
he1
,
he2
);
if
(
!
b
||
result
!=
Point
(
5
,
10
))
return
false
;
he1
.
first
=
Point
(
0
,
0
);
he1
.
second
=
Point
(
1
,
9
);
he2
.
first
=
Point
(
0
,
9
);
he2
.
second
=
Point
(
1
,
0
);
b
=
compute_intersection
(
result
,
he1
,
he2
);
b
=
scanline_base
<
Unit
>::
compute_intersection
(
result
,
he1
,
he2
);
if
(
!
b
||
result
!=
Point
(
0
,
4
))
return
false
;
he1
.
first
=
Point
(
0
,
-
10
);
he1
.
second
=
Point
(
1
,
-
1
);
he2
.
first
=
Point
(
0
,
-
1
);
he2
.
second
=
Point
(
1
,
-
10
);
b
=
compute_intersection
(
result
,
he1
,
he2
);
b
=
scanline_base
<
Unit
>::
compute_intersection
(
result
,
he1
,
he2
);
if
(
!
b
||
result
!=
Point
(
0
,
-
5
))
return
false
;
he1
.
first
=
Point
((
std
::
numeric_limits
<
int
>::
max
)(),
(
std
::
numeric_limits
<
int
>::
max
)()
-
1
);
he1
.
second
=
Point
((
std
::
numeric_limits
<
int
>::
min
)(),
(
std
::
numeric_limits
<
int
>::
max
)());
...
...
@@ -2068,13 +2093,13 @@ namespace boost { namespace polygon{
he2
.
first
=
Point
((
std
::
numeric_limits
<
int
>::
max
)()
-
1
,
(
std
::
numeric_limits
<
int
>::
max
)());
he2
.
second
=
Point
((
std
::
numeric_limits
<
int
>::
max
)(),
(
std
::
numeric_limits
<
int
>::
min
)());
//he2.second = Point((std::numeric_limits<int>::max)(), 0);
b
=
compute_intersection
(
result
,
he1
,
he2
);
b
=
scanline_base
<
Unit
>::
compute_intersection
(
result
,
he1
,
he2
);
//b is false because of overflow error
he1
.
first
=
Point
(
1000
,
2000
);
he1
.
second
=
Point
(
1010
,
2010
);
he2
.
first
=
Point
(
1000
,
2000
);
he2
.
second
=
Point
(
1010
,
2020
);
b
=
compute_intersection
(
result
,
he1
,
he2
);
b
=
scanline_base
<
Unit
>::
compute_intersection
(
result
,
he1
,
he2
);
if
(
!
b
||
result
!=
Point
(
1000
,
2000
))
return
false
;
return
b
;
...
...
@@ -2301,7 +2326,7 @@ namespace boost { namespace polygon{
bool
have_vertical_tail_from_below
=
false
;
if
(
c_size
&&
is_vertical
(
counts_from_scanline
.
back
().
first
.
first
))
{
scanline_base
<
Unit
>::
is_vertical
(
counts_from_scanline
.
back
().
first
.
first
))
{
have_vertical_tail_from_below
=
true
;
}
//assert size = size_less_1 + 1
...
...
@@ -2607,7 +2632,7 @@ namespace boost { namespace polygon{
//std::cout << "current Y " << currentY << std::endl;
//std::cout << "scanline size " << scanData_.size() << std::endl;
//print(scanData_);
iterator
iter
=
lookUp_
(
currentY
);
iterator
iter
=
this
->
lookUp_
(
currentY
);
//std::cout << "found element in scanline " << (iter != scanData_.end()) << std::endl;
//int counts[4] = {0, 0, 0, 0};
incoming_count
counts_from_scanline
;
...
...
@@ -2634,7 +2659,7 @@ namespace boost { namespace polygon{
}
Point
currentPoint
(
polygon_arbitrary_formation
<
Unit
>::
x_
,
currentY
);
//std::cout << "counts_from_scanline size " << counts_from_scanline.size() << std::endl;
sort_incoming_count
(
counts_from_scanline
,
currentPoint
);
this
->
sort_incoming_count
(
counts_from_scanline
,
currentPoint
);
vertex_arbitrary_count
incoming
;
//std::cout << "aggregating\n";
...
...
@@ -2646,7 +2671,7 @@ namespace boost { namespace polygon{
}
while
(
currentIter
!=
inputEnd
&&
currentIter
->
pt
.
get
(
VERTICAL
)
==
currentY
&&
currentIter
->
pt
.
get
(
HORIZONTAL
)
==
polygon_arbitrary_formation
<
Unit
>::
x_
);
//print(incoming);
sort_vertex_arbitrary_count
(
incoming
,
currentPoint
);
this
->
sort_vertex_arbitrary_count
(
incoming
,
currentPoint
);
//std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << std::endl;
//print(incoming);
//std::cout << "incoming counts from input size " << incoming.size() << std::endl;
...
...
include/boost/polygon/detail/polygon_formation.hpp
View file @
d48f6e00
...
...
@@ -1721,7 +1721,7 @@ namespace polygon_formation {
unsigned
int
get_polygons
(
output_container
&
container
,
iterator_type
begin
,
iterator_type
end
,
orientation_2d
orient
,
bool
fracture_holes
,
concept_type
)
{
typedef
typename
output_container
::
value_type
polygon_type
;
typedef
typename
iterator_type
::
value_type
::
first_type
coordinate_type
;
typedef
typename
std
::
iterator_traits
<
iterator_type
>
::
value_type
::
first_type
coordinate_type
;
polygon_type
poly
;
unsigned
int
countPolygons
=
0
;
typedef
typename
geometry_concept
<
polygon_type
>::
type
polygon_concept_type
;
...
...
include/boost/polygon/detail/polygon_set_view.hpp
View file @
d48f6e00
...
...
@@ -153,13 +153,13 @@ namespace boost { namespace polygon{
};
template
<
typename
ltype
,
typename
rtype
,
int
op_type
>
typename
polygon_set_
view
<
ltype
,
rtype
,
op_type
>::
iterator_type
typename
polygon_set_
traits
<
polygon_set_view
<
ltype
,
rtype
,
op_type
>
>::
iterator_type
polygon_set_traits
<
polygon_set_view
<
ltype
,
rtype
,
op_type
>
>::
begin
(
const
polygon_set_view
<
ltype
,
rtype
,
op_type
>&
polygon_set
)
{
return
polygon_set
.
begin
();
}
template
<
typename
ltype
,
typename
rtype
,
int
op_type
>
typename
polygon_set_
view
<
ltype
,
rtype
,
op_type
>::
iterator_type
typename
polygon_set_
traits
<
polygon_set_view
<
ltype
,
rtype
,
op_type
>
>::
iterator_type
polygon_set_traits
<
polygon_set_view
<
ltype
,
rtype
,
op_type
>
>::
end
(
const
polygon_set_view
<
ltype
,
rtype
,
op_type
>&
polygon_set
)
{
return
polygon_set
.
end
();
...
...
include/boost/polygon/detail/scan_arbitrary.hpp
View file @
d48f6e00
...
...
@@ -33,38 +33,38 @@ namespace boost { namespace polygon{
typedef
std
::
map
<
half_edge
,
std
::
set
<
segment_id
>
,
less_half_edge
>
edge_scanline
;
typedef
typename
edge_scanline
::
iterator
iterator
;
std
::
map
<
Unit
,
std
::
set
<
segment_id
>
>
vertical_data_
;
edge_scanline
edge_scanline_
;
Unit
x_
;
int
just_before_
;
segment_id
segment_id_
;
std
::
vector
<
std
::
pair
<
half_edge
,
int
>
>
event_edges_
;
std
::
set
<
Point
>
intersection_queue_
;
//
std::map<Unit, std::set<segment_id> > vertical_data_;
//
edge_scanline edge_scanline_;
//
Unit x_;
//
int just_before_;
//
segment_id segment_id_;
//
std::vector<std::pair<half_edge, int> > event_edges_;
//
std::set<Point> intersection_queue_;
public
:
inline
line_intersection
()
:
vertical_data_
(),
edge_scanline_
(),
x_
((
std
::
numeric_limits
<
Unit
>::
max
)()),
just_before_
(
0
),
segment_id_
(
0
),
event_edges_
(),
intersection_queue_
()
{
less_half_edge
lessElm
(
&
x_
,
&
just_before_
);
edge_scanline_
=
edge_scanline
(
lessElm
);
}
inline
line_intersection
(
const
line_intersection
&
that
)
:
vertical_data_
(),
edge_scanline_
(),
x_
(),
just_before_
(),
segment_id_
(),
event_edges_
(),
intersection_queue_
()
{
(
*
this
)
=
that
;
}
inline
line_intersection
&
operator
=
(
const
line_intersection
&
that
)
{
x_
=
that
.
x_
;
just_before_
=
that
.
just_before_
;
segment_id_
=
that
.
segment_id_
;
//
inline line_intersection() : vertical_data_(), edge_scanline_(), x_((std::numeric_limits<Unit>::max)()), just_before_(0), segment_id_(0), event_edges_(), intersection_queue_() {
//
less_half_edge lessElm(&x_, &just_before_);
//
edge_scanline_ = edge_scanline(lessElm);
//
}
//
inline line_intersection(const line_intersection& that) : vertical_data_(), edge_scanline_(), x_(), just_before_(), segment_id_(), event_edges_(), intersection_queue_() { (*this) = that; }
//
inline line_intersection& operator=(const line_intersection& that) {
//
x_ = that.x_;
//
just_before_ = that.just_before_;
//
segment_id_ = that.segment_id_;
//I cannot simply copy that.edge_scanline_ to this edge_scanline_ becuase the functor store pointers to other members!
less_half_edge
lessElm
(
&
x_
,
&
just_before_
);
edge_scanline_
=
edge_scanline
(
lessElm
);
//
//I cannot simply copy that.edge_scanline_ to this edge_scanline_ becuase the functor store pointers to other members!
//
less_half_edge lessElm(&x_, &just_before_);
//
edge_scanline_ = edge_scanline(lessElm);
edge_scanline_
.
insert
(
that
.
edge_scanline_
.
begin
(),
that
.
edge_scanline_
.
end
());
return
*
this
;
}
//
edge_scanline_.insert(that.edge_scanline_.begin(), that.edge_scanline_.end());
//
return *this;
//
}
static
inline
void
between
(
Point
pt
,
Point
pt1
,
Point
pt2
)
{
less_point
lp
;
if
(
lp
(
pt1
,
pt2
))
return
lp
(
pt
,
pt2
)
&&
lp
(
pt1
,
pt
);
return
lp
(
pt
,
pt1
)
&&
lp
(
pt2
,
pt
);
}
//
static inline void between(Point pt, Point pt1, Point pt2) {
//
less_point lp;
//
if(lp(pt1, pt2))
//
return lp(pt, pt2) && lp(pt1, pt);
//
return lp(pt, pt1) && lp(pt2, pt);
//
}
template
<
typename
iT
>
static
inline
void
compute_histogram_in_y
(
iT
begin
,
iT
end
,
std
::
size_t
size
,
std
::
vector
<
std
::
pair
<
Unit
,
std
::
pair
<
std
::
size_t
,
std
::
size_t
>
>
>&
histogram
)
{
...
...
@@ -216,7 +216,7 @@ namespace boost { namespace polygon{
//itr2 = pts.end();
while
(
lfinger
!=
newend
&&
(
*
lfinger
).
x
()
<
startpt
.
x
())
++
lfinger
;
for
(
typename
std
::
vector
<
Point
>::
iterator
itr
=
lfinger
;
itr
!=
newend
&&
(
*
itr
).
x
()
<=
stoppt
.
x
();
++
itr
)
{
if
(
intersects_grid
(
*
itr
,
he1
))
if
(
scanline_base
<
Unit
>::
intersects_grid
(
*
itr
,
he1
))
intersection_points
[
id1
].
insert
(
*
itr
);
}
}
...
...
@@ -243,8 +243,8 @@ namespace boost { namespace polygon{
//edge changed orientation, invert count on edge
output_segments
.
back
().
second
.
second
*=
-
1
;
}
if
(
!
is_vertical
(
input_segments
[
intermediate_segments
[
i
].
second
].
first
)
&&
is_vertical
(
output_segments
.
back
().
first
))
{
if
(
!
scanline_base
<
Unit
>::
is_vertical
(
input_segments
[
intermediate_segments
[
i
].
second
].
first
)
&&
scanline_base
<
Unit
>::
is_vertical
(
output_segments
.
back
().
first
))
{
output_segments
.
back
().
second
.
second
*=
-
1
;
}
if
(
lp
(
output_segments
.
back
().
first
.
second
,
output_segments
.
back
().
first
.
first
))
{
...
...
@@ -349,7 +349,7 @@ namespace boost { namespace polygon{
segment_id
id
=
(
*
iter
).
second
;
const
std
::
set
<
Point
>&
pts
=
intersection_points
[
id
];
Point
hpt
(
he
.
first
.
get
(
HORIZONTAL
)
+
1
,
he
.
first
.
get
(
VERTICAL
));
if
(
!
is_vertical
(
he
)
&&
less_slope
(
he
.
first
.
get
(
HORIZONTAL
),
he
.
first
.
get
(
VERTICAL
),
if
(
!
scanline_base
<
Unit
>::
is_vertical
(
he
)
&&
scanline_base
<
Unit
>::
less_slope
(
he
.
first
.
get
(
HORIZONTAL
),
he
.
first
.
get
(
VERTICAL
),
he
.
second
,
hpt
))
{
//slope is below horizontal
std
::
vector
<
Point
>
tmpPts
;
...
...
@@ -365,263 +365,263 @@ namespace boost { namespace polygon{
}
}
//iT iterator over unsorted pair<Point> representing line segments of input
//output_segments is populated with fully intersected output line segment half
//edges and the index of the input segment that they are assoicated with
//duplicate output half edges with different ids will be generated in the case
//that parallel input segments intersection
//outputs are in sorted order and include both begin and end events for
//each segment
template
<
typename
iT
>
inline
void
scan
(
std
::
vector
<
std
::
pair
<
half_edge
,
int
>
>&
output_segments
,
iT
begin
,
iT
end
)
{
std
::
map
<
segment_id
,
std
::
set
<
Point
>
>
intersection_points
;
scan
(
intersection_points
,
begin
,
end
);
segment_intersections
(
output_segments
,
intersection_points
,
begin
,
end
);
}
//iT iterator over sorted sequence of half edge, segment id pairs representing segment begin and end points
//intersection points provides a mapping from input segment id (vector index) to the set
//of intersection points assocated with that input segment
template
<
typename
iT
>
inline
void
scan
(
std
::
map
<
segment_id
,
std
::
set
<
Point
>
>&
intersection_points
,
iT
begin
,
iT
end
)
{
for
(
iT
iter
=
begin
;
iter
!=
end
;
++
iter
)
{
const
std
::
pair
<
half_edge
,
int
>&
elem
=
*
iter
;
const
half_edge
&
he
=
elem
.
first
;
Unit
current_x
=
he
.
first
.
get
(
HORIZONTAL
);
if
(
current_x
!=
x_
)
{
process_scan_event
(
intersection_points
);
while
(
!
intersection_queue_
.
empty
()
&&
(
*
(
intersection_queue_
.
begin
()).
get
(
HORIZONTAL
)
<
current_x
))
{
x_
=
*
(
intersection_queue_
.
begin
()).
get
(
HORIZONTAL
);
process_intersections_at_scan_event
(
intersection_points
);
}
x_
=
current_x
;
}
event_edges_
.
push_back
(
elem
);
}
process_scan_event
(
intersection_points
);
}
inline
iterator
lookup
(
const
half_edge
&
he
)
{
return
edge_scanline_
.
find
(
he
);
}
inline
void
insert_into_scanline
(
const
half_edge
&
he
,
int
id
)
{
edge_scanline_
[
he
].
insert
(
id
);
}
inline
void
lookup_and_remove
(
const
half_edge
&
he
,
int
id
)
{
iterator
remove_iter
=
lookup
(
he
);
if
(
remove_iter
==
edge_scanline_
.
end
())
{
//std::cout << "failed to find removal segment in scanline\n";
return
;
}
std
::
set
<
segment_id
>&
ids
=
(
*
remove_iter
).
second
;
std
::
set
<
segment_id
>::
iterator
id_iter
=
ids
.
find
(
id
);
if
(
id_iter
==
ids
.
end
())
{
//std::cout << "failed to find removal segment id in scanline set\n";
return
;
}
ids
.
erase
(
id_iter
);
if
(
ids
.
empty
())
edge_scanline_
.
erase
(
remove_iter
);
}
static
inline
void
update_segments
(
std
::
map
<
segment_id
,
std
::
set
<
Point
>
>&
intersection_points
,
const
std
::
set
<
segment_id
>&
segments
,
Point
pt
)
{
for
(
std
::
set
<
segment_id
>::
const_iterator
itr
=
segments
.
begin
();
itr
!=
segments
.
end
();
++
itr
)
{
intersection_points
[
*
itr
].
insert
(
pt
);
}
}
inline
void
process_intersections_at_scan_event
(
std
::
map
<
segment_id
,
std
::
set
<
Point
>
>&
intersection_points
)
{
//there may be additional intersection points at this x location that haven't been
//found yet if vertical or near vertical line segments intersect more than
//once before the next x location
just_before_
=
true
;
std
::
set
<
iterator
>
intersecting_elements
;
std
::
set
<
Unit
>
intersection_locations
;
typedef
typename
std
::
set
<
Point
>::
iterator
intersection_iterator
;
intersection_iterator
iter
;
//first find all secondary intersection locations and all scanline iterators
//that are intersecting
for
(
iter
=
intersection_queue_
.
begin
();
iter
!=
intersection_queue_
.
end
()
&&
(
*
iter
).
get
(
HORIZONTAL
)
==
x_
;
++
iter
)
{
Point
pt
=
*
iter
;
Unit
y
=
pt
.
get
(
VERTICAL
);
intersection_locations
.
insert
(
y
);
//if x_ is max there can be only end events and no sloping edges
if
(
x_
!=
(
std
::
numeric_limits
<
Unit
>::
max
)())
{
//deal with edges that project to the right of scanline
//first find the edges in the scanline adjacent to primary intersectin points
//lookup segment in scanline at pt
iterator
itr
=
edge_scanline_
.
lower_bound
(
half_edge
(
pt
,
Point
(
x_
+
1
,
y
)));
//look above pt in scanline until reaching end or segment that doesn't intersect
//1x1 grid upper right of pt
//look below pt in scanline until reaching begin or segment that doesn't interset
//1x1 grid upper right of pt
//second find edges in scanline on the y interval of each edge found in the previous
//step for x_ to x_ + 1
//third find overlaps in the y intervals of all found edges to find all
//secondary intersection points
}
}
//erase the intersection points from the queue
intersection_queue_
.
erase
(
intersection_queue_
.
begin
(),
iter
);
std
::
vector
<
scanline_element
>
insertion_edges
;
insertion_edges
.
reserve
(
intersecting_elements
.
size
());
std
::
vector
<
std
::
pair
<
Unit
,
iterator
>
>
sloping_ends
;
//do all the work of updating the output of all intersecting
for
(
typename
std
::
set
<
iterator
>::
iterator
inter_iter
=
intersecting_elements
.
begin
();
inter_iter
!=
intersecting_elements
.
end
();
++
inter_iter
)
{
//if it is horizontal update it now and continue
if
(
is_horizontal
((
*
inter_iter
).
first
))
{
update_segments
(
intersection_points
,
(
*
inter_iter
).
second
,
Point
(
x_
,
(
*
inter_iter
).
first
.
get
(
VERTICAL
)));
}
else
{
//if x_ is max there can be only end events and no sloping edges
if
(
x_
!=
(
std
::
numeric_limits
<
Unit
>::
max
)())
{
//insert its end points into the vector of sloping ends
const
half_edge
&
he
=
(
*
inter_iter
).
first
;
Unit
y
=
evalAtXforY
(
x_
,
he
.
first
,
he
.
second
);
Unit
y2
=
evalAtXforY
(
x_
+
1
,
he
.
first
,
he
.
second
);
if
(
y2
>=
y
)
y2
+=
1
;
//we round up, in exact case we don't worry about overbite of one
else
y
+=
1
;
//downward sloping round up
sloping_ends
.
push_back
(
std
::
make_pair
(
y
,
inter_iter
));
sloping_ends
.
push_back
(
std
::
make_pair
(
y2
,
inter_iter
));
}
}
}
//
//iT iterator over unsorted pair<Point> representing line segments of input
//
//output_segments is populated with fully intersected output line segment half
//
//edges and the index of the input segment that they are assoicated with
//
//duplicate output half edges with different ids will be generated in the case
//
//that parallel input segments intersection
//
//outputs are in sorted order and include both begin and end events for
//
//each segment
//
template <typename iT>
//
inline void scan(std::vector<std::pair<half_edge, int> >& output_segments,
//
iT begin, iT end) {
//
std::map<segment_id, std::set<Point> > intersection_points;
//
scan(intersection_points, begin, end);
//
segment_intersections(output_segments, intersection_points, begin, end);
//
}
//
//iT iterator over sorted sequence of half edge, segment id pairs representing segment begin and end points
//
//intersection points provides a mapping from input segment id (vector index) to the set
//
//of intersection points assocated with that input segment
//
template <typename iT>
//
inline void scan(std::map<segment_id, std::set<Point> >& intersection_points,
//
iT begin, iT end) {
//
for(iT iter = begin; iter != end; ++iter) {
//
const std::pair<half_edge, int>& elem = *iter;
//
const half_edge& he = elem.first;
//
Unit current_x = he.first.get(HORIZONTAL);
//
if(current_x != x_) {
//
process_scan_event(intersection_points);
//
while(!intersection_queue_.empty() &&
//
(*(intersection_queue_.begin()).get(HORIZONTAL) < current_x)) {
//
x_ = *(intersection_queue_.begin()).get(HORIZONTAL);
//
process_intersections_at_scan_event(intersection_points);
//
}
//
x_ = current_x;
//
}
//
event_edges_.push_back(elem);
//
}
//
process_scan_event(intersection_points);
//
}
//
inline iterator lookup(const half_edge& he) {
//
return edge_scanline_.find(he);
//
}
//
inline void insert_into_scanline(const half_edge& he, int id) {
//
edge_scanline_[he].insert(id);
//
}
//
inline void lookup_and_remove(const half_edge& he, int id) {
//
iterator remove_iter = lookup(he);
//
if(remove_iter == edge_scanline_.end()) {
//
//std::cout << "failed to find removal segment in scanline\n";
//
return;
//
}
//
std::set<segment_id>& ids = (*remove_iter).second;
//
std::set<segment_id>::iterator id_iter = ids.find(id);
//
if(id_iter == ids.end()) {
//
//std::cout << "failed to find removal segment id in scanline set\n";
//
return;
//
}
//
ids.erase(id_iter);
//
if(ids.empty())
//
edge_scanline_.erase(remove_iter);
//
}
//
static inline void update_segments(std::map<segment_id, std::set<Point> >& intersection_points,
//
const std::set<segment_id>& segments, Point pt) {
//
for(std::set<segment_id>::const_iterator itr = segments.begin(); itr != segments.end(); ++itr) {
//
intersection_points[*itr].insert(pt);
//
}
//
}
//
inline void process_intersections_at_scan_event(std::map<segment_id, std::set<Point> >& intersection_points) {
//
//there may be additional intersection points at this x location that haven't been
//
//found yet if vertical or near vertical line segments intersect more than
//
//once before the next x location
//
just_before_ = true;
//
std::set<iterator> intersecting_elements;
//
std::set<Unit> intersection_locations;
//
typedef typename std::set<Point>::iterator intersection_iterator;
//
intersection_iterator iter;
//
//first find all secondary intersection locations and all scanline iterators
//
//that are intersecting
//
for(iter = intersection_queue_.begin();
//
iter != intersection_queue_.end() && (*iter).get(HORIZONTAL) == x_; ++iter) {
//
Point pt = *iter;
//
Unit y = pt.get(VERTICAL);
//
intersection_locations.insert(y);
//
//if x_ is max there can be only end events and no sloping edges
//
if(x_ != (std::numeric_limits<Unit>::max)()) {
//
//deal with edges that project to the right of scanline
//
//first find the edges in the scanline adjacent to primary intersectin points
//
//lookup segment in scanline at pt
//
iterator itr = edge_scanline_.lower_bound(half_edge(pt, Point(x_+1, y)));
//
//look above pt in scanline until reaching end or segment that doesn't intersect
//
//1x1 grid upper right of pt
//
//look below pt in scanline until reaching begin or segment that doesn't interset
//
//1x1 grid upper right of pt
//
//second find edges in scanline on the y interval of each edge found in the previous
//
//step for x_ to x_ + 1
//
//third find overlaps in the y intervals of all found edges to find all
//
//secondary intersection points
//
}
//
}
//
//erase the intersection points from the queue
//
intersection_queue_.erase(intersection_queue_.begin(), iter);
//
std::vector<scanline_element> insertion_edges;
//
insertion_edges.reserve(intersecting_elements.size());
//
std::vector<std::pair<Unit, iterator> > sloping_ends;
//
//do all the work of updating the output of all intersecting
//
for(typename std::set<iterator>::iterator inter_iter = intersecting_elements.begin();
//
inter_iter != intersecting_elements.end(); ++inter_iter) {
//
//if it is horizontal update it now and continue
//
if(is_horizontal((*inter_iter).first)) {
//
update_segments(intersection_points, (*inter_iter).second, Point(x_, (*inter_iter).first.get(VERTICAL)));
//
} else {
//
//if x_ is max there can be only end events and no sloping edges
//
if(x_ != (std::numeric_limits<Unit>::max)()) {
//
//insert its end points into the vector of sloping ends
//
const half_edge& he = (*inter_iter).first;
//
Unit y = evalAtXforY(x_, he.first, he.second);
//
Unit y2 = evalAtXforY(x_+1, he.first, he.second);
//
if(y2 >= y) y2 +=1; //we round up, in exact case we don't worry about overbite of one
//
else y += 1; //downward sloping round up
//
sloping_ends.push_back(std::make_pair(y, inter_iter));
//
sloping_ends.push_back(std::make_pair(y2, inter_iter));
//
}
//
}
//
}
//merge sloping element data
std
::
sort
(
sloping_ends
.
begin
(),
sloping_ends
.
end
());
std
::
map
<
Unit
,
std
::
set
<
iterator
>
>
sloping_elements
;
std
::
set
<
iterator
>
merge_elements
;
for
(
typename
std
::
vector
<
std
::
pair
<
Unit
,
iterator
>
>::
iterator
slop_iter
=
sloping_ends
.
begin
();
slop_iter
=
sloping_ends
.
end
();
++
slop_iter
)
{
//merge into sloping elements
typename
std
::
set
<
iterator
>::
iterator
merge_iterator
=
merge_elements
.
find
((
*
slop_iter
).
second
);
if
(
merge_iterator
=
merge_elements
.
end
())
{
merge_elements
.
insert
((
*
slop_iter
).
second
);
}
else
{
merge_elements
.
erase
(
merge_iterator
);
}
sloping_elements
[(
*
slop_iter
).
first
]
=
merge_elements
;
}
//scan intersection points
typename
std
::
map
<
Unit
,
std
::
set
<
segment_id
>
>::
iterator
vertical_iter
=
vertical_data_
.
begin
();
typename
std
::
map
<
Unit
,
std
::
set
<
iterator
>
>::
iterator
sloping_iter
=
sloping_elements
.
begin
();
for
(
typename
std
::
set
<
Unit
>::
iterator
position_iter
=
intersection_locations
.
begin
();
position_iter
=
intersection_locations
.
end
();
++
position_iter
)
{
//look for vertical segments that intersect this point and update them
Unit
y
=
*
position_iter
;
Point
pt
(
x_
,
y
);
//handle vertical segments
if
(
vertical_iter
!=
vertical_data_
.
end
())
{
typename
std
::
map
<
Unit
,
std
::
set
<
segment_id
>
>::
iterator
next_vertical
=
vertical_iter
;
for
(
++
next_vertical
;
next_vertical
!=
vertical_data_
.
end
()
&&
(
*
next_vertical
).
first
<
y
;
++
next_vertical
)
{
vertical_iter
=
next_vertical
;
}
if
((
*
vertical_iter
).
first
<
y
&&
!
(
*
vertical_iter
).
second
.
empty
())
{
update_segments
(
intersection_points
,
(
*
vertical_iter
).
second
,
pt
);
++
vertical_iter
;
if
(
vertical_iter
!=
vertical_data_
.
end
()
&&
(
*
vertical_iter
).
first
==
y
)
update_segments
(
intersection_points
,
(
*
vertical_iter
).
second
,
pt
);
}
}
//handle sloping segments
if
(
sloping_iter
!=
sloping_elements
.
end
())
{
typename
std
::
map
<
Unit
,
std
::
set
<
iterator
>
>::
iterator
next_sloping
=
sloping_iter
;
for
(
++
next_sloping
;
next_sloping
!=
sloping_elements
.
end
()
&&
(
*
next_sloping
).
first
<
y
;
++
next_sloping
)
{
sloping_iter
=
next_sloping
;
}
if
((
*
sloping_iter
).
first
<
y
&&
!
(
*
sloping_iter
).
second
.
empty
())
{
for
(
typename
std
::
set
<
iterator
>::
iterator
element_iter
=
(
*
sloping_iter
).
second
.
begin
();
element_iter
!=
(
*
sloping_iter
).
second
.
end
();
++
element_iter
)
{
const
half_edge
&
he
=
(
*
element_iter
).
first
;
if
(
intersects_grid
(
pt
,
he
))
{
update_segments
(
intersection_points
,
(
*
element_iter
).
second
,
pt
);
}
}
++
sloping_iter
;
if
(
sloping_iter
!=
sloping_elements
.
end
()
&&
(
*
sloping_iter
).
first
==
y
&&
!
(
*
sloping_iter
).
second
.
empty
())
{
for
(
typename
std
::
set
<
iterator
>::
iterator
element_iter
=
(
*
sloping_iter
).
second
.
begin
();
element_iter
!=
(
*
sloping_iter
).
second
.
end
();
++
element_iter
)
{
const
half_edge
&
he
=
(
*
element_iter
).
first
;
if
(
intersects_grid
(
pt
,
he
))
{
update_segments
(
intersection_points
,
(
*
element_iter
).
second
,
pt
);
}
}
}
}
}
}
//erase and reinsert edges into scanline with check for future intersection
}
// //merge sloping element data
// std::sort(sloping_ends.begin(), sloping_ends.end());
// std::map<Unit, std::set<iterator> > sloping_elements;
// std::set<iterator> merge_elements;
// for(typename std::vector<std::pair<Unit, iterator> >::iterator slop_iter = sloping_ends.begin();
// slop_iter == sloping_ends.end(); ++slop_iter) {
// //merge into sloping elements
// typename std::set<iterator>::iterator merge_iterator = merge_elements.find((*slop_iter).second);
// if(merge_iterator == merge_elements.end()) {
// merge_elements.insert((*slop_iter).second);
// } else {
// merge_elements.erase(merge_iterator);
// }
// sloping_elements[(*slop_iter).first] = merge_elements;
// }
inline
void
process_scan_event
(
std
::
map
<
segment_id
,
std
::
set
<
Point
>
>&
intersection_points
)
{
just_before_
=
true
;
// //scan intersection points
// typename std::map<Unit, std::set<segment_id> >::iterator vertical_iter = vertical_data_.begin();
// typename std::map<Unit, std::set<iterator> >::iterator sloping_iter = sloping_elements.begin();
// for(typename std::set<Unit>::iterator position_iter = intersection_locations.begin();
// position_iter == intersection_locations.end(); ++position_iter) {
// //look for vertical segments that intersect this point and update them
// Unit y = *position_iter;
// Point pt(x_, y);
// //handle vertical segments
// if(vertical_iter != vertical_data_.end()) {
// typename std::map<Unit, std::set<segment_id> >::iterator next_vertical = vertical_iter;
// for(++next_vertical; next_vertical != vertical_data_.end() &&
// (*next_vertical).first < y; ++next_vertical) {
// vertical_iter = next_vertical;
// }
// if((*vertical_iter).first < y && !(*vertical_iter).second.empty()) {
// update_segments(intersection_points, (*vertical_iter).second, pt);
// ++vertical_iter;
// if(vertical_iter != vertical_data_.end() && (*vertical_iter).first == y)
// update_segments(intersection_points, (*vertical_iter).second, pt);
// }
// }
// //handle sloping segments
// if(sloping_iter != sloping_elements.end()) {
// typename std::map<Unit, std::set<iterator> >::iterator next_sloping = sloping_iter;
// for(++next_sloping; next_sloping != sloping_elements.end() &&
// (*next_sloping).first < y; ++next_sloping) {
// sloping_iter = next_sloping;
// }
// if((*sloping_iter).first < y && !(*sloping_iter).second.empty()) {
// for(typename std::set<iterator>::iterator element_iter = (*sloping_iter).second.begin();
// element_iter != (*sloping_iter).second.end(); ++element_iter) {
// const half_edge& he = (*element_iter).first;
// if(intersects_grid(pt, he)) {
// update_segments(intersection_points, (*element_iter).second, pt);
// }
// }
// ++sloping_iter;
// if(sloping_iter != sloping_elements.end() && (*sloping_iter).first == y &&
// !(*sloping_iter).second.empty()) {
// for(typename std::set<iterator>::iterator element_iter = (*sloping_iter).second.begin();
// element_iter != (*sloping_iter).second.end(); ++element_iter) {
// const half_edge& he = (*element_iter).first;
// if(intersects_grid(pt, he)) {
// update_segments(intersection_points, (*element_iter).second, pt);
// }
// }
// }
// }
// }
// }
//process end events by removing those segments from the scanline
//and insert vertices of all events into intersection queue
Point
prev_point
((
std
::
numeric_limits
<
Unit
>::
min
)(),
(
std
::
numeric_limits
<
Unit
>::
min
)());
less_point
lp
;
std
::
set
<
segment_id
>
vertical_ids
;
vertical_data_
.
clear
();
for
(
std
::
size_t
i
=
0
;
i
<
event_edges_
.
size
();
++
i
)
{
segment_id
id
=
event_edges_
[
i
].
second
;
const
half_edge
&
he
=
event_edges_
[
i
].
first
;
//vertical half edges are handled during intersection processing because
//they cannot be inserted into the scanline
if
(
!
is_vertical
(
he
))
{
if
(
lp
(
he
.
second
,
he
.
first
))
{
//half edge is end event
lookup_and_remove
(
he
,
id
);
}
else
{
//half edge is begin event
insert_into_scanline
(
he
,
id
);
//note that they will be immediately removed and reinserted after
//handling their intersection (vertex)
//an optimization would allow them to be processed specially to avoid the redundant
//removal and reinsertion
}
}
else
{
//common case if you are lucky
//update the map of y to set of segment id
if
(
lp
(
he
.
second
,
he
.
first
))
{
//half edge is end event
std
::
set
<
segment_id
>::
iterator
itr
=
vertical_ids
.
find
(
id
);
if
(
itr
==
vertical_ids
.
end
())
{
//std::cout << "Failed to find end event id in vertical ids\n";
}
else
{
vertical_ids
.
erase
(
itr
);
vertical_data_
[
he
.
first
.
get
(
HORIZONTAL
)]
=
vertical_ids
;
}
}
else
{
//half edge is a begin event
vertical_ids
.
insert
(
id
);
vertical_data_
[
he
.
first
.
get
(
HORIZONTAL
)]
=
vertical_ids
;
}
}
//prevent repeated insertion of same vertex into intersection queue
if
(
prev_point
!=
he
.
first
)
intersection_queue_
.
insert
(
he
.
first
);
else
prev_point
=
he
.
first
;
// process intersections at scan event
process_intersections_at_scan_event
(
intersection_points
);
}
event_edges_
.
clear
();
}
// //erase and reinsert edges into scanline with check for future intersection
// }
// inline void process_scan_event(std::map<segment_id, std::set<Point> >& intersection_points) {
// just_before_ = true;
// //process end events by removing those segments from the scanline
// //and insert vertices of all events into intersection queue
// Point prev_point((std::numeric_limits<Unit>::min)(), (std::numeric_limits<Unit>::min)());
// less_point lp;
// std::set<segment_id> vertical_ids;
// vertical_data_.clear();
// for(std::size_t i = 0; i < event_edges_.size(); ++i) {
// segment_id id = event_edges_[i].second;
// const half_edge& he = event_edges_[i].first;
// //vertical half edges are handled during intersection processing because
// //they cannot be inserted into the scanline
// if(!is_vertical(he)) {
// if(lp(he.second, he.first)) {
// //half edge is end event
// lookup_and_remove(he, id);
// } else {
// //half edge is begin event
// insert_into_scanline(he, id);
// //note that they will be immediately removed and reinserted after
// //handling their intersection (vertex)
// //an optimization would allow them to be processed specially to avoid the redundant
// //removal and reinsertion
// }
// } else {
// //common case if you are lucky
// //update the map of y to set of segment id
// if(lp(he.second, he.first)) {
// //half edge is end event
// std::set<segment_id>::iterator itr = vertical_ids.find(id);
// if(itr == vertical_ids.end()) {
// //std::cout << "Failed to find end event id in vertical ids\n";
// } else {
// vertical_ids.erase(itr);
// vertical_data_[he.first.get(HORIZONTAL)] = vertical_ids;
// }
// } else {
// //half edge is a begin event
// vertical_ids.insert(id);
// vertical_data_[he.first.get(HORIZONTAL)] = vertical_ids;
// }
// }
// //prevent repeated insertion of same vertex into intersection queue
// if(prev_point != he.first)
// intersection_queue_.insert(he.first);
// else
// prev_point = he.first;
// // process intersections at scan event
// process_intersections_at_scan_event(intersection_points);
// }
// event_edges_.clear();
// }
public
:
template
<
typename
stream_type
>
...
...
@@ -892,23 +892,23 @@ namespace boost { namespace polygon{
return
false
;
}
edges
.
pop_back
();
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
1
,
0
),
Point
(
11
,
11
)),
edges
.
size
()));
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
1
,
0
),
Point
(
11
,
11
)),
(
segment_id
)
edges
.
size
()));
if
(
!
verify_scan
(
result
,
edges
.
begin
(),
edges
.
end
()))
{
stdcout
<<
"fail3
\n
"
;
return
false
;
}
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
1
,
0
),
Point
(
10
,
11
)),
edges
.
size
()));
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
1
,
0
),
Point
(
10
,
11
)),
(
segment_id
)
edges
.
size
()));
if
(
verify_scan
(
result
,
edges
.
begin
(),
edges
.
end
()))
{
stdcout
<<
"fail4
\n
"
;
return
false
;
}
edges
.
pop_back
();
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
1
,
2
),
Point
(
11
,
11
)),
edges
.
size
()));
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
1
,
2
),
Point
(
11
,
11
)),
(
segment_id
)
edges
.
size
()));
if
(
!
verify_scan
(
result
,
edges
.
begin
(),
edges
.
end
()))
{
stdcout
<<
"fail5 "
<<
result
.
first
<<
" "
<<
result
.
second
<<
"
\n
"
;
return
false
;
}
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
0
,
5
),
Point
(
0
,
11
)),
edges
.
size
()));
edges
.
push_back
(
std
::
make_pair
(
half_edge
(
Point
(
0
,
5
),
Point
(
0
,
11
)),
(
segment_id
)
edges
.
size
()));
if
(
verify_scan
(
result
,
edges
.
begin
(),
edges
.
end
()))
{
stdcout
<<
"fail6 "
<<
result
.
first
<<
" "
<<
result
.
second
<<
"
\n
"
;
return
false
;
...
...
@@ -1048,7 +1048,7 @@ namespace boost { namespace polygon{
if
(
current_iter
!=
scan_data_
.
end
())
{
//make sure we are looking at element in scanline just below y
//if(evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) != y) {
if
(
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
!=
0
)
{
if
(
scanline_base
<
Unit
>::
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
!=
0
)
{
Point
e2
(
pt
);
if
(
e2
.
get
(
VERTICAL
)
!=
(
std
::
numeric_limits
<
Unit
>::
max
)())
e2
.
set
(
VERTICAL
,
e2
.
get
(
VERTICAL
)
+
1
);
...
...
@@ -1060,12 +1060,12 @@ namespace boost { namespace polygon{
if
(
current_iter
!=
scan_data_
.
end
())
{
//get the bottom iterator for elements at this point
//while(evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) >= (high_precision)y &&
while
(
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
!=
1
&&
while
(
scanline_base
<
Unit
>::
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
!=
1
&&
current_iter
!=
scan_data_
.
begin
())
{
--
current_iter
;
}
//if(evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) >= (high_precision)y) {
if
(
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
!=
1
)
{
if
(
scanline_base
<
Unit
>::
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
!=
1
)
{
properties_below
.
clear
();
}
else
{
properties_below
=
(
*
current_iter
).
second
;
...
...
@@ -1078,7 +1078,7 @@ namespace boost { namespace polygon{
while
(
current_iter
!=
scan_data_
.
end
()
&&
//can only be true if y is integer
//evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) == y) {
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
==
0
)
{
scanline_base
<
Unit
>::
on_above_or_below
(
Point
(
x_
,
y
),
(
*
current_iter
).
first
)
==
0
)
{
//removal_set_.push_back(current_iter);
++
current_iter
;
}
...
...
@@ -1129,7 +1129,7 @@ namespace boost { namespace polygon{
y
=
vertical_edge_below
.
second
.
get
(
VERTICAL
);
continue
;
}
if
(
is_vertical
(
he
))
{
if
(
scanline_base
<
Unit
>::
is_vertical
(
he
))
{
update_property_map
(
vertical_properties_above
,
vp
.
second
);
vertical_edge_above
=
he
;
}
else
{
...
...
@@ -1556,7 +1556,7 @@ namespace boost { namespace polygon{
sl
.
scan
(
result
,
mof
,
pmd
.
begin
(),
pmd
.
end
());
}
inline
bool
verify
()
{
inline
bool
verify
1
()
{
std
::
pair
<
int
,
int
>
offenders
;
std
::
vector
<
std
::
pair
<
half_edge
,
int
>
>
lines
;
int
count
=
0
;
...
...
@@ -1704,8 +1704,8 @@ namespace boost { namespace polygon{
//if half edge 1 is not vertical its slope is less than that of half edge 2
return
get
(
pt1
,
HORIZONTAL
)
!=
get
(
pt2
,
HORIZONTAL
);
}
return
less_slope
(
get
(
pt_
,
HORIZONTAL
),
get
(
pt_
,
VERTICAL
),
pt1
,
pt2
);
return
scanline_base
<
Unit
>::
less_slope
(
get
(
pt_
,
HORIZONTAL
),
get
(
pt_
,
VERTICAL
),
pt1
,
pt2
);
}
};
...
...
@@ -2154,7 +2154,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388
si
.
insert
(
poly
,
444
);
result
.
clear
();
si
.
merge
(
result
);
si
.
verify
();
si
.
verify
1
();
print
(
stdcout
,
si
.
pmd
)
<<
std
::
endl
;
if
(
!
result
.
empty
())
{
psd
=
(
*
(
result
.
begin
())).
second
;
...
...
@@ -2534,7 +2534,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388
elem
.
first
=
edge
;
elem
.
second
=
1
;
if
(
edge
.
second
<
edge
.
first
)
elem
.
second
*=
-
1
;
if
(
is_vertical
(
edge
))
elem
.
second
*=
-
1
;
if
(
scanline_base
<
Unit
>::
is_vertical
(
edge
))
elem
.
second
*=
-
1
;
#ifdef BOOST_POLYGON_MSVC
#pragma warning (disable: 4127)
#endif
...
...
include/boost/polygon/point_data.hpp
View file @
d48f6e00
...
...
@@ -34,17 +34,29 @@ namespace boost { namespace polygon{
#endif
{
(
*
this
)
=
that
;
}
template
<
typename
other
>
point_data
(
const
other
&
that
)
:
coords_
()
{
(
*
this
)
=
that
;
}
point_data
(
const
other
&
that
)
#ifndef BOOST_POLYGON_MSVC
:
coords_
()
#endif
{
(
*
this
)
=
that
;
}
inline
point_data
&
operator
=
(
const
point_data
&
that
)
{
coords_
[
0
]
=
that
.
coords_
[
0
];
coords_
[
1
]
=
that
.
coords_
[
1
];
return
*
this
;
}
template
<
typename
T1
,
typename
T2
>
inline
point_data
(
const
T1
&
x
,
const
T2
&
y
)
:
coords_
()
{
inline
point_data
(
const
T1
&
x
,
const
T2
&
y
)
#ifndef BOOST_POLYGON_MSVC
:
coords_
()
#endif
{
coords_
[
HORIZONTAL
]
=
(
coordinate_type
)
x
;
coords_
[
VERTICAL
]
=
(
coordinate_type
)
y
;
}
template
<
typename
T2
>
inline
point_data
(
const
point_data
<
T2
>&
rvalue
)
:
coords_
()
{
inline
point_data
(
const
point_data
<
T2
>&
rvalue
)
#ifndef BOOST_POLYGON_MSVC
:
coords_
()
#endif
{
coords_
[
HORIZONTAL
]
=
(
coordinate_type
)(
rvalue
.
x
());
coords_
[
VERTICAL
]
=
(
coordinate_type
)(
rvalue
.
y
());
}
...
...
include/boost/polygon/polygon_45_data.hpp
View file @
d48f6e00
...
...
@@ -62,7 +62,7 @@ public:
inline
std
::
size_t
size
()
const
{
return
coords_
.
size
();
}
p
rivate
:
p
ublic
:
std
::
vector
<
point_data
<
coordinate_type
>
>
coords_
;
};
...
...
include/boost/polygon/polygon_45_set_data.hpp
View file @
d48f6e00
...
...
@@ -1541,11 +1541,11 @@ namespace boost { namespace polygon{
polygon_90_set_data
<
Unit
>
l90sd
(
VERTICAL
),
r90sd
(
VERTICAL
),
output
(
VERTICAL
);
for
(
typename
value_type
::
const_iterator
itr
=
data_
.
begin
();
itr
!=
data_
.
end
();
++
itr
)
{
if
((
*
itr
).
count
[
3
]
==
0
)
continue
;
//skip all non vertical edges
l90sd
.
insert
(
std
::
make_pair
((
*
itr
).
pt
.
x
(),
std
::
make_pair
((
*
itr
).
pt
.
y
(),
(
*
itr
).
count
[
3
])),
false
,
VERTICAL
);
l90sd
.
insert
(
std
::
make_pair
((
*
itr
).
pt
.
x
(),
std
::
make_pair
<
Unit
,
int
>
((
*
itr
).
pt
.
y
(),
(
*
itr
).
count
[
3
])),
false
,
VERTICAL
);
}
for
(
typename
value_type
::
const_iterator
itr
=
rvalue
.
data_
.
begin
();
itr
!=
rvalue
.
data_
.
end
();
++
itr
)
{
if
((
*
itr
).
count
[
3
]
==
0
)
continue
;
//skip all non vertical edges
r90sd
.
insert
(
std
::
make_pair
((
*
itr
).
pt
.
x
(),
std
::
make_pair
((
*
itr
).
pt
.
y
(),
(
*
itr
).
count
[
3
])),
false
,
VERTICAL
);
r90sd
.
insert
(
std
::
make_pair
((
*
itr
).
pt
.
x
(),
std
::
make_pair
<
Unit
,
int
>
((
*
itr
).
pt
.
y
(),
(
*
itr
).
count
[
3
])),
false
,
VERTICAL
);
}
l90sd
.
sort
();
r90sd
.
sort
();
...
...
@@ -1673,7 +1673,7 @@ namespace boost { namespace polygon{
polygon_90_set_data
<
Unit
>
l90sd
(
VERTICAL
);
for
(
typename
value_type
::
const_iterator
itr
=
data_
.
begin
();
itr
!=
data_
.
end
();
++
itr
)
{
if
((
*
itr
).
count
[
3
]
==
0
)
continue
;
//skip all non vertical edges
l90sd
.
insert
(
std
::
make_pair
((
*
itr
).
pt
.
x
(),
std
::
make_pair
((
*
itr
).
pt
.
y
(),
(
*
itr
).
count
[
3
])),
false
,
VERTICAL
);
l90sd
.
insert
(
std
::
make_pair
((
*
itr
).
pt
.
x
(),
std
::
make_pair
<
Unit
,
int
>
((
*
itr
).
pt
.
y
(),
(
*
itr
).
count
[
3
])),
false
,
VERTICAL
);
}
l90sd
.
sort
();
#ifdef BOOST_POLYGON_MSVC
...
...
include/boost/polygon/polygon_45_set_traits.hpp
View file @
d48f6e00
...
...
@@ -137,7 +137,7 @@ namespace boost { namespace polygon{
static
inline
bool
clean
(
const
polygon_45_set_data
<
T
>&
polygon_set
)
{
polygon_set
.
clean
();
return
true
;
}
static
inline
bool
sorted
(
const
polygon_45_set_data
<
T
>&
polygon_set
)
{
int
untested
=
0
;
polygon_set
.
sort
();
return
true
;
}
static
inline
bool
sorted
(
const
polygon_45_set_data
<
T
>&
polygon_set
)
{
polygon_set
.
sort
();
return
true
;
}
};
}
...
...
include/boost/polygon/polygon_45_with_holes_data.hpp
View file @
d48f6e00
...
...
@@ -96,10 +96,12 @@ public:
return
holes_
.
size
();
}
p
rivate
:
p
ublic
:
polygon_45_data
<
coordinate_type
>
self_
;
std
::
list
<
hole_type
>
holes_
;
};
}
}
#endif
...
...
include/boost/polygon/polygon_90_set_data.hpp
View file @
d48f6e00
...
...
@@ -244,6 +244,38 @@ namespace boost { namespace polygon{
// get the scanline orientation of the polygon set
inline
orientation_2d
orient
()
const
{
return
orient_
;
}
polygon_90_set_data
<
coordinate_type
>&
operator
-=
(
const
polygon_90_set_data
&
that
)
{
sort
();
that
.
sort
();
value_type
data
;
std
::
swap
(
data
,
data_
);
applyBooleanBinaryOp
(
data
.
begin
(),
data
.
end
(),
that
.
begin
(),
that
.
end
(),
boolean_op
::
BinaryCount
<
boolean_op
::
BinaryNot
>
());
return
*
this
;
}
polygon_90_set_data
<
coordinate_type
>&
operator
^=
(
const
polygon_90_set_data
&
that
)
{
sort
();
that
.
sort
();
value_type
data
;
std
::
swap
(
data
,
data_
);
applyBooleanBinaryOp
(
data
.
begin
(),
data
.
end
(),
that
.
begin
(),
that
.
end
(),
boolean_op
::
BinaryCount
<
boolean_op
::
BinaryXor
>
());
return
*
this
;
}
polygon_90_set_data
<
coordinate_type
>&
operator
&=
(
const
polygon_90_set_data
&
that
)
{
sort
();
that
.
sort
();
value_type
data
;
std
::
swap
(
data
,
data_
);
applyBooleanBinaryOp
(
data
.
begin
(),
data
.
end
(),
that
.
begin
(),
that
.
end
(),
boolean_op
::
BinaryCount
<
boolean_op
::
BinaryAnd
>
());
return
*
this
;
}
polygon_90_set_data
<
coordinate_type
>&
operator
|=
(
const
polygon_90_set_data
&
that
)
{
insert
(
that
);
return
*
this
;
}
void
clean
()
const
{
sort
();
if
(
dirty_
)
{
...
...
@@ -297,7 +329,7 @@ namespace boost { namespace polygon{
}
polygon_90_set_data
&
bloat
(
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
west_bloating
,
bloat
2
(
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
west_bloating
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
east_bloating
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
south_bloating
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
north_bloating
)
{
...
...
@@ -318,11 +350,257 @@ namespace boost { namespace polygon{
return
*
this
;
}
static
void
modify_pt
(
point_data
<
coordinate_type
>&
pt
,
const
point_data
<
coordinate_type
>&
prev_pt
,
const
point_data
<
coordinate_type
>&
current_pt
,
const
point_data
<
coordinate_type
>&
next_pt
,
coordinate_type
west_bloating
,
coordinate_type
east_bloating
,
coordinate_type
south_bloating
,
coordinate_type
north_bloating
)
{
bool
pxl
=
prev_pt
.
x
()
<
current_pt
.
x
();
bool
pyl
=
prev_pt
.
y
()
<
current_pt
.
y
();
bool
nxl
=
next_pt
.
x
()
<
current_pt
.
x
();
bool
nyl
=
next_pt
.
y
()
<
current_pt
.
y
();
bool
pxg
=
prev_pt
.
x
()
>
current_pt
.
x
();
bool
pyg
=
prev_pt
.
y
()
>
current_pt
.
y
();
bool
nxg
=
next_pt
.
x
()
>
current_pt
.
x
();
bool
nyg
=
next_pt
.
y
()
>
current_pt
.
y
();
//two of the four if statements will execute
if
(
pxl
)
pt
.
y
(
current_pt
.
y
()
-
south_bloating
);
if
(
pxg
)
pt
.
y
(
current_pt
.
y
()
+
north_bloating
);
if
(
nxl
)
pt
.
y
(
current_pt
.
y
()
+
north_bloating
);
if
(
nxg
)
pt
.
y
(
current_pt
.
y
()
-
south_bloating
);
if
(
pyl
)
pt
.
x
(
current_pt
.
x
()
+
east_bloating
);
if
(
pyg
)
pt
.
x
(
current_pt
.
x
()
-
west_bloating
);
if
(
nyl
)
pt
.
x
(
current_pt
.
x
()
-
west_bloating
);
if
(
nyg
)
pt
.
x
(
current_pt
.
x
()
+
east_bloating
);
}
static
void
resize_poly_up
(
std
::
vector
<
point_data
<
coordinate_type
>
>&
poly
,
coordinate_type
west_bloating
,
coordinate_type
east_bloating
,
coordinate_type
south_bloating
,
coordinate_type
north_bloating
)
{
point_data
<
coordinate_type
>
first_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
second_pt
=
poly
[
1
];
point_data
<
coordinate_type
>
prev_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
current_pt
=
poly
[
1
];
for
(
std
::
size_t
i
=
2
;
i
<
poly
.
size
();
++
i
)
{
point_data
<
coordinate_type
>
next_pt
=
poly
[
i
];
modify_pt
(
poly
[
i
-
1
],
prev_pt
,
current_pt
,
next_pt
,
west_bloating
,
east_bloating
,
south_bloating
,
north_bloating
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
}
point_data
<
coordinate_type
>
next_pt
=
first_pt
;
modify_pt
(
poly
.
back
(),
prev_pt
,
current_pt
,
next_pt
,
west_bloating
,
east_bloating
,
south_bloating
,
north_bloating
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
next_pt
=
second_pt
;
modify_pt
(
poly
[
0
],
prev_pt
,
current_pt
,
next_pt
,
west_bloating
,
east_bloating
,
south_bloating
,
north_bloating
);
remove_colinear_pts
(
poly
);
}
static
bool
resize_poly_down
(
std
::
vector
<
point_data
<
coordinate_type
>
>&
poly
,
coordinate_type
west_shrinking
,
coordinate_type
east_shrinking
,
coordinate_type
south_shrinking
,
coordinate_type
north_shrinking
)
{
rectangle_data
<
coordinate_type
>
extents_rectangle
;
set_points
(
extents_rectangle
,
poly
[
0
],
poly
[
0
]);
point_data
<
coordinate_type
>
first_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
second_pt
=
poly
[
1
];
point_data
<
coordinate_type
>
prev_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
current_pt
=
poly
[
1
];
encompass
(
extents_rectangle
,
current_pt
);
for
(
int
i
=
2
;
i
<
poly
.
size
();
++
i
)
{
point_data
<
coordinate_type
>
next_pt
=
poly
[
i
];
encompass
(
extents_rectangle
,
next_pt
);
modify_pt
(
poly
[
i
-
1
],
prev_pt
,
current_pt
,
next_pt
,
west_shrinking
,
east_shrinking
,
south_shrinking
,
north_shrinking
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
}
if
(
delta
(
extents_rectangle
,
HORIZONTAL
)
<
std
::
abs
(
west_shrinking
+
east_shrinking
))
return
false
;
if
(
delta
(
extents_rectangle
,
VERTICAL
)
<
std
::
abs
(
north_shrinking
+
south_shrinking
))
return
false
;
point_data
<
coordinate_type
>
next_pt
=
first_pt
;
modify_pt
(
poly
.
back
(),
prev_pt
,
current_pt
,
next_pt
,
west_shrinking
,
east_shrinking
,
south_shrinking
,
north_shrinking
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
next_pt
=
second_pt
;
modify_pt
(
poly
[
0
],
prev_pt
,
current_pt
,
next_pt
,
west_shrinking
,
east_shrinking
,
south_shrinking
,
north_shrinking
);
return
remove_colinear_pts
(
poly
);
}
static
bool
remove_colinear_pts
(
std
::
vector
<
point_data
<
coordinate_type
>
>&
poly
)
{
bool
found_colinear
=
true
;
while
(
found_colinear
)
{
found_colinear
=
false
;
typename
std
::
vector
<
point_data
<
coordinate_type
>
>::
iterator
itr
=
poly
.
begin
();
itr
+=
poly
.
size
()
-
1
;
//get last element position
typename
std
::
vector
<
point_data
<
coordinate_type
>
>::
iterator
itr2
=
poly
.
begin
();
typename
std
::
vector
<
point_data
<
coordinate_type
>
>::
iterator
itr3
=
itr2
;
++
itr3
;
std
::
size_t
count
=
0
;
for
(
;
itr3
<
poly
.
end
();
++
itr3
)
{
if
(((
*
itr
).
x
()
==
(
*
itr2
).
x
()
&&
(
*
itr
).
x
()
==
(
*
itr3
).
x
())
||
((
*
itr
).
y
()
==
(
*
itr2
).
y
()
&&
(
*
itr
).
y
()
==
(
*
itr3
).
y
())
)
{
++
count
;
found_colinear
=
true
;
}
else
{
itr
=
itr2
;
++
itr2
;
}
*
itr2
=
*
itr3
;
}
itr3
=
poly
.
begin
();
if
(((
*
itr
).
x
()
==
(
*
itr2
).
x
()
&&
(
*
itr
).
x
()
==
(
*
itr3
).
x
())
||
((
*
itr
).
y
()
==
(
*
itr2
).
y
()
&&
(
*
itr
).
y
()
==
(
*
itr3
).
y
())
)
{
++
count
;
found_colinear
=
true
;
}
poly
.
erase
(
poly
.
end
()
-
count
,
poly
.
end
());
}
return
poly
.
size
()
>=
4
;
}
polygon_90_set_data
&
bloat
(
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
west_bloating
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
east_bloating
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
south_bloating
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
north_bloating
)
{
std
::
list
<
polygon_45_with_holes_data
<
coordinate_type
>
>
polys
;
get
(
polys
);
clear
();
for
(
typename
std
::
list
<
polygon_45_with_holes_data
<
coordinate_type
>
>::
iterator
itr
=
polys
.
begin
();
itr
!=
polys
.
end
();
++
itr
)
{
//polygon_90_set_data<coordinate_type> psref;
//psref.insert(view_as<polygon_90_concept>((*itr).self_));
//rectangle_data<coordinate_type> prerect;
//psref.extents(prerect);
resize_poly_up
((
*
itr
).
self_
.
coords_
,
west_bloating
,
east_bloating
,
south_bloating
,
north_bloating
);
iterator_geometry_to_set
<
polygon_90_concept
,
view_of
<
polygon_90_concept
,
polygon_45_data
<
coordinate_type
>
>
>
begin_input
(
view_as
<
polygon_90_concept
>
((
*
itr
).
self_
),
LOW
,
orient_
,
false
,
true
,
COUNTERCLOCKWISE
),
end_input
(
view_as
<
polygon_90_concept
>
((
*
itr
).
self_
),
HIGH
,
orient_
,
false
,
true
,
COUNTERCLOCKWISE
);
insert
(
begin_input
,
end_input
,
orient_
);
//polygon_90_set_data<coordinate_type> pstest;
//pstest.insert(view_as<polygon_90_concept>((*itr).self_));
//psref.bloat2(west_bloating, east_bloating, south_bloating, north_bloating);
//if(!equivalence(psref, pstest)) {
// std::cout << "test failed\n";
//}
for
(
typename
std
::
list
<
polygon_45_data
<
coordinate_type
>
>::
iterator
itrh
=
(
*
itr
).
holes_
.
begin
();
itrh
!=
(
*
itr
).
holes_
.
end
();
++
itrh
)
{
//rectangle_data<coordinate_type> rect;
//psref.extents(rect);
//polygon_90_set_data<coordinate_type> psrefhole;
//psrefhole.insert(prerect);
//psrefhole.insert(view_as<polygon_90_concept>(*itrh), true);
//polygon_45_data<coordinate_type> testpoly(*itrh);
if
(
resize_poly_down
((
*
itrh
).
coords_
,
west_bloating
,
east_bloating
,
south_bloating
,
north_bloating
))
{
iterator_geometry_to_set
<
polygon_90_concept
,
view_of
<
polygon_90_concept
,
polygon_45_data
<
coordinate_type
>
>
>
begin_input
(
view_as
<
polygon_90_concept
>
(
*
itrh
),
LOW
,
orient_
,
true
,
true
),
end_input
(
view_as
<
polygon_90_concept
>
(
*
itrh
),
HIGH
,
orient_
,
true
,
true
);
insert
(
begin_input
,
end_input
,
orient_
);
//polygon_90_set_data<coordinate_type> pstesthole;
//pstesthole.insert(rect);
//iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
// begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true);
//pstesthole.insert(begin_input2, end_input, orient_);
//psrefhole.bloat2(west_bloating, east_bloating, south_bloating, north_bloating);
//if(!equivalence(psrefhole, pstesthole)) {
// std::cout << (winding(testpoly) == CLOCKWISE) << std::endl;
// std::cout << (winding(*itrh) == CLOCKWISE) << std::endl;
// polygon_90_set_data<coordinate_type> c(psrefhole);
// c.clean();
// polygon_90_set_data<coordinate_type> a(pstesthole);
// polygon_90_set_data<coordinate_type> b(pstesthole);
// a.sort();
// b.clean();
// std::cout << "test hole failed\n";
// //std::cout << testpoly << std::endl;
//}
}
}
}
return
*
this
;
}
polygon_90_set_data
&
shrink
(
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
west_shrinking
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
east_shrinking
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
south_shrinking
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
north_shrinking
)
{
std
::
list
<
polygon_45_with_holes_data
<
coordinate_type
>
>
polys
;
get
(
polys
);
clear
();
for
(
typename
std
::
list
<
polygon_45_with_holes_data
<
coordinate_type
>
>::
iterator
itr
=
polys
.
begin
();
itr
!=
polys
.
end
();
++
itr
)
{
//polygon_90_set_data<coordinate_type> psref;
//psref.insert(view_as<polygon_90_concept>((*itr).self_));
//rectangle_data<coordinate_type> prerect;
//psref.extents(prerect);
//polygon_45_data<coordinate_type> testpoly((*itr).self_);
if
(
resize_poly_down
((
*
itr
).
self_
.
coords_
,
-
west_shrinking
,
-
east_shrinking
,
-
south_shrinking
,
-
north_shrinking
))
{
iterator_geometry_to_set
<
polygon_90_concept
,
view_of
<
polygon_90_concept
,
polygon_45_data
<
coordinate_type
>
>
>
begin_input
(
view_as
<
polygon_90_concept
>
((
*
itr
).
self_
),
LOW
,
orient_
,
false
,
true
,
COUNTERCLOCKWISE
),
end_input
(
view_as
<
polygon_90_concept
>
((
*
itr
).
self_
),
HIGH
,
orient_
,
false
,
true
,
COUNTERCLOCKWISE
);
insert
(
begin_input
,
end_input
,
orient_
);
//iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
// begin_input2(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE);
//polygon_90_set_data<coordinate_type> pstest;
//pstest.insert(begin_input2, end_input, orient_);
//psref.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
//if(!equivalence(psref, pstest)) {
// std::cout << "test failed\n";
//}
for
(
typename
std
::
list
<
polygon_45_data
<
coordinate_type
>
>::
iterator
itrh
=
(
*
itr
).
holes_
.
begin
();
itrh
!=
(
*
itr
).
holes_
.
end
();
++
itrh
)
{
//rectangle_data<coordinate_type> rect;
//psref.extents(rect);
//polygon_90_set_data<coordinate_type> psrefhole;
//psrefhole.insert(prerect);
//psrefhole.insert(view_as<polygon_90_concept>(*itrh), true);
//polygon_45_data<coordinate_type> testpoly(*itrh);
resize_poly_up
((
*
itrh
).
coords_
,
-
west_shrinking
,
-
east_shrinking
,
-
south_shrinking
,
-
north_shrinking
);
iterator_geometry_to_set
<
polygon_90_concept
,
view_of
<
polygon_90_concept
,
polygon_45_data
<
coordinate_type
>
>
>
begin_input
(
view_as
<
polygon_90_concept
>
(
*
itrh
),
LOW
,
orient_
,
true
,
true
),
end_input
(
view_as
<
polygon_90_concept
>
(
*
itrh
),
HIGH
,
orient_
,
true
,
true
);
insert
(
begin_input
,
end_input
,
orient_
);
//polygon_90_set_data<coordinate_type> pstesthole;
//pstesthole.insert(rect);
//iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > >
// begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true);
//pstesthole.insert(begin_input2, end_input, orient_);
//psrefhole.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
//if(!equivalence(psrefhole, pstesthole)) {
// std::cout << (winding(testpoly) == CLOCKWISE) << std::endl;
// std::cout << (winding(*itrh) == CLOCKWISE) << std::endl;
// polygon_90_set_data<coordinate_type> c(psrefhole);
// c.clean();
// polygon_90_set_data<coordinate_type> a(pstesthole);
// polygon_90_set_data<coordinate_type> b(pstesthole);
// a.sort();
// b.clean();
// std::cout << "test hole failed\n";
// //std::cout << testpoly << std::endl;
//}
}
}
}
return
*
this
;
}
polygon_90_set_data
&
shrink2
(
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
west_shrinking
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
east_shrinking
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
south_shrinking
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
north_shrinking
)
{
rectangle_data
<
coordinate_type
>
externalBoundary
;
if
(
!
extents
(
externalBoundary
))
return
*
this
;
::
boost
::
polygon
::
bloat
(
externalBoundary
,
10
);
//bloat by diferential ammount
...
...
@@ -352,6 +630,30 @@ namespace boost { namespace polygon{
return
*
this
;
}
polygon_90_set_data
&
shrink
(
direction_2d
dir
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
shrinking
)
{
if
(
dir
==
WEST
)
return
shrink
(
shrinking
,
0
,
0
,
0
);
if
(
dir
==
EAST
)
return
shrink
(
0
,
shrinking
,
0
,
0
);
if
(
dir
==
SOUTH
)
return
shrink
(
0
,
0
,
shrinking
,
0
);
if
(
dir
==
NORTH
)
return
shrink
(
0
,
0
,
0
,
shrinking
);
}
polygon_90_set_data
&
bloat
(
direction_2d
dir
,
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
shrinking
)
{
if
(
dir
==
WEST
)
return
bloat
(
shrinking
,
0
,
0
,
0
);
if
(
dir
==
EAST
)
return
bloat
(
0
,
shrinking
,
0
,
0
);
if
(
dir
==
SOUTH
)
return
bloat
(
0
,
0
,
shrinking
,
0
);
if
(
dir
==
NORTH
)
return
bloat
(
0
,
0
,
0
,
shrinking
);
}
polygon_90_set_data
&
resize
(
coordinate_type
west
,
coordinate_type
east
,
coordinate_type
south
,
coordinate_type
north
);
...
...
include/boost/polygon/polygon_data.hpp
View file @
d48f6e00
...
...
@@ -60,7 +60,7 @@ public:
inline
std
::
size_t
size
()
const
{
return
coords_
.
size
();
}
p
rivate
:
p
ublic
:
std
::
vector
<
point_data
<
coordinate_type
>
>
coords_
;
};
...
...
include/boost/polygon/polygon_set_data.hpp
View file @
d48f6e00
...
...
@@ -120,38 +120,7 @@ namespace boost { namespace polygon {
template
<
typename
polygon_type
>
inline
void
insert
(
const
polygon_type
&
polygon_object
,
bool
is_hole
,
polygon_concept
)
{
bool
first_iteration
=
true
;
point_type
first_point
;
point_type
previous_point
;
point_type
current_point
;
direction_1d
winding_dir
=
winding
(
polygon_object
);
int
multiplier
=
winding_dir
==
COUNTERCLOCKWISE
?
1
:
-
1
;
if
(
is_hole
)
multiplier
*=
-
1
;
for
(
typename
polygon_traits
<
polygon_type
>::
iterator_type
itr
=
begin_points
(
polygon_object
);
itr
!=
end_points
(
polygon_object
);
++
itr
)
{
assign
(
current_point
,
*
itr
);
if
(
first_iteration
)
{
first_iteration
=
false
;
first_point
=
previous_point
=
current_point
;
}
else
{
if
(
previous_point
!=
current_point
)
{
element_type
elem
(
edge_type
(
previous_point
,
current_point
),
(
previous_point
.
get
(
HORIZONTAL
)
==
current_point
.
get
(
HORIZONTAL
)
?
-
1
:
1
)
*
multiplier
);
insert_clean
(
elem
);
}
}
previous_point
=
current_point
;
}
current_point
=
first_point
;
if
(
!
first_iteration
)
{
if
(
previous_point
!=
current_point
)
{
element_type
elem
(
edge_type
(
previous_point
,
current_point
),
(
previous_point
.
get
(
HORIZONTAL
)
==
current_point
.
get
(
HORIZONTAL
)
?
-
1
:
1
)
*
multiplier
);
insert_clean
(
elem
);
}
dirty_
=
true
;
unsorted_
=
true
;
}
insert_vertex_sequence
(
begin_points
(
polygon_object
),
end_points
(
polygon_object
),
winding
(
polygon_object
),
is_hole
);
}
inline
void
insert
(
const
polygon_set_data
&
ps
,
bool
is_hole
=
false
)
{
...
...
@@ -229,9 +198,37 @@ namespace boost { namespace polygon {
template
<
class
iT
>
inline
void
insert_vertex_sequence
(
iT
begin_vertex
,
iT
end_vertex
,
direction_1d
winding
,
bool
is_hole
)
{
polygon_data
<
coordinate_type
>
poly
;
poly
.
set
(
begin_vertex
,
end_vertex
);
insert
(
poly
,
is_hole
);
bool
first_iteration
=
true
;
point_type
first_point
;
point_type
previous_point
;
point_type
current_point
;
direction_1d
winding_dir
=
winding
;
int
multiplier
=
winding_dir
==
COUNTERCLOCKWISE
?
1
:
-
1
;
if
(
is_hole
)
multiplier
*=
-
1
;
for
(
;
begin_vertex
!=
end_vertex
;
++
begin_vertex
)
{
assign
(
current_point
,
*
begin_vertex
);
if
(
first_iteration
)
{
first_iteration
=
false
;
first_point
=
previous_point
=
current_point
;
}
else
{
if
(
previous_point
!=
current_point
)
{
element_type
elem
(
edge_type
(
previous_point
,
current_point
),
(
previous_point
.
get
(
HORIZONTAL
)
==
current_point
.
get
(
HORIZONTAL
)
?
-
1
:
1
)
*
multiplier
);
insert_clean
(
elem
);
}
}
previous_point
=
current_point
;
}
current_point
=
first_point
;
if
(
!
first_iteration
)
{
if
(
previous_point
!=
current_point
)
{
element_type
elem
(
edge_type
(
previous_point
,
current_point
),
(
previous_point
.
get
(
HORIZONTAL
)
==
current_point
.
get
(
HORIZONTAL
)
?
-
1
:
1
)
*
multiplier
);
insert_clean
(
elem
);
}
dirty_
=
true
;
unsorted_
=
true
;
}
}
template
<
typename
output_container
>
...
...
@@ -363,6 +360,13 @@ namespace boost { namespace polygon {
inline
polygon_set_data
&
resize
(
coordinate_type
resizing
,
bool
corner_fill_arc
=
false
,
unsigned
int
num_circle_segments
=
0
)
{
if
(
!
corner_fill_arc
)
{
if
(
resizing
<
0
)
return
shrink
(
-
resizing
);
if
(
resizing
>
0
)
return
bloat
(
-
resizing
);
return
*
this
;
}
if
(
resizing
==
0
)
return
*
this
;
std
::
list
<
polygon_with_holes_data
<
coordinate_type
>
>
pl
;
get
(
pl
);
...
...
@@ -421,6 +425,139 @@ namespace boost { namespace polygon {
return
*
this
;
}
static
inline
void
compute_offset_edge
(
point_data
<
coordinate_type
>&
pt1
,
point_data
<
coordinate_type
>&
pt2
,
const
point_data
<
coordinate_type
>&
prev_pt
,
const
point_data
<
coordinate_type
>&
current_pt
,
coordinate_type
distance
,
int
multiplier
)
{
coordinate_type
dx
=
current_pt
.
x
()
-
prev_pt
.
x
();
coordinate_type
dy
=
current_pt
.
y
()
-
prev_pt
.
y
();
double
ddx
=
(
double
)
dx
;
double
ddy
=
(
double
)
dy
;
double
edge_length
=
std
::
sqrt
(
ddx
*
ddx
+
ddy
*
ddy
);
double
dnx
=
dy
;
double
dny
=
-
dx
;
dnx
=
dnx
*
(
double
)
distance
/
edge_length
;
dny
=
dny
*
(
double
)
distance
/
edge_length
;
dnx
=
std
::
floor
(
dnx
+
0.5
);
dny
=
std
::
floor
(
dny
+
0.5
);
pt1
.
x
(
prev_pt
.
x
()
+
(
coordinate_type
)
dnx
*
(
coordinate_type
)
multiplier
);
pt2
.
x
(
current_pt
.
x
()
+
(
coordinate_type
)
dnx
*
(
coordinate_type
)
multiplier
);
pt1
.
y
(
prev_pt
.
y
()
+
(
coordinate_type
)
dny
*
(
coordinate_type
)
multiplier
);
pt2
.
y
(
current_pt
.
y
()
+
(
coordinate_type
)
dny
*
(
coordinate_type
)
multiplier
);
}
static
inline
void
modify_pt
(
point_data
<
coordinate_type
>&
pt
,
const
point_data
<
coordinate_type
>&
prev_pt
,
const
point_data
<
coordinate_type
>&
current_pt
,
const
point_data
<
coordinate_type
>&
next_pt
,
coordinate_type
distance
,
coordinate_type
multiplier
)
{
std
::
pair
<
point_data
<
coordinate_type
>
,
point_data
<
coordinate_type
>
>
he1
(
prev_pt
,
current_pt
),
he2
(
current_pt
,
next_pt
);
compute_offset_edge
(
he1
.
first
,
he1
.
second
,
prev_pt
,
current_pt
,
distance
,
multiplier
);
compute_offset_edge
(
he2
.
first
,
he2
.
second
,
current_pt
,
next_pt
,
distance
,
multiplier
);
typename
scanline_base
<
coordinate_type
>::
compute_intersection_pack
pack
;
if
(
!
pack
.
compute_lazy_intersection
(
pt
,
he1
,
he2
,
true
,
true
))
{
pt
=
he1
.
second
;
//colinear offset edges use shared point
}
}
static
void
resize_poly_up
(
std
::
vector
<
point_data
<
coordinate_type
>
>&
poly
,
coordinate_type
distance
,
coordinate_type
multiplier
)
{
point_data
<
coordinate_type
>
first_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
second_pt
=
poly
[
1
];
point_data
<
coordinate_type
>
prev_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
current_pt
=
poly
[
1
];
for
(
std
::
size_t
i
=
2
;
i
<
poly
.
size
()
-
1
;
++
i
)
{
point_data
<
coordinate_type
>
next_pt
=
poly
[
i
];
modify_pt
(
poly
[
i
-
1
],
prev_pt
,
current_pt
,
next_pt
,
distance
,
multiplier
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
}
point_data
<
coordinate_type
>
next_pt
=
first_pt
;
modify_pt
(
poly
[
poly
.
size
()
-
2
],
prev_pt
,
current_pt
,
next_pt
,
distance
,
multiplier
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
next_pt
=
second_pt
;
modify_pt
(
poly
[
0
],
prev_pt
,
current_pt
,
next_pt
,
distance
,
multiplier
);
poly
.
back
()
=
poly
.
front
();
}
static
bool
resize_poly_down
(
std
::
vector
<
point_data
<
coordinate_type
>
>&
poly
,
coordinate_type
distance
,
coordinate_type
multiplier
)
{
std
::
vector
<
point_data
<
coordinate_type
>
>
orig_poly
(
poly
);
rectangle_data
<
coordinate_type
>
extents_rectangle
;
set_points
(
extents_rectangle
,
poly
[
0
],
poly
[
0
]);
point_data
<
coordinate_type
>
first_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
second_pt
=
poly
[
1
];
point_data
<
coordinate_type
>
prev_pt
=
poly
[
0
];
point_data
<
coordinate_type
>
current_pt
=
poly
[
1
];
encompass
(
extents_rectangle
,
current_pt
);
for
(
std
::
size_t
i
=
2
;
i
<
poly
.
size
()
-
1
;
++
i
)
{
point_data
<
coordinate_type
>
next_pt
=
poly
[
i
];
encompass
(
extents_rectangle
,
next_pt
);
modify_pt
(
poly
[
i
-
1
],
prev_pt
,
current_pt
,
next_pt
,
distance
,
multiplier
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
}
if
(
delta
(
extents_rectangle
,
HORIZONTAL
)
<=
std
::
abs
(
2
*
distance
))
return
false
;
if
(
delta
(
extents_rectangle
,
VERTICAL
)
<=
std
::
abs
(
2
*
distance
))
return
false
;
point_data
<
coordinate_type
>
next_pt
=
first_pt
;
modify_pt
(
poly
[
poly
.
size
()
-
2
],
prev_pt
,
current_pt
,
next_pt
,
distance
,
multiplier
);
prev_pt
=
current_pt
;
current_pt
=
next_pt
;
next_pt
=
second_pt
;
modify_pt
(
poly
[
0
],
prev_pt
,
current_pt
,
next_pt
,
distance
,
multiplier
);
poly
.
back
()
=
poly
.
front
();
//if the line segments formed between orignial and new points cross for an edge that edge inverts
//if all edges invert the polygon should be discarded
//if even one edge does not invert return true because the polygon is valid
bool
non_inverting_edge
=
false
;
for
(
std
::
size_t
i
=
1
;
i
<
poly
.
size
();
++
i
)
{
std
::
pair
<
point_data
<
coordinate_type
>
,
point_data
<
coordinate_type
>
>
he1
(
poly
[
i
],
orig_poly
[
i
]),
he2
(
poly
[
i
-
1
],
orig_poly
[
i
-
1
]);
if
(
!
scanline_base
<
coordinate_type
>::
intersects
(
he1
,
he2
))
{
non_inverting_edge
=
true
;
break
;
}
}
return
non_inverting_edge
;
}
polygon_set_data
&
bloat
(
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
distance
)
{
std
::
list
<
polygon_with_holes_data
<
coordinate_type
>
>
polys
;
get
(
polys
);
clear
();
for
(
typename
std
::
list
<
polygon_with_holes_data
<
coordinate_type
>
>::
iterator
itr
=
polys
.
begin
();
itr
!=
polys
.
end
();
++
itr
)
{
resize_poly_up
((
*
itr
).
self_
.
coords_
,
(
coordinate_type
)
distance
,
(
coordinate_type
)
1
);
insert_vertex_sequence
((
*
itr
).
self_
.
begin
(),
(
*
itr
).
self_
.
end
(),
COUNTERCLOCKWISE
,
false
);
//inserts without holes
for
(
typename
std
::
list
<
polygon_data
<
coordinate_type
>
>::
iterator
itrh
=
(
*
itr
).
holes_
.
begin
();
itrh
!=
(
*
itr
).
holes_
.
end
();
++
itrh
)
{
if
(
resize_poly_down
((
*
itrh
).
coords_
,
(
coordinate_type
)
distance
,
(
coordinate_type
)
1
))
{
insert_vertex_sequence
((
*
itrh
).
coords_
.
begin
(),
(
*
itrh
).
coords_
.
end
(),
CLOCKWISE
,
true
);
}
}
}
return
*
this
;
}
polygon_set_data
&
shrink
(
typename
coordinate_traits
<
coordinate_type
>::
unsigned_area_type
distance
)
{
std
::
list
<
polygon_with_holes_data
<
coordinate_type
>
>
polys
;
get
(
polys
);
clear
();
for
(
typename
std
::
list
<
polygon_with_holes_data
<
coordinate_type
>
>::
iterator
itr
=
polys
.
begin
();
itr
!=
polys
.
end
();
++
itr
)
{
if
(
resize_poly_down
((
*
itr
).
self_
.
coords_
,
(
coordinate_type
)
distance
,
(
coordinate_type
)
-
1
))
{
insert_vertex_sequence
((
*
itr
).
self_
.
begin
(),
(
*
itr
).
self_
.
end
(),
COUNTERCLOCKWISE
,
false
);
//inserts without holes
for
(
typename
std
::
list
<
polygon_data
<
coordinate_type
>
>::
iterator
itrh
=
(
*
itr
).
holes_
.
begin
();
itrh
!=
(
*
itr
).
holes_
.
end
();
++
itrh
)
{
resize_poly_up
((
*
itrh
).
coords_
,
(
coordinate_type
)
distance
,
(
coordinate_type
)
-
1
);
insert_vertex_sequence
((
*
itrh
).
coords_
.
begin
(),
(
*
itrh
).
coords_
.
end
(),
CLOCKWISE
,
true
);
}
}
}
return
*
this
;
}
// TODO:: should be private
template
<
typename
geometry_type
>
inline
polygon_set_data
&
...
...
@@ -481,6 +618,7 @@ namespace boost { namespace polygon {
bool
sizing_sign
=
resizing
>
0
;
bool
prev_concave
=
true
;
point_data
<
T
>
prev_point
;
//int iCtr=0;
//insert minkofski shapes on edges and corners
...
...
@@ -494,7 +632,9 @@ namespace boost { namespace polygon {
double
direction
=
normal1
.
x
()
*
normal2
.
y
()
-
normal2
.
x
()
*
normal1
.
y
();
bool
convex
=
direction
>
0
;
bool
treat_as_concave
=
convex
^
sizing_sign
;
bool
treat_as_concave
=
!
convex
;
if
(
sizing_sign
)
treat_as_concave
=
convex
;
point_data
<
double
>
v
;
assign
(
v
,
normal1
);
double
s2
=
(
v
.
x
()
*
v
.
x
()
+
v
.
y
()
*
v
.
y
());
...
...
@@ -533,14 +673,14 @@ namespace boost { namespace polygon {
,
num_circle_segments
,
corner_fill_arc
))
{
if
(
first_pts
.
size
())
{
for
(
unsigned
i
=
0
;
i
<
pts
.
size
();
i
++
)
{
for
(
unsigned
i
nt
i
=
0
;
i
<
pts
.
size
();
i
++
)
{
sizingSet
.
insert_vertex_sequence
(
pts
[
i
].
begin
(),
pts
[
i
].
end
(),
winding
,
false
);
}
}
else
{
first_pts
=
pts
[
0
];
first_wdir
=
resize_wdir
;
for
(
unsigned
i
=
1
;
i
<
pts
.
size
();
i
++
)
{
for
(
unsigned
i
nt
i
=
1
;
i
<
pts
.
size
();
i
++
)
{
sizingSet
.
insert_vertex_sequence
(
pts
[
i
].
begin
(),
pts
[
i
].
end
(),
winding
,
false
);
}
}
...
...
@@ -573,7 +713,7 @@ namespace boost { namespace polygon {
//insert original shape
tmp
.
insert
(
poly
,
false
,
polygon_concept
());
if
(
((
resizing
<
0
)
^
hole
)
)
tmp
-=
sizingSet
;
if
(
(
resizing
<
0
)
^
hole
)
tmp
-=
sizingSet
;
else
tmp
+=
sizingSet
;
//tmp.clean();
insert
(
tmp
,
hole
);
...
...
@@ -662,13 +802,13 @@ namespace boost { namespace polygon {
typedef
polygon_set_concept
type
;
};
template
<
typename
T
>
inline
double
compute_area
(
point_data
<
T
>&
a
,
point_data
<
T
>&
b
,
point_data
<
T
>&
c
)
{
//
template <typename T>
//
inline double compute_area(point_data<T>& a, point_data<T>& b, point_data<T>& c) {
return
(
double
)(
b
.
x
()
-
a
.
x
())
*
(
double
)(
c
.
y
()
-
a
.
y
())
-
(
double
)(
c
.
x
()
-
a
.
x
())
*
(
double
)(
b
.
y
()
-
a
.
y
());
//
return (double)(b.x()-a.x())*(double)(c.y()-a.y())- (double)(c.x()-a.x())*(double)(b.y()-a.y());
}
//
}
template
<
typename
T
>
inline
int
make_resizing_vertex_list
(
std
::
vector
<
std
::
vector
<
point_data
<
T
>
>
>&
return_points
,
...
...
@@ -709,7 +849,7 @@ namespace boost { namespace polygon {
std
::
pair
<
point_data
<
double
>
,
point_data
<
double
>
>
he1
(
start_offset
,
mid1_offset
);
std
::
pair
<
point_data
<
double
>
,
point_data
<
double
>
>
he2
(
mid2_offset
,
end_offset
);
typedef
typename
high_precision_type
<
double
>::
type
high_precision
;
//
typedef typename high_precision_type<double>::type high_precision;
point_data
<
T
>
intersect
;
typename
scanline_base
<
T
>::
compute_intersection_pack
pack
;
...
...
@@ -723,8 +863,8 @@ namespace boost { namespace polygon {
return_points_back
.
push_back
(
start
);
return_points_back
.
push_back
(
curr_prev
);
/
*double d1= */
compute_area
(
intersect
,
middle
,
start
);
/
*double d2= */
compute_area
(
start
,
curr_prev
,
intersect
);
/
/double d1=
compute_area(intersect,middle,start);
/
/double d2=
compute_area(start,curr_prev,intersect);
curr_prev
=
intersect
;
...
...
@@ -754,7 +894,7 @@ namespace boost { namespace polygon {
ps
+=
2.0
*
our_pi
;
if
(
pe
<=
0.0
)
pe
+=
2.0
*
our_pi
;
if
(
ps
>=
2.0
*
M_PI
)
if
(
ps
>=
2.0
*
our_pi
)
ps
-=
2.0
*
our_pi
;
while
(
pe
<=
ps
)
pe
+=
2.0
*
our_pi
;
...
...
@@ -771,9 +911,9 @@ namespace boost { namespace polygon {
}
return_points
.
push_back
(
round_down
<
T
>
(
center
));
return_points
.
push_back
(
round_down
<
T
>
(
start
));
int
i
=
0
;
unsigned
int
i
=
0
;
double
curr_angle
=
ps
+
delta_angle
;
while
(
curr_angle
<
pe
-
0.01
&&
i
<
2
*
(
int
)
num_circle_segments
)
{
while
(
curr_angle
<
pe
-
0.01
&&
i
<
2
*
num_circle_segments
)
{
i
++
;
double
x
=
center
.
x
()
+
r
*
cos
(
curr_angle
);
double
y
=
center
.
y
()
+
r
*
sin
(
curr_angle
);
...
...
include/boost/polygon/polygon_set_traits.hpp
View file @
d48f6e00
...
...
@@ -121,7 +121,7 @@ namespace boost { namespace polygon{
static
inline
bool
clean
(
const
polygon_set_data
<
T
>&
polygon_set
)
{
polygon_set
.
clean
();
return
true
;
}
static
inline
bool
sorted
(
const
polygon_set_data
<
T
>&
polygon_set
)
{
int
untested
=
0
;
polygon_set
.
sort
();
return
true
;
}
static
inline
bool
sorted
(
const
polygon_set_data
<
T
>&
polygon_set
)
{
polygon_set
.
sort
();
return
true
;
}
};
}
...
...
include/boost/polygon/polygon_with_holes_data.hpp
View file @
d48f6e00
...
...
@@ -96,7 +96,7 @@ public:
return
holes_
.
size
();
}
p
rivate
:
p
ublic
:
polygon_data
<
coordinate_type
>
self_
;
std
::
list
<
hole_type
>
holes_
;
};
...
...
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
View file @
d48f6e00
...
...
@@ -131,33 +131,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
* so m_ZoneMinThickness is the min thickness of the filled zones areas
* the main polygon is stored in polyset_zone_solid_areas
*/
#if 1
{
/* creates the main polygon (i.e. the filled area using only one outline)
* in GroupA in Bool_Engine to do a BOOL_CORRECTION operation
* to reserve a m_ZoneMinThickness/2 margin around the outlines
*/
Bool_Engine
*
booleng
=
new
Bool_Engine
();
ArmBoolEng
(
booleng
,
true
);
CopyPolygonsFromFilledPolysListToBoolengine
(
booleng
,
GROUP_A
);
booleng
->
SetCorrectionFactor
(
(
double
)
-
margin
);
booleng
->
Do_Operation
(
BOOL_CORRECTION
);
/* Now copy the new outline in m_FilledPolysList */
m_FilledPolysList
.
clear
();
CopyPolygonsFromBoolengineToFilledPolysList
(
booleng
);
delete
booleng
;
CopyPolygonsFromFilledPolysListTotKPolygonList
(
this
,
polyset_zone_solid_areas
);
}
#else
/* currently does not work well.
* using kbool gives reliable results
* using boost::polygone gives erroneous results
*/
CopyPolygonsFromFilledPolysListTotKPolygonList
(
this
,
polyset_zone_solid_areas
);
polyset_zone_solid_areas
-=
margin
;
#endif
if
(
polyset_zone_solid_areas
.
size
()
==
0
)
return
;
...
...
@@ -523,82 +500,6 @@ void AddUnconnectedThermalStubsToKPolygonList( std::vector<CPolyPt>& aCornerBuff
}
/** Function CopyPolygonsFromFilledPolysListToBoolengine
* Copy (Add) polygons found in m_FilledPolysList to kbool BoolEngine
* m_FilledPolysList may have more than one polygon
* @param aBoolengine = kbool engine
* @param aGroup = group in kbool engine (GROUP_A or GROUP_B only)
* @return the corner count
*/
int
ZONE_CONTAINER
::
CopyPolygonsFromFilledPolysListToBoolengine
(
Bool_Engine
*
aBoolengine
,
GroupType
aGroup
)
{
unsigned
corners_count
=
m_FilledPolysList
.
size
();
int
count
=
0
;
unsigned
ic
=
0
;
while
(
ic
<
corners_count
)
{
if
(
aBoolengine
->
StartPolygonAdd
(
aGroup
)
)
{
for
(
;
ic
<
corners_count
;
ic
++
)
{
CPolyPt
*
corner
=
&
m_FilledPolysList
[
ic
];
aBoolengine
->
AddPoint
(
corner
->
x
,
corner
->
y
);
count
++
;
if
(
corner
->
end_contour
)
{
ic
++
;
break
;
}
}
aBoolengine
->
EndPolygonAdd
();
}
}
return
count
;
}
/** Function CopyPolygonsFromBoolengineToFilledPolysList
* Copy (Add) polygons created by kbool (after Do_Operation) to m_FilledPolysList
* @param aBoolengine = kbool engine
* @return the corner count
*/
int
ZONE_CONTAINER
::
CopyPolygonsFromBoolengineToFilledPolysList
(
Bool_Engine
*
aBoolengine
)
{
int
count
=
0
;
while
(
aBoolengine
->
StartPolygonGet
()
)
{
CPolyPt
corner
(
0
,
0
,
false
);
while
(
aBoolengine
->
PolygonHasMorePoints
()
)
{
corner
.
x
=
(
int
)
aBoolengine
->
GetPolygonXPoint
();
corner
.
y
=
(
int
)
aBoolengine
->
GetPolygonYPoint
();
corner
.
end_contour
=
false
;
// Flag this corner if starting a hole connection segment:
// This is used by draw functions to draw only useful segments (and not extra segments)
corner
.
utility
=
(
aBoolengine
->
GetPolygonPointEdgeType
()
==
KB_FALSE_EDGE
)
?
1
:
0
;
m_FilledPolysList
.
push_back
(
corner
);
count
++
;
}
corner
.
end_contour
=
true
;
m_FilledPolysList
.
pop_back
();
m_FilledPolysList
.
push_back
(
corner
);
aBoolengine
->
EndPolygonGet
();
}
return
count
;
}
void
AddPolygonCornersToKPolygonList
(
std
::
vector
<
CPolyPt
>&
aCornersBuffer
,
KPolygonSet
&
aKPolyList
)
...
...
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