Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
pyMKcam
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
machinery
pyMKcam
Commits
73cb1bb0
Commit
73cb1bb0
authored
Mar 24, 2012
by
Whitham D. Reeve II
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed old commented out code and converted PolygonExtractor.py to new Point tuple style.
parent
d45b6dcb
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
90 additions
and
270 deletions
+90
-270
Letters.py
pycam/Geometry/Letters.py
+0
-4
Line.py
pycam/Geometry/Line.py
+0
-19
Model.py
pycam/Geometry/Model.py
+0
-9
Plane.py
pycam/Geometry/Plane.py
+0
-5
PointKdtree.py
pycam/Geometry/PointKdtree.py
+0
-1
Polygon.py
pycam/Geometry/Polygon.py
+0
-37
PolygonExtractor.py
pycam/Geometry/PolygonExtractor.py
+85
-85
Triangle.py
pycam/Geometry/Triangle.py
+5
-31
__init__.py
pycam/Geometry/__init__.py
+0
-21
intersection.py
pycam/Geometry/intersection.py
+0
-58
No files found.
pycam/Geometry/Letters.py
View file @
73cb1bb0
...
@@ -119,7 +119,6 @@ class Charset(object):
...
@@ -119,7 +119,6 @@ class Charset(object):
for
character
in
line
:
for
character
in
line
:
if
character
==
" "
:
if
character
==
" "
:
base
=
padd
(
base
,
(
word_spacing
,
0
,
0
))
base
=
padd
(
base
,
(
word_spacing
,
0
,
0
))
#base = base.add(Point(word_spacing, 0, 0))
elif
character
in
self
.
letters
.
keys
():
elif
character
in
self
.
letters
.
keys
():
charset_letter
=
self
.
letters
[
character
]
charset_letter
=
self
.
letters
[
character
]
new_model
=
ContourModel
()
new_model
=
ContourModel
()
...
@@ -133,14 +132,11 @@ class Charset(object):
...
@@ -133,14 +132,11 @@ class Charset(object):
line_height
=
max
(
line_height
,
charset_letter
.
maxy
())
line_height
=
max
(
line_height
,
charset_letter
.
maxy
())
# shift the base position
# shift the base position
base
=
padd
(
base
,
(
charset_letter
.
maxx
()
+
letter_spacing
,
0
,
0
))
base
=
padd
(
base
,
(
charset_letter
.
maxx
()
+
letter_spacing
,
0
,
0
))
#base = base.add((charset_letter.maxx() + letter_spacing, 0, 0))
else
:
else
:
# unknown character - add a small whitespace
# unknown character - add a small whitespace
base
=
padd
(
base
,
(
letter_spacing
,
0
,
0
))
base
=
padd
(
base
,
(
letter_spacing
,
0
,
0
))
#base = base.add(Point(letter_spacing, 0, 0))
# go to the next line
# go to the next line
base
=
(
origin
[
0
],
base
[
1
]
-
line_height
*
line_factor
,
origin
[
2
])
base
=
(
origin
[
0
],
base
[
1
]
-
line_height
*
line_factor
,
origin
[
2
])
#base = Point(origin.x, base.y - line_height * line_factor, origin.z)
if
not
current_line
.
maxx
is
None
:
if
not
current_line
.
maxx
is
None
:
if
align
==
TEXT_ALIGN_CENTER
:
if
align
==
TEXT_ALIGN_CENTER
:
current_line
.
shift
(
-
current_line
.
maxx
/
2
,
0
,
0
)
current_line
.
shift
(
-
current_line
.
maxx
/
2
,
0
,
0
)
...
...
pycam/Geometry/Line.py
View file @
73cb1bb0
...
@@ -54,18 +54,15 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -54,18 +54,15 @@ class Line(IDGenerator, TransformableContainer):
def
vector
(
self
):
def
vector
(
self
):
if
self
.
_vector
is
None
:
if
self
.
_vector
is
None
:
self
.
_vector
=
psub
(
self
.
p2
,
self
.
p1
)
self
.
_vector
=
psub
(
self
.
p2
,
self
.
p1
)
#self._vector = self.p2.sub(self.p1)
return
self
.
_vector
return
self
.
_vector
@
property
@
property
def
dir
(
self
):
def
dir
(
self
):
return
pnormalized
(
self
.
vector
)
return
pnormalized
(
self
.
vector
)
#return self.vector.normalized()
@
property
@
property
def
len
(
self
):
def
len
(
self
):
return
pnorm
(
self
.
vector
)
return
pnorm
(
self
.
vector
)
#return self.vector.norm
@
property
@
property
def
minx
(
self
):
def
minx
(
self
):
...
@@ -125,8 +122,6 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -125,8 +122,6 @@ class Line(IDGenerator, TransformableContainer):
def
next
(
self
):
def
next
(
self
):
yield
"p1"
yield
"p1"
#yield self.p1
#yield lambda x: self.p2 = x
yield
"p2"
yield
"p2"
def
get_children_count
(
self
):
def
get_children_count
(
self
):
...
@@ -147,13 +142,11 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -147,13 +142,11 @@ class Line(IDGenerator, TransformableContainer):
def
point_with_length_multiply
(
self
,
l
):
def
point_with_length_multiply
(
self
,
l
):
return
padd
(
self
.
p1
,
pmul
(
self
.
dir
,
l
*
self
.
len
))
return
padd
(
self
.
p1
,
pmul
(
self
.
dir
,
l
*
self
.
len
))
#return self.p1.add(self.dir.mul(l*self.len))
def
get_length_line
(
self
,
length
):
def
get_length_line
(
self
,
length
):
""" return a line with the same direction and the specified length
""" return a line with the same direction and the specified length
"""
"""
return
Line
(
self
.
p1
,
padd
(
self
.
p1
,
pmul
(
self
.
dir
,
length
)))
return
Line
(
self
.
p1
,
padd
(
self
.
p1
,
pmul
(
self
.
dir
,
length
)))
#return Line(self.p1, self.p1.add(self.dir.mul(length)))
def
closest_point
(
self
,
p
):
def
closest_point
(
self
,
p
):
v
=
self
.
dir
v
=
self
.
dir
...
@@ -161,13 +154,10 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -161,13 +154,10 @@ class Line(IDGenerator, TransformableContainer):
# for zero-length lines
# for zero-length lines
return
self
.
p1
return
self
.
p1
l
=
pdot
(
self
.
p1
,
v
)
-
pdot
(
p
,
v
)
l
=
pdot
(
self
.
p1
,
v
)
-
pdot
(
p
,
v
)
#l = self.p1.dot(v) - p.dot(v)
return
psub
(
self
.
p1
,
pmul
(
v
,
l
))
return
psub
(
self
.
p1
,
pmul
(
v
,
l
))
#return self.p1.sub(v.mul(l))
def
dist_to_point_sq
(
self
,
p
):
def
dist_to_point_sq
(
self
,
p
):
return
pnormsq
(
psub
(
p
,
self
.
closes_point
(
p
)))
return
pnormsq
(
psub
(
p
,
self
.
closes_point
(
p
)))
#return p.sub(self.closest_point(p)).normsq
def
dist_to_point
(
self
,
p
):
def
dist_to_point
(
self
,
p
):
return
sqrt
(
self
.
dist_to_point_sq
(
p
))
return
sqrt
(
self
.
dist_to_point_sq
(
p
))
...
@@ -178,9 +168,7 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -178,9 +168,7 @@ class Line(IDGenerator, TransformableContainer):
return
True
return
True
dir1
=
pnormalized
(
psub
(
p
,
self
.
p1
))
dir1
=
pnormalized
(
psub
(
p
,
self
.
p1
))
#dir1 = p.sub(self.p1).normalized()
dir2
=
pnormalized
(
psub
(
self
.
p2
,
p
))
dir2
=
pnormalized
(
psub
(
self
.
p2
,
p
))
#dir2 = self.p2.sub(p).normalized()
# True if the two parts of the line have the same direction or if the
# True if the two parts of the line have the same direction or if the
# point is self.p1 or self.p2.
# point is self.p1 or self.p2.
return
(
dir1
==
dir2
==
self
.
dir
)
or
(
dir1
is
None
)
or
(
dir2
is
None
)
return
(
dir1
==
dir2
==
self
.
dir
)
or
(
dir1
is
None
)
or
(
dir2
is
None
)
...
@@ -210,19 +198,14 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -210,19 +198,14 @@ class Line(IDGenerator, TransformableContainer):
"""
"""
x1
,
x2
,
x3
,
x4
=
self
.
p1
,
self
.
p2
,
line
.
p1
,
line
.
p2
x1
,
x2
,
x3
,
x4
=
self
.
p1
,
self
.
p2
,
line
.
p1
,
line
.
p2
a
=
psub
(
x2
,
x1
)
a
=
psub
(
x2
,
x1
)
#a = x2.sub(x1)
b
=
psub
(
x4
,
x3
)
b
=
psub
(
x4
,
x3
)
#b = x4.sub(x3)
c
=
psub
(
x3
,
x1
)
c
=
psub
(
x3
,
x1
)
#c = x3.sub(x1)
# see http://mathworld.wolfram.com/Line-LineIntersection.html (24)
# see http://mathworld.wolfram.com/Line-LineIntersection.html (24)
try
:
try
:
factor
=
pdot
(
pcross
(
c
,
b
),
pcross
(
a
,
b
))
/
pnormsq
(
pcross
(
a
,
b
))
factor
=
pdot
(
pcross
(
c
,
b
),
pcross
(
a
,
b
))
/
pnormsq
(
pcross
(
a
,
b
))
#factor = c.cross(b).dot(a.cross(b)) / a.cross(b).normsq
except
ZeroDivisionError
:
except
ZeroDivisionError
:
# lines are parallel
# lines are parallel
# check if they are _one_ line
# check if they are _one_ line
#if a.cross(c).norm != 0:
if
pnorm
(
pcross
(
a
,
c
))
!=
0
:
if
pnorm
(
pcross
(
a
,
c
))
!=
0
:
# the lines are parallel with a distance
# the lines are parallel with a distance
return
None
,
None
return
None
,
None
...
@@ -232,7 +215,6 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -232,7 +215,6 @@ class Line(IDGenerator, TransformableContainer):
candidates
.
append
((
x3
,
pnorm
(
c
)
/
pnorm
(
a
)))
candidates
.
append
((
x3
,
pnorm
(
c
)
/
pnorm
(
a
)))
elif
self
.
is_point_inside
(
x4
):
elif
self
.
is_point_inside
(
x4
):
candidates
.
append
((
x4
,
pnorm
(
psub
(
line
.
p2
,
self
.
p1
))
/
pnorm
(
a
)))
candidates
.
append
((
x4
,
pnorm
(
psub
(
line
.
p2
,
self
.
p1
))
/
pnorm
(
a
)))
#candidates.append((x4, line.p2.sub(self.p1).norm / a.norm))
elif
line
.
is_point_inside
(
x1
):
elif
line
.
is_point_inside
(
x1
):
candidates
.
append
((
x1
,
0
))
candidates
.
append
((
x1
,
0
))
elif
line
.
is_point_inside
(
x2
):
elif
line
.
is_point_inside
(
x2
):
...
@@ -244,7 +226,6 @@ class Line(IDGenerator, TransformableContainer):
...
@@ -244,7 +226,6 @@ class Line(IDGenerator, TransformableContainer):
return
candidates
[
0
]
return
candidates
[
0
]
if
infinite_lines
or
(
-
epsilon
<=
factor
<=
1
+
epsilon
):
if
infinite_lines
or
(
-
epsilon
<=
factor
<=
1
+
epsilon
):
intersection
=
padd
(
x1
,
pmul
(
a
,
factor
))
intersection
=
padd
(
x1
,
pmul
(
a
,
factor
))
#intersection = x1.add(a.mul(factor))
# check if the intersection is between x3 and x4
# check if the intersection is between x3 and x4
if
infinite_lines
:
if
infinite_lines
:
return
intersection
,
factor
return
intersection
,
factor
...
...
pycam/Geometry/Model.py
View file @
73cb1bb0
...
@@ -980,7 +980,6 @@ class PolygonGroup(object):
...
@@ -980,7 +980,6 @@ class PolygonGroup(object):
line_distances
=
[]
line_distances
=
[]
for
line
in
self
.
lines
:
for
line
in
self
.
lines
:
cross_product
=
pcross
(
line
.
dir
,
psub
(
point
,
line
.
p1
))
cross_product
=
pcross
(
line
.
dir
,
psub
(
point
,
line
.
p1
))
#cross_product = line.dir.cross(point.sub(line.p1))
if
cross_product
[
2
]
>
0
:
if
cross_product
[
2
]
>
0
:
close_points
=
[]
close_points
=
[]
close_point
=
line
.
closest_point
(
point
)
close_point
=
line
.
closest_point
(
point
)
...
@@ -991,9 +990,7 @@ class PolygonGroup(object):
...
@@ -991,9 +990,7 @@ class PolygonGroup(object):
close_points
.
append
(
close_point
)
close_points
.
append
(
close_point
)
for
p
in
close_points
:
for
p
in
close_points
:
direction
=
psub
(
point
,
p
)
direction
=
psub
(
point
,
p
)
#direction = point.sub(p)
dist
=
pnorm
(
direction
)
dist
=
pnorm
(
direction
)
#dist = direction.norm
line_distances
.
append
(
dist
)
line_distances
.
append
(
dist
)
elif
cross_product
.
z
==
0
:
elif
cross_product
.
z
==
0
:
# the point is on the line
# the point is on the line
...
@@ -1071,7 +1068,6 @@ class Rectangle(IDGenerator, TransformableContainer):
...
@@ -1071,7 +1068,6 @@ class Rectangle(IDGenerator, TransformableContainer):
orders
=
((
p1
,
p2
,
p3
,
p4
),
(
p1
,
p2
,
p4
,
p3
),
(
p1
,
p3
,
p2
,
p4
),
orders
=
((
p1
,
p2
,
p3
,
p4
),
(
p1
,
p2
,
p4
,
p3
),
(
p1
,
p3
,
p2
,
p4
),
(
p1
,
p3
,
p4
,
p2
),
(
p1
,
p4
,
p2
,
p3
),
(
p1
,
p4
,
p3
,
p2
))
(
p1
,
p3
,
p4
,
p2
),
(
p1
,
p4
,
p2
,
p3
),
(
p1
,
p4
,
p3
,
p2
))
for
order
in
orders
:
for
order
in
orders
:
#if abs(order[0].sub(order[2]).norm - order[1].sub(order[3]).norm) < epsilon:
if
abs
(
pnorm
(
psub
(
order
[
0
],
order
[
2
]))
-
pnorm
(
psub
(
order
[
1
],
order
[
3
])))
<
epsilon
:
if
abs
(
pnorm
(
psub
(
order
[
0
],
order
[
2
]))
-
pnorm
(
psub
(
order
[
1
],
order
[
3
])))
<
epsilon
:
t1
=
Triangle
(
order
[
0
],
order
[
1
],
order
[
2
])
t1
=
Triangle
(
order
[
0
],
order
[
1
],
order
[
2
])
t2
=
Triangle
(
order
[
2
],
order
[
3
],
order
[
0
])
t2
=
Triangle
(
order
[
2
],
order
[
3
],
order
[
0
])
...
@@ -1101,10 +1097,6 @@ class Rectangle(IDGenerator, TransformableContainer):
...
@@ -1101,10 +1097,6 @@ class Rectangle(IDGenerator, TransformableContainer):
return
(
self
.
p1
,
self
.
p2
,
self
.
p3
,
self
.
p4
)
return
(
self
.
p1
,
self
.
p2
,
self
.
p3
,
self
.
p4
)
def
next
(
self
):
def
next
(
self
):
#yield self.p1
#yield self.p2
#yield self.p3
#yield self.p4
yield
"p1"
yield
"p1"
yield
"p2"
yield
"p2"
yield
"p3"
yield
"p3"
...
@@ -1141,7 +1133,6 @@ class Rectangle(IDGenerator, TransformableContainer):
...
@@ -1141,7 +1133,6 @@ class Rectangle(IDGenerator, TransformableContainer):
log
.
error
(
"Invalid number of vertices:
%
s"
%
unique_vertices
)
log
.
error
(
"Invalid number of vertices:
%
s"
%
unique_vertices
)
return
None
return
None
if
abs
(
pnorm
(
psub
(
unique_verticies
[
0
],
unique_verticies
[
1
]))
-
pnorm
(
psub
(
shared_vertices
[
0
],
shared_vertices
[
1
])))
<
epsilon
:
if
abs
(
pnorm
(
psub
(
unique_verticies
[
0
],
unique_verticies
[
1
]))
-
pnorm
(
psub
(
shared_vertices
[
0
],
shared_vertices
[
1
])))
<
epsilon
:
#if abs(unique_vertices[0].sub(unique_vertices[1]).norm - shared_vertices[0].sub(shared_vertices[1]).norm) < epsilon:
try
:
try
:
return
Rectangle
(
unique_vertices
[
0
],
unique_vertices
[
1
],
return
Rectangle
(
unique_vertices
[
0
],
unique_vertices
[
1
],
shared_vertices
[
0
],
shared_vertices
[
1
],
shared_vertices
[
0
],
shared_vertices
[
1
],
...
...
pycam/Geometry/Plane.py
View file @
73cb1bb0
...
@@ -77,13 +77,10 @@ class Plane(IDGenerator, TransformableContainer):
...
@@ -77,13 +77,10 @@ class Plane(IDGenerator, TransformableContainer):
if
direction
is
None
:
if
direction
is
None
:
return
(
None
,
INFINITE
)
return
(
None
,
INFINITE
)
denom
=
pdot
(
self
.
n
,
direction
)
denom
=
pdot
(
self
.
n
,
direction
)
#denom = self.n.dot(direction)
if
denom
==
0
:
if
denom
==
0
:
return
(
None
,
INFINITE
)
return
(
None
,
INFINITE
)
l
=
-
(
pdot
(
self
.
n
,
point
)
-
pdot
(
self
.
n
,
self
.
p
))
/
denom
l
=
-
(
pdot
(
self
.
n
,
point
)
-
pdot
(
self
.
n
,
self
.
p
))
/
denom
#l = -(self.n.dot(point) - self.n.dot(self.p)) / denom
cp
=
padd
(
point
,
pmul
(
direction
,
l
))
cp
=
padd
(
point
,
pmul
(
direction
,
l
))
#cp = point.add(direction.mul(l))
return
(
cp
,
l
)
return
(
cp
,
l
)
def
intersect_triangle
(
self
,
triangle
,
counter_clockwise
=
False
):
def
intersect_triangle
(
self
,
triangle
,
counter_clockwise
=
False
):
...
@@ -121,8 +118,6 @@ class Plane(IDGenerator, TransformableContainer):
...
@@ -121,8 +118,6 @@ class Plane(IDGenerator, TransformableContainer):
if
collision_line
.
len
==
0
:
if
collision_line
.
len
==
0
:
return
collision_line
return
collision_line
cross
=
pcross
(
self
.
n
,
collision_line
.
dir
)
cross
=
pcross
(
self
.
n
,
collision_line
.
dir
)
#cross = self.n.cross(collision_line.dir)
#if (cross.dot(triangle.normal) < 0) == bool(not counter_clockwise):
if
(
pdot
(
cross
,
triangle
.
normal
)
<
0
)
==
bool
(
not
counter_clockwise
):
if
(
pdot
(
cross
,
triangle
.
normal
)
<
0
)
==
bool
(
not
counter_clockwise
):
# anti-clockwise direction -> revert the direction of the line
# anti-clockwise direction -> revert the direction of the line
collision_line
=
Line
(
collision_line
.
p2
,
collision_line
.
p1
)
collision_line
=
Line
(
collision_line
.
p2
,
collision_line
.
p1
)
...
...
pycam/Geometry/PointKdtree.py
View file @
73cb1bb0
...
@@ -47,7 +47,6 @@ class PointKdtree(kdtree):
...
@@ -47,7 +47,6 @@ class PointKdtree(kdtree):
return
dx
*
dx
+
dy
*
dy
+
dz
*
dz
return
dx
*
dx
+
dy
*
dy
+
dz
*
dz
def
Point
(
self
,
x
,
y
,
z
):
def
Point
(
self
,
x
,
y
,
z
):
#return Point(x,y,z)
if
self
.
_n
:
if
self
.
_n
:
n
=
self
.
_n
n
=
self
.
_n
n
.
bound
=
(
x
,
y
,
z
)
n
.
bound
=
(
x
,
y
,
z
)
...
...
pycam/Geometry/Polygon.py
View file @
73cb1bb0
...
@@ -72,7 +72,6 @@ class PolygonInTree(IDGenerator):
...
@@ -72,7 +72,6 @@ class PolygonInTree(IDGenerator):
def
get_cost
(
self
,
other
):
def
get_cost
(
self
,
other
):
return
pnorm
(
psub
(
other
.
start
,
self
.
end
))
return
pnorm
(
psub
(
other
.
start
,
self
.
end
))
#return other.start.sub(self.end).norm
class
PolygonPositionSorter
(
object
):
class
PolygonPositionSorter
(
object
):
...
@@ -251,7 +250,6 @@ class Polygon(TransformableContainer):
...
@@ -251,7 +250,6 @@ class Polygon(TransformableContainer):
self
.
_update_limits
(
line
.
p2
)
self
.
_update_limits
(
line
.
p2
)
elif
self
.
_points
[
-
1
]
==
line
.
p1
:
elif
self
.
_points
[
-
1
]
==
line
.
p1
:
# the new Line can be added to the end of the polygon
# the new Line can be added to the end of the polygon
#if line.dir == self._points[-1].sub(self._points[-2]).normalized():
if
line
.
dir
==
pnormalized
(
psub
(
self
.
_points
[
-
1
],
self
.
_points
[
-
2
])):
if
line
.
dir
==
pnormalized
(
psub
(
self
.
_points
[
-
1
],
self
.
_points
[
-
2
])):
# Remove the last point, if the previous point combination
# Remove the last point, if the previous point combination
# is in line with the new Line. This avoids unnecessary
# is in line with the new Line. This avoids unnecessary
...
@@ -266,7 +264,6 @@ class Polygon(TransformableContainer):
...
@@ -266,7 +264,6 @@ class Polygon(TransformableContainer):
self
.
reset_cache
()
self
.
reset_cache
()
else
:
else
:
# the new Line can be added to the beginning of the polygon
# the new Line can be added to the beginning of the polygon
#if (len(self._points) > 1) and (line.dir == self._points[1].sub(self._points[0]).normalized()):
if
(
len
(
self
.
_points
)
>
1
)
and
(
line
.
dir
==
pnormalized
(
psub
(
self
.
_points
[
1
],
self
.
_points
[
0
]))):
if
(
len
(
self
.
_points
)
>
1
)
and
(
line
.
dir
==
pnormalized
(
psub
(
self
.
_points
[
1
],
self
.
_points
[
0
]))):
# Avoid points on straight lines - see above.
# Avoid points on straight lines - see above.
self
.
_points
.
pop
(
0
)
self
.
_points
.
pop
(
0
)
...
@@ -323,8 +320,6 @@ class Polygon(TransformableContainer):
...
@@ -323,8 +320,6 @@ class Polygon(TransformableContainer):
return
False
return
False
def
next
(
self
):
def
next
(
self
):
#for idx,point in enumerate(self._points):
# yield (idx, "_points")
yield
"_points"
yield
"_points"
yield
self
.
plane
yield
self
.
plane
...
@@ -418,16 +413,13 @@ class Polygon(TransformableContainer):
...
@@ -418,16 +413,13 @@ class Polygon(TransformableContainer):
return
None
return
None
else
:
else
:
return
pdiv
(
padd
(
self
.
_points
[
index
],
self
.
_points
[(
index
+
1
)
%
len
(
self
.
_points
)]),
2
)
return
pdiv
(
padd
(
self
.
_points
[
index
],
self
.
_points
[(
index
+
1
)
%
len
(
self
.
_points
)]),
2
)
#return self._points[index].add(self._points[(index + 1) % len(self._points)]).div(2)
def
get_lengths
(
self
):
def
get_lengths
(
self
):
result
=
[]
result
=
[]
for
index
in
range
(
len
(
self
.
_points
)
-
1
):
for
index
in
range
(
len
(
self
.
_points
)
-
1
):
result
.
append
(
pnorm
(
psub
(
self
.
_points
[
index
+
1
],
self
.
_points
[
index
])))
result
.
append
(
pnorm
(
psub
(
self
.
_points
[
index
+
1
],
self
.
_points
[
index
])))
#result.append(self._points[index + 1].sub(self._points[index]).norm)
if
self
.
is_closed
:
if
self
.
is_closed
:
result
.
append
(
pnorm
(
psub
(
self
.
_points
[
0
],
self
.
_points
[
-
1
])))
result
.
append
(
pnorm
(
psub
(
self
.
_points
[
0
],
self
.
_points
[
-
1
])))
#result.append(self._points[0].sub(self._points[-1]).norm)
return
result
return
result
def
get_max_inside_distance
(
self
):
def
get_max_inside_distance
(
self
):
...
@@ -436,13 +428,11 @@ class Polygon(TransformableContainer):
...
@@ -436,13 +428,11 @@ class Polygon(TransformableContainer):
if
len
(
self
.
_points
)
<
2
:
if
len
(
self
.
_points
)
<
2
:
return
None
return
None
distance
=
pnorm
(
psub
(
self
.
_points
[
1
],
self
.
_points
[
0
]))
distance
=
pnorm
(
psub
(
self
.
_points
[
1
],
self
.
_points
[
0
]))
#distance = self._points[1].sub(self._points[0]).norm
for
p1
in
self
.
_points
:
for
p1
in
self
.
_points
:
for
p2
in
self
.
_points
:
for
p2
in
self
.
_points
:
if
p1
is
p2
:
if
p1
is
p2
:
continue
continue
distance
=
max
(
distance
,
pnorm
(
psub
(
p2
,
p1
)))
distance
=
max
(
distance
,
pnorm
(
psub
(
p2
,
p1
)))
#distance = max(distance, p2.sub(p1).norm)
return
distance
return
distance
def
is_outer
(
self
):
def
is_outer
(
self
):
...
@@ -595,15 +585,11 @@ class Polygon(TransformableContainer):
...
@@ -595,15 +585,11 @@ class Polygon(TransformableContainer):
p1
=
self
.
_points
[
index
]
p1
=
self
.
_points
[
index
]
p2
=
self
.
_points
[(
index
+
1
)
%
len
(
self
.
_points
)]
p2
=
self
.
_points
[(
index
+
1
)
%
len
(
self
.
_points
)]
cross_offset
=
pnormalized
(
pcross
(
psub
(
p2
,
p1
),
self
.
plane
.
n
))
cross_offset
=
pnormalized
(
pcross
(
psub
(
p2
,
p1
),
self
.
plane
.
n
))
#cross_offset = p2.sub(p1).cross(self.plane.n).normalized()
bisector_normalized
=
self
.
get_bisector
(
index
)
bisector_normalized
=
self
.
get_bisector
(
index
)
factor
=
pdot
(
cross_offset
,
bisector_normalized
)
factor
=
pdot
(
cross_offset
,
bisector_normalized
)
#factor = cross_offset.dot(bisector_normalized)
if
factor
!=
0
:
if
factor
!=
0
:
bisector_sized
=
pmul
(
bisector_normalized
,
offset
/
factor
)
bisector_sized
=
pmul
(
bisector_normalized
,
offset
/
factor
)
#bisector_sized = bisector_normalized.mul(offset / factor)
return
padd
(
p1
,
bisector_sized
)
return
padd
(
p1
,
bisector_sized
)
#return p1.add(bisector_sized)
else
:
else
:
return
p2
return
p2
if
offset
*
2
>=
self
.
get_max_inside_distance
():
if
offset
*
2
>=
self
.
get_max_inside_distance
():
...
@@ -615,7 +601,6 @@ class Polygon(TransformableContainer):
...
@@ -615,7 +601,6 @@ class Polygon(TransformableContainer):
max_dist
=
1000
*
epsilon
max_dist
=
1000
*
epsilon
def
test_point_near
(
p
,
others
):
def
test_point_near
(
p
,
others
):
for
o
in
others
:
for
o
in
others
:
#if p.sub(o).norm < max_dist:
if
pnorm
(
psub
(
p
,
o
))
<
max_dist
:
if
pnorm
(
psub
(
p
,
o
))
<
max_dist
:
return
True
return
True
return
False
return
False
...
@@ -626,10 +611,7 @@ class Polygon(TransformableContainer):
...
@@ -626,10 +611,7 @@ class Polygon(TransformableContainer):
p1
=
points
[
index
]
p1
=
points
[
index
]
p2
=
points
[
next_index
]
p2
=
points
[
next_index
]
diff
=
psub
(
p2
,
p1
)
diff
=
psub
(
p2
,
p1
)
#diff = p2.sub(p1)
old_dir
=
pnormalized
(
psub
(
self
.
_points
[
next_index
],
self
.
_points
[
index
]))
old_dir
=
pnormalized
(
psub
(
self
.
_points
[
next_index
],
self
.
_points
[
index
]))
#old_dir = self._points[next_index].sub(self._points[index]).normalized()
#if diff.normalized() != old_dir:
if
pnormalized
(
diff
)
!=
old_dir
:
if
pnormalized
(
diff
)
!=
old_dir
:
# the direction turned around
# the direction turned around
if
pnorm
(
diff
)
>
max_dist
:
if
pnorm
(
diff
)
>
max_dist
:
...
@@ -663,7 +645,6 @@ class Polygon(TransformableContainer):
...
@@ -663,7 +645,6 @@ class Polygon(TransformableContainer):
# no lines are left
# no lines are left
print
"out 2"
print
"out 2"
return
[]
return
[]
#if prev_line.p2.sub(next_line.p1).norm > max_dist:
if
pnorm
(
psub
(
prev_line
.
p2
,
next_line
.
p1
))
>
max_dist
:
if
pnorm
(
psub
(
prev_line
.
p2
,
next_line
.
p1
))
>
max_dist
:
cp
,
dist
=
prev_line
.
get_intersection
(
next_line
)
cp
,
dist
=
prev_line
.
get_intersection
(
next_line
)
else
:
else
:
...
@@ -711,9 +692,7 @@ class Polygon(TransformableContainer):
...
@@ -711,9 +692,7 @@ class Polygon(TransformableContainer):
# maybe we have been here before
# maybe we have been here before
if
not
cp
in
split_points
:
if
not
cp
in
split_points
:
split_points
.
append
(
cp
)
split_points
.
append
(
cp
)
#elif (cp.sub(line.p1).norm < max_dist) or (cp.sub(line.p2).norm < max_dist):
elif
(
pnorm
(
psub
(
cp
,
line
.
p1
))
<
max_dist
)
or
(
pnorm
(
psub
(
cp
,
line
.
p2
))
<
max_dist
):
elif
(
pnorm
(
psub
(
cp
,
line
.
p1
))
<
max_dist
)
or
(
pnorm
(
psub
(
cp
,
line
.
p2
))
<
max_dist
):
#if cp.sub(line.p1).norm < cp.sub(line.p2).norm:
if
pnorm
(
psub
(
cp
,
lines
.
p1
))
<
pnorm
(
psub
(
cp
,
line
.
p2
)):
if
pnorm
(
psub
(
cp
,
lines
.
p1
))
<
pnorm
(
psub
(
cp
,
line
.
p2
)):
non_reversed
[
index
]
=
Line
(
cp
,
line
.
p2
)
non_reversed
[
index
]
=
Line
(
cp
,
line
.
p2
)
else
:
else
:
...
@@ -790,7 +769,6 @@ class Polygon(TransformableContainer):
...
@@ -790,7 +769,6 @@ class Polygon(TransformableContainer):
if
len
(
group
)
<=
2
:
if
len
(
group
)
<=
2
:
continue
continue
poly
=
Polygon
(
self
.
plane
)
poly
=
Polygon
(
self
.
plane
)
#print "**************************************"
for
line
in
group
:
for
line
in
group
:
try
:
try
:
poly
.
append
(
line
)
poly
.
append
(
line
)
...
@@ -871,15 +849,11 @@ class Polygon(TransformableContainer):
...
@@ -871,15 +849,11 @@ class Polygon(TransformableContainer):
p1
=
self
.
_points
[
index
]
p1
=
self
.
_points
[
index
]
p2
=
self
.
_points
[(
index
+
1
)
%
len
(
self
.
_points
)]
p2
=
self
.
_points
[(
index
+
1
)
%
len
(
self
.
_points
)]
cross_offset
=
pnormalized
(
pcross
(
psub
(
p2
,
p1
),
self
.
plane
.
n
))
cross_offset
=
pnormalized
(
pcross
(
psub
(
p2
,
p1
),
self
.
plane
.
n
))
#cross_offset = p2.sub(p1).cross(self.plane.n).normalized()
bisector_normalized
=
self
.
get_bisector
(
index
)
bisector_normalized
=
self
.
get_bisector
(
index
)
factor
=
pdot
(
cross_offset
,
bisector_normalized
)
factor
=
pdot
(
cross_offset
,
bisector_normalized
)
#factor = cross_offset.dot(bisector_normalized)
if
factor
!=
0
:
if
factor
!=
0
:
bisector_sized
=
pmul
(
bisector_normalized
,
offset
/
factor
)
bisector_sized
=
pmul
(
bisector_normalized
,
offset
/
factor
)
#bisector_sized = bisector_normalized.mul(offset / factor)
return
padd
(
p1
,
bisector_sized
)
return
padd
(
p1
,
bisector_sized
)
#return p1.add(bisector_sized)
else
:
else
:
return
p2
return
p2
def
simplify_polygon_intersections
(
lines
):
def
simplify_polygon_intersections
(
lines
):
...
@@ -1056,16 +1030,13 @@ class Polygon(TransformableContainer):
...
@@ -1056,16 +1030,13 @@ class Polygon(TransformableContainer):
return
Line
(
line
.
p1
,
line
.
p2
)
return
Line
(
line
.
p1
,
line
.
p2
)
else
:
else
:
cross_offset
=
pmul
(
pnormalized
(
pcross
(
line
.
dir
,
self
.
plane
.
n
)),
offset
)
cross_offset
=
pmul
(
pnormalized
(
pcross
(
line
.
dir
,
self
.
plane
.
n
)),
offset
)
#cross_offset = line.dir.cross(self.plane.n).normalized().mul(offset)
# Prolong the line at the beginning and at the end - to allow
# Prolong the line at the beginning and at the end - to allow
# overlaps. Use factor "2" to take care for star-like structure
# overlaps. Use factor "2" to take care for star-like structure
# where a complete convex triangle would get cropped (two lines
# where a complete convex triangle would get cropped (two lines
# get lost instead of just one). Use the "abs" value to
# get lost instead of just one). Use the "abs" value to
# compensate negative offsets.
# compensate negative offsets.
in_line
=
pmul
(
line
.
dir
,
2
*
abs
(
offset
))
in_line
=
pmul
(
line
.
dir
,
2
*
abs
(
offset
))
#in_line = line.dir.mul(2 * abs(offset))
return
Line
(
psub
(
padd
(
line
.
p1
,
cross_offset
),
in_line
),
padd
(
padd
(
line
.
p2
,
cross_offset
),
in_line
))
return
Line
(
psub
(
padd
(
line
.
p1
,
cross_offset
),
in_line
),
padd
(
padd
(
line
.
p2
,
cross_offset
),
in_line
))
#return Line(line.p1.add(cross_offset).sub(in_line), line.p2.add(cross_offset).add(in_line))
def
do_lines_intersection
(
l1
,
l2
):
def
do_lines_intersection
(
l1
,
l2
):
""" calculate the new intersection between two neighbouring lines
""" calculate the new intersection between two neighbouring lines
"""
"""
...
@@ -1078,15 +1049,11 @@ class Polygon(TransformableContainer):
...
@@ -1078,15 +1049,11 @@ class Polygon(TransformableContainer):
return
return
x1
,
x2
,
x3
,
x4
=
l2
.
p1
,
l2
.
p2
,
l1
.
p1
,
l1
.
p2
x1
,
x2
,
x3
,
x4
=
l2
.
p1
,
l2
.
p2
,
l1
.
p1
,
l1
.
p2
a
=
psub
(
x2
,
x1
)
a
=
psub
(
x2
,
x1
)
#a = x2.sub(x1)
b
=
psub
(
x4
,
x3
)
b
=
psub
(
x4
,
x3
)
#b = x4.sub(x3)
c
=
psub
(
x3
,
x1
)
c
=
psub
(
x3
,
x1
)
#c = x3.sub(x1)
# see http://mathworld.wolfram.com/Line-LineIntersection.html (24)
# see http://mathworld.wolfram.com/Line-LineIntersection.html (24)
try
:
try
:
factor
=
pdot
(
pcross
(
c
,
b
),
pcross
(
a
,
b
))
/
pnormsq
(
pcross
(
a
,
b
))
factor
=
pdot
(
pcross
(
c
,
b
),
pcross
(
a
,
b
))
/
pnormsq
(
pcross
(
a
,
b
))
#factor = c.cross(b).dot(a.cross(b)) / a.cross(b).normsq
except
ZeroDivisionError
:
except
ZeroDivisionError
:
l2
.
p1
=
None
l2
.
p1
=
None
return
return
...
@@ -1095,7 +1062,6 @@ class Polygon(TransformableContainer):
...
@@ -1095,7 +1062,6 @@ class Polygon(TransformableContainer):
l2
.
p1
=
None
l2
.
p1
=
None
else
:
else
:
intersection
=
padd
(
x1
,
pmul
(
a
,
factor
))
intersection
=
padd
(
x1
,
pmul
(
a
,
factor
))
#intersection = x1.add(a.mul(factor))
if
Line
(
l1
.
p1
,
intersection
)
.
dir
!=
l1
.
dir
:
if
Line
(
l1
.
p1
,
intersection
)
.
dir
!=
l1
.
dir
:
# Remove lines that would change their direction due to the
# Remove lines that would change their direction due to the
# new intersection. These are usually lines that become
# new intersection. These are usually lines that become
...
@@ -1338,14 +1304,12 @@ class Polygon(TransformableContainer):
...
@@ -1338,14 +1304,12 @@ class Polygon(TransformableContainer):
for
index
in
range
(
len
(
collisions
)
-
1
):
for
index
in
range
(
len
(
collisions
)
-
1
):
p1
=
collisions
[
index
][
0
]
p1
=
collisions
[
index
][
0
]
p2
=
collisions
[
index
+
1
][
0
]
p2
=
collisions
[
index
+
1
][
0
]
#if p1.sub(p2).norm < epsilon:
if
pnorm
(
psub
(
p1
,
p2
))
<
epsilon
:
if
pnorm
(
psub
(
p1
,
p2
))
<
epsilon
:
# ignore zero-length lines
# ignore zero-length lines
continue
continue
# Use the middle between p1 and p2 to check the
# Use the middle between p1 and p2 to check the
# inner/outer state.
# inner/outer state.
p_middle
=
pdiv
(
padd
(
p1
,
p2
),
2
)
p_middle
=
pdiv
(
padd
(
p1
,
p2
),
2
)
#p_middle = p1.add(p2).div(2)
p_inside
=
poly2
.
is_point_inside
(
p_middle
)
\
p_inside
=
poly2
.
is_point_inside
(
p_middle
)
\
and
not
poly2
.
is_point_on_outline
(
p_middle
)
and
not
poly2
.
is_point_on_outline
(
p_middle
)
if
not
p_inside
:
if
not
p_inside
:
...
@@ -1391,7 +1355,6 @@ class Polygon(TransformableContainer):
...
@@ -1391,7 +1355,6 @@ class Polygon(TransformableContainer):
p2
,
d2
=
intersections
[
index
+
1
]
p2
,
d2
=
intersections
[
index
+
1
]
if
p1
!=
p2
:
if
p1
!=
p2
:
middle
=
pdiv
(
padd
(
p1
,
p2
),
2
)
middle
=
pdiv
(
padd
(
p1
,
p2
),
2
)
#middle = p1.add(p2).div(2)
new_line
=
Line
(
get_original_point
(
d1
),
get_original_point
(
d2
))
new_line
=
Line
(
get_original_point
(
d1
),
get_original_point
(
d2
))
if
self
.
is_point_inside
(
middle
):
if
self
.
is_point_inside
(
middle
):
inner
.
append
(
new_line
)
inner
.
append
(
new_line
)
...
...
pycam/Geometry/PolygonExtractor.py
View file @
73cb1bb0
...
@@ -80,7 +80,7 @@ class PolygonExtractor(object):
...
@@ -80,7 +80,7 @@ class PolygonExtractor(object):
print
"points="
,
path
.
points
print
"points="
,
path
.
points
i
=
0
i
=
0
while
i
<
len
(
path
.
points
)
-
1
:
while
i
<
len
(
path
.
points
)
-
1
:
if
path
.
points
[
i
]
.
x
>
path
.
points
[
i
+
1
]
.
x
:
if
path
.
points
[
i
]
[
0
]
>
path
.
points
[
i
+
1
][
0
]
:
if
DEBUG_POLYGONEXTRACTOR2
:
if
DEBUG_POLYGONEXTRACTOR2
:
print
"drop point
%
d:"
%
path
.
points
[
i
]
.
id
print
"drop point
%
d:"
%
path
.
points
[
i
]
.
id
path
.
points
=
path
.
points
[:
i
]
+
path
.
points
[
i
+
1
:]
path
.
points
=
path
.
points
[:
i
]
+
path
.
points
[
i
+
1
:]
...
@@ -95,7 +95,7 @@ class PolygonExtractor(object):
...
@@ -95,7 +95,7 @@ class PolygonExtractor(object):
print
"
%
d:"
%
path
.
id
,
print
"
%
d:"
%
path
.
id
,
print
"
%
d ->"
%
path
.
top_join
.
id
print
"
%
d ->"
%
path
.
top_join
.
id
for
point
in
path
.
points
:
for
point
in
path
.
points
:
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
.
x
,
point
.
y
),
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
[
0
],
point
[
1
]
),
print
"->
%
d"
%
path
.
bot_join
.
id
print
"->
%
d"
%
path
.
bot_join
.
id
path_list
=
[]
path_list
=
[]
...
@@ -133,7 +133,7 @@ class PolygonExtractor(object):
...
@@ -133,7 +133,7 @@ class PolygonExtractor(object):
for
path
in
path_list
:
for
path
in
path_list
:
print
"path
%
d(w=
%
d): "
%
(
path
.
id
,
path
.
winding
),
print
"path
%
d(w=
%
d): "
%
(
path
.
id
,
path
.
winding
),
for
point
in
path
.
points
:
for
point
in
path
.
points
:
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
.
x
,
point
.
y
),
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
[
0
],
point
[
1
]
),
print
print
if
self
.
current_dir
==
0
:
if
self
.
current_dir
==
0
:
...
@@ -156,13 +156,13 @@ class PolygonExtractor(object):
...
@@ -156,13 +156,13 @@ class PolygonExtractor(object):
self
.
svg
.
fill
(
"red"
)
self
.
svg
.
fill
(
"red"
)
else
:
else
:
self
.
svg
.
fill
(
"blue"
)
self
.
svg
.
fill
(
"blue"
)
self
.
svg
.
AddDot
(
p
.
x
,
p
.
y
)
self
.
svg
.
AddDot
(
p
[
0
],
p
[
1
]
)
self
.
svg
.
AddText
(
p
.
x
,
p
.
y
,
str
(
p
.
id
))
self
.
svg
.
AddText
(
p
[
0
],
p
[
1
]
,
str
(
p
.
id
))
if
prev
:
if
prev
:
self
.
svg
.
AddLine
(
p
.
x
,
p
.
y
,
prev
.
x
,
prev
.
y
)
self
.
svg
.
AddLine
(
p
[
0
],
p
[
1
],
prev
[
0
],
prev
[
1
]
)
prev
=
p
prev
=
p
p
=
path
.
points
[
0
]
p
=
path
.
points
[
0
]
self
.
svg
.
AddLine
(
p
.
x
,
p
.
y
,
prev
.
x
,
prev
.
y
)
self
.
svg
.
AddLine
(
p
[
0
],
p
[
1
],
prev
[
0
],
prev
[
1
]
)
self
.
svg
.
close
()
self
.
svg
.
close
()
self
.
cont
.
close
()
self
.
cont
.
close
()
...
@@ -176,8 +176,8 @@ class PolygonExtractor(object):
...
@@ -176,8 +176,8 @@ class PolygonExtractor(object):
def
append
(
self
,
p
):
def
append
(
self
,
p
):
if
DEBUG_POLYGONEXTRACTOR3
:
if
DEBUG_POLYGONEXTRACTOR3
:
p
.
dir
=
self
.
current_dir
p
.
dir
=
self
.
current_dir
self
.
svg
.
AddDot
(
p
.
x
,
p
.
y
)
self
.
svg
.
AddDot
(
p
[
0
],
p
[
1
]
)
self
.
svg
.
AddText
(
p
.
x
,
p
.
y
,
str
(
p
.
id
))
self
.
svg
.
AddText
(
p
[
0
],
p
[
1
]
,
str
(
p
.
id
))
self
.
curr_line
.
append
(
p
)
self
.
curr_line
.
append
(
p
)
def
end_scanline
(
self
):
def
end_scanline
(
self
):
...
@@ -187,7 +187,7 @@ class PolygonExtractor(object):
...
@@ -187,7 +187,7 @@ class PolygonExtractor(object):
if
self
.
policy
==
PolygonExtractor
.
CONTOUR
and
self
.
hor_path_list
:
if
self
.
policy
==
PolygonExtractor
.
CONTOUR
and
self
.
hor_path_list
:
next_x
=
-
INFINITE
next_x
=
-
INFINITE
if
len
(
self
.
curr_line
)
>
0
:
if
len
(
self
.
curr_line
)
>
0
:
next_x
=
self
.
curr_line
[
0
]
.
x
next_x
=
self
.
curr_line
[
0
]
[
0
]
self
.
delta_x
=
next_x
-
self
.
last_x
self
.
delta_x
=
next_x
-
self
.
last_x
self
.
last_x
=
next_x
self
.
last_x
=
next_x
else
:
else
:
...
@@ -204,7 +204,7 @@ class PolygonExtractor(object):
...
@@ -204,7 +204,7 @@ class PolygonExtractor(object):
inside
=
False
inside
=
False
s
=
""
s
=
""
for
point
in
scanline
:
for
point
in
scanline
:
next_x
=
point
.
x
next_x
=
point
[
0
]
if
inside
:
if
inside
:
s
+=
"*"
*
int
(
next_x
-
last
)
s
+=
"*"
*
int
(
next_x
-
last
)
else
:
else
:
...
@@ -217,17 +217,17 @@ class PolygonExtractor(object):
...
@@ -217,17 +217,17 @@ class PolygonExtractor(object):
print
"active paths: "
,
print
"active paths: "
,
for
path
in
self
.
curr_path_list
:
for
path
in
self
.
curr_path_list
:
print
"
%
d(
%
g,
%
g)"
\
print
"
%
d(
%
g,
%
g)"
\
%
(
path
.
id
,
path
.
points
[
-
1
]
.
x
,
path
.
points
[
-
1
]
.
y
),
%
(
path
.
id
,
path
.
points
[
-
1
]
[
0
],
path
.
points
[
-
1
][
1
]
),
print
print
print
"prev points: "
,
print
"prev points: "
,
for
point
in
self
.
prev_line
:
for
point
in
self
.
prev_line
:
print
"(
%
g,
%
g)"
%
(
point
.
x
,
point
.
y
),
print
"(
%
g,
%
g)"
%
(
point
[
0
],
point
[
1
]
),
print
print
print
"active points: "
,
print
"active points: "
,
for
point
in
scanline
:
for
point
in
scanline
:
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
.
x
,
point
.
y
),
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
[
0
],
point
.
[
1
]
),
print
print
prev_point
=
Iterator
(
self
.
prev_line
)
prev_point
=
Iterator
(
self
.
prev_line
)
...
@@ -246,13 +246,13 @@ class PolygonExtractor(object):
...
@@ -246,13 +246,13 @@ class PolygonExtractor(object):
p0
=
Path
()
p0
=
Path
()
p0
.
winding
=
winding
+
1
p0
.
winding
=
winding
+
1
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g)"
%
(
p0
.
id
,
c0
.
x
,
c0
.
y
)
print
"new path
%
d(
%
g,
%
g)"
%
(
p0
.
id
,
c0
[
0
],
c0
[
1
]
)
p0
.
append
(
c0
)
p0
.
append
(
c0
)
self
.
curr_path_list
.
append
(
p0
)
self
.
curr_path_list
.
append
(
p0
)
p1
=
Path
()
p1
=
Path
()
p1
.
winding
=
winding
p1
.
winding
=
winding
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g)"
%
(
p1
.
id
,
c1
.
x
,
c1
.
y
)
print
"new path
%
d(
%
g,
%
g)"
%
(
p1
.
id
,
c1
[
0
],
c1
[
1
]
)
p1
.
append
(
c1
)
p1
.
append
(
c1
)
self
.
curr_path_list
.
append
(
p1
)
self
.
curr_path_list
.
append
(
p1
)
p0
.
top_join
=
p1
p0
.
top_join
=
p1
...
@@ -282,16 +282,16 @@ class PolygonExtractor(object):
...
@@ -282,16 +282,16 @@ class PolygonExtractor(object):
c1
=
curr_point
.
peek
(
1
)
c1
=
curr_point
.
peek
(
1
)
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"overlap test: p0=
%
g p1=
%
g"
%
(
p0
.
x
,
p1
.
x
)
print
"overlap test: p0=
%
g p1=
%
g"
%
(
p0
[
0
],
p1
[
0
]
)
print
"overlap test: c0=
%
g c1=
%
g"
%
(
c0
.
x
,
c1
.
x
)
print
"overlap test: c0=
%
g c1=
%
g"
%
(
c0
[
0
],
c1
[
0
]
)
if
c1
.
x
<
p0
.
x
:
if
c1
[
0
]
<
p0
[
0
]
:
# new segment is completely to the left
# new segment is completely to the left
# new path starts
# new path starts
s0
=
Path
()
s0
=
Path
()
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
%
(
s0
.
id
,
c0
.
x
,
c0
.
y
,
winding
+
1
)
%
(
s0
.
id
,
c0
[
0
],
c0
[
0
]
,
winding
+
1
)
s0
.
append
(
c0
)
s0
.
append
(
c0
)
curr_path
.
insert
(
s0
)
curr_path
.
insert
(
s0
)
s1
=
Path
()
s1
=
Path
()
...
@@ -299,14 +299,14 @@ class PolygonExtractor(object):
...
@@ -299,14 +299,14 @@ class PolygonExtractor(object):
s1
.
winding
=
winding
s1
.
winding
=
winding
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
%
(
s1
.
id
,
c1
.
x
,
c1
.
y
,
winding
)
%
(
s1
.
id
,
c1
[
0
],
c1
[
1
]
,
winding
)
s1
.
append
(
c1
)
s1
.
append
(
c1
)
curr_path
.
insert
(
s1
)
curr_path
.
insert
(
s1
)
curr_point
.
next
()
curr_point
.
next
()
curr_point
.
next
()
curr_point
.
next
()
s0
.
top_join
=
s1
s0
.
top_join
=
s1
s1
.
top_join
=
s0
s1
.
top_join
=
s0
elif
c0
.
x
>
p1
.
x
:
elif
c0
[
0
]
>
p1
[
0
]
:
# new segment is completely to the right
# new segment is completely to the right
# old path ends
# old path ends
s0
=
curr_path
.
takeNext
()
s0
=
curr_path
.
takeNext
()
...
@@ -342,9 +342,9 @@ class PolygonExtractor(object):
...
@@ -342,9 +342,9 @@ class PolygonExtractor(object):
p2
=
prev_point
.
peek
(
1
)
p2
=
prev_point
.
peek
(
1
)
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"join test: p0=
%
g p1=
%
g p2=
%
g"
\
print
"join test: p0=
%
g p1=
%
g p2=
%
g"
\
%
(
p0
.
x
,
p1
.
x
,
p2
.
x
)
%
(
p0
[
0
],
p1
[
0
],
p2
[
0
]
)
print
"join test: c0=
%
g c1=
%
g"
%
(
c0
.
x
,
c1
.
x
)
print
"join test: c0=
%
g c1=
%
g"
%
(
c0
[
0
],
c1
[
0
]
)
if
p2
.
x
<=
c1
.
x
:
if
p2
[
0
]
<=
c1
[
0
]
:
overlap_p
=
True
overlap_p
=
True
if
self
.
policy
==
PolygonExtractor
.
CONTOUR
:
if
self
.
policy
==
PolygonExtractor
.
CONTOUR
:
s0
=
curr_path
.
takeNext
()
s0
=
curr_path
.
takeNext
()
...
@@ -384,10 +384,10 @@ class PolygonExtractor(object):
...
@@ -384,10 +384,10 @@ class PolygonExtractor(object):
if
curr_point
.
remains
()
>=
2
:
if
curr_point
.
remains
()
>=
2
:
c2
=
curr_point
.
peek
(
1
)
c2
=
curr_point
.
peek
(
1
)
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"split test: p0=
%
g p1=
%
g"
%
(
p0
.
x
,
p1
.
x
)
print
"split test: p0=
%
g p1=
%
g"
%
(
p0
[
0
],
p1
[
0
]
)
print
"split test: c0=
%
g c1=
%
g c2=
%
g"
\
print
"split test: c0=
%
g c1=
%
g c2=
%
g"
\
%
(
c0
.
x
,
c1
.
x
,
c2
.
x
)
%
(
c0
[
0
],
c1
[
0
],
c2
[
0
]
)
if
c2
.
x
<=
p1
.
x
:
if
c2
[
0
]
<=
p1
[
0
]
:
overlap_c
=
True
overlap_c
=
True
s0
=
Path
()
s0
=
Path
()
s1
=
Path
()
s1
=
Path
()
...
@@ -419,14 +419,14 @@ class PolygonExtractor(object):
...
@@ -419,14 +419,14 @@ class PolygonExtractor(object):
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"add to path
%
d(
%
g,
%
g)"
\
print
"add to path
%
d(
%
g,
%
g)"
\
%
(
left_path
.
id
,
left_point
.
x
,
left_point
.
y
)
%
(
left_path
.
id
,
left_point
[
0
],
left_point
[
1
]
)
left_path
.
append
(
left_point
)
left_path
.
append
(
left_point
)
right_path
.
append
(
right_point
)
right_path
.
append
(
right_point
)
if
right_path
==
curr_path
.
peek
():
if
right_path
==
curr_path
.
peek
():
curr_path
.
next
()
curr_path
.
next
()
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"add to path
%
d(
%
g,
%
g)"
\
print
"add to path
%
d(
%
g,
%
g)"
\
%
(
right_path
.
id
,
right_point
.
x
,
right_point
.
y
)
%
(
right_path
.
id
,
right_point
[
0
],
right_point
[
1
]
)
winding
=
right_path
.
winding
winding
=
right_path
.
winding
prev_point
.
next
()
prev_point
.
next
()
curr_point
.
next
()
curr_point
.
next
()
...
@@ -434,8 +434,8 @@ class PolygonExtractor(object):
...
@@ -434,8 +434,8 @@ class PolygonExtractor(object):
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"active paths: "
,
print
"active paths: "
,
for
path
in
self
.
curr_path_list
:
for
path
in
self
.
curr_path_list
:
print
"
%
d(
%
g,
%
g,w=
%
d)"
%
(
path
.
id
,
path
.
points
[
-
1
]
.
x
,
print
"
%
d(
%
g,
%
g,w=
%
d)"
%
(
path
.
id
,
path
.
points
[
-
1
]
[
0
]
,
path
.
points
[
-
1
]
.
y
,
path
.
winding
),
path
.
points
[
-
1
]
[
1
]
,
path
.
winding
),
print
print
self
.
prev_line
=
scanline
self
.
prev_line
=
scanline
...
@@ -448,11 +448,11 @@ class PolygonExtractor(object):
...
@@ -448,11 +448,11 @@ class PolygonExtractor(object):
self
.
cont
.
fill
(
"red"
)
self
.
cont
.
fill
(
"red"
)
else
:
else
:
self
.
cont
.
fill
(
"blue"
)
self
.
cont
.
fill
(
"blue"
)
self
.
cont
.
AddDot
(
p
.
x
,
p
.
y
)
self
.
cont
.
AddDot
(
p
[
0
],
p
[
1
]
)
self
.
cont
.
fill
(
"black"
)
self
.
cont
.
fill
(
"black"
)
self
.
cont
.
AddText
(
p
.
x
,
p
.
y
,
str
(
p
.
id
))
self
.
cont
.
AddText
(
p
[
0
],
p
[
1
]
,
str
(
p
.
id
))
if
prev
:
if
prev
:
self
.
cont
.
AddLine
(
prev
.
x
,
prev
.
y
,
p
.
x
,
p
.
y
)
self
.
cont
.
AddLine
(
prev
[
0
],
prev
[
1
],
p
[
0
],
p
[
1
]
)
prev
=
p
prev
=
p
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
...
@@ -460,7 +460,7 @@ class PolygonExtractor(object):
...
@@ -460,7 +460,7 @@ class PolygonExtractor(object):
inside
=
False
inside
=
False
s
=
""
s
=
""
for
point
in
scanline
:
for
point
in
scanline
:
next_y
=
point
.
y
next_y
=
point
[
1
]
if
inside
:
if
inside
:
s
+=
"*"
*
int
(
next_y
-
last
)
s
+=
"*"
*
int
(
next_y
-
last
)
else
:
else
:
...
@@ -473,17 +473,17 @@ class PolygonExtractor(object):
...
@@ -473,17 +473,17 @@ class PolygonExtractor(object):
print
"active paths: "
,
print
"active paths: "
,
for
path
in
self
.
curr_path_list
:
for
path
in
self
.
curr_path_list
:
print
"
%
d(
%
g,
%
g)"
\
print
"
%
d(
%
g,
%
g)"
\
%
(
path
.
id
,
path
.
points
[
-
1
]
.
x
,
path
.
points
[
-
1
]
.
y
),
%
(
path
.
id
,
path
.
points
[
-
1
]
[
0
],
path
.
points
[
-
1
][
1
]
),
print
print
print
"prev points: "
,
print
"prev points: "
,
for
point
in
self
.
prev_line
:
for
point
in
self
.
prev_line
:
print
"(
%
g,
%
g)"
%
(
point
.
x
,
point
.
y
),
print
"(
%
g,
%
g)"
%
(
point
[
0
],
point
[
1
]
),
print
print
print
"active points: "
,
print
"active points: "
,
for
point
in
scanline
:
for
point
in
scanline
:
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
.
x
,
point
.
y
),
print
"
%
d(
%
g,
%
g)"
%
(
point
.
id
,
point
[
0
],
point
[
1
]
),
print
print
prev_point
=
Iterator
(
self
.
prev_line
)
prev_point
=
Iterator
(
self
.
prev_line
)
...
@@ -502,13 +502,13 @@ class PolygonExtractor(object):
...
@@ -502,13 +502,13 @@ class PolygonExtractor(object):
p0
=
Path
()
p0
=
Path
()
p0
.
winding
=
winding
+
1
p0
.
winding
=
winding
+
1
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g)"
%
(
p0
.
id
,
c0
.
x
,
c0
.
y
)
print
"new path
%
d(
%
g,
%
g)"
%
(
p0
.
id
,
c0
[
0
],
c0
[
1
]
)
p0
.
append
(
c0
)
p0
.
append
(
c0
)
self
.
curr_path_list
.
append
(
p0
)
self
.
curr_path_list
.
append
(
p0
)
p1
=
Path
()
p1
=
Path
()
p1
.
winding
=
winding
p1
.
winding
=
winding
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g)"
%
(
p1
.
id
,
c1
.
x
,
c1
.
y
)
print
"new path
%
d(
%
g,
%
g)"
%
(
p1
.
id
,
c1
[
0
],
c1
[
1
]
)
p1
.
append
(
c1
)
p1
.
append
(
c1
)
self
.
curr_path_list
.
append
(
p1
)
self
.
curr_path_list
.
append
(
p1
)
p0
.
top_join
=
p1
p0
.
top_join
=
p1
...
@@ -538,16 +538,16 @@ class PolygonExtractor(object):
...
@@ -538,16 +538,16 @@ class PolygonExtractor(object):
c1
=
curr_point
.
peek
(
1
)
c1
=
curr_point
.
peek
(
1
)
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"overlap test: p0=
%
g p1=
%
g"
%
(
p0
.
x
,
p1
.
x
)
print
"overlap test: p0=
%
g p1=
%
g"
%
(
p0
[
0
],
p1
[
0
]
)
print
"overlap test: c0=
%
g c1=
%
g"
%
(
c0
.
x
,
c1
.
x
)
print
"overlap test: c0=
%
g c1=
%
g"
%
(
c0
[
0
],
c1
[
0
]
)
if
c1
.
y
<
p0
.
y
:
if
c1
[
1
]
<
p0
[
1
]
:
# new segment is completely to the left
# new segment is completely to the left
# new path starts
# new path starts
s0
=
Path
()
s0
=
Path
()
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
%
(
s0
.
id
,
c0
.
x
,
c0
.
y
,
winding
+
1
)
%
(
s0
.
id
,
c0
[
0
],
c0
[
1
]
,
winding
+
1
)
s0
.
append
(
c0
)
s0
.
append
(
c0
)
curr_path
.
insert
(
s0
)
curr_path
.
insert
(
s0
)
s1
=
Path
()
s1
=
Path
()
...
@@ -555,14 +555,14 @@ class PolygonExtractor(object):
...
@@ -555,14 +555,14 @@ class PolygonExtractor(object):
s1
.
winding
=
winding
s1
.
winding
=
winding
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
print
"new path
%
d(
%
g,
%
g) w=
%
d"
\
%
(
s1
.
id
,
c1
.
x
,
c1
.
y
,
winding
)
%
(
s1
.
id
,
c1
[
0
],
c1
[
1
]
,
winding
)
s1
.
append
(
c1
)
s1
.
append
(
c1
)
curr_path
.
insert
(
s1
)
curr_path
.
insert
(
s1
)
curr_point
.
next
()
curr_point
.
next
()
curr_point
.
next
()
curr_point
.
next
()
s0
.
top_join
=
s1
s0
.
top_join
=
s1
s1
.
top_join
=
s0
s1
.
top_join
=
s0
elif
c0
.
y
>
p1
.
y
:
elif
c0
[
1
]
>
p1
[
1
]
:
# new segment is completely to the right
# new segment is completely to the right
# old path ends
# old path ends
s0
=
curr_path
.
takeNext
()
s0
=
curr_path
.
takeNext
()
...
@@ -598,9 +598,9 @@ class PolygonExtractor(object):
...
@@ -598,9 +598,9 @@ class PolygonExtractor(object):
p2
=
prev_point
.
peek
(
1
)
p2
=
prev_point
.
peek
(
1
)
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"join test: p0=
%
g p1=
%
g p2=
%
g"
\
print
"join test: p0=
%
g p1=
%
g p2=
%
g"
\
%
(
p0
.
x
,
p1
.
x
,
p2
.
x
)
%
(
p0
[
0
],
p1
[
0
],
p2
[
0
]
)
print
"join test: c0=
%
g c1=
%
g"
%
(
c0
.
x
,
c1
.
x
)
print
"join test: c0=
%
g c1=
%
g"
%
(
c0
[
0
],
c1
[
0
]
)
if
p2
.
y
<=
c1
.
y
:
if
p2
[
1
]
<=
c1
[
1
]
:
overlap_p
=
True
overlap_p
=
True
if
self
.
policy
==
PolygonExtractor
.
CONTOUR
:
if
self
.
policy
==
PolygonExtractor
.
CONTOUR
:
s0
=
curr_path
.
takeNext
()
s0
=
curr_path
.
takeNext
()
...
@@ -640,10 +640,10 @@ class PolygonExtractor(object):
...
@@ -640,10 +640,10 @@ class PolygonExtractor(object):
if
curr_point
.
remains
()
>=
2
:
if
curr_point
.
remains
()
>=
2
:
c2
=
curr_point
.
peek
(
1
)
c2
=
curr_point
.
peek
(
1
)
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"split test: p0=
%
g p1=
%
g"
%
(
p0
.
x
,
p1
.
x
)
print
"split test: p0=
%
g p1=
%
g"
%
(
p0
[
0
],
p1
[
0
]
)
print
"split test: c0=
%
g c1=
%
g c2=
%
g"
\
print
"split test: c0=
%
g c1=
%
g c2=
%
g"
\
%
(
c0
.
x
,
c1
.
x
,
c2
.
x
)
%
(
c0
[
0
],
c1
[
0
],
c2
[
0
]
)
if
c2
.
y
<=
p1
.
y
:
if
c2
[
1
]
<=
p1
[
1
]
:
overlap_c
=
True
overlap_c
=
True
s0
=
Path
()
s0
=
Path
()
s1
=
Path
()
s1
=
Path
()
...
@@ -675,14 +675,14 @@ class PolygonExtractor(object):
...
@@ -675,14 +675,14 @@ class PolygonExtractor(object):
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"add to path
%
d(
%
g,
%
g)"
\
print
"add to path
%
d(
%
g,
%
g)"
\
%
(
left_path
.
id
,
left_point
.
x
,
left_point
.
y
)
%
(
left_path
.
id
,
left_point
[
0
],
left_point
[
1
]
)
left_path
.
append
(
left_point
)
left_path
.
append
(
left_point
)
right_path
.
append
(
right_point
)
right_path
.
append
(
right_point
)
if
right_path
==
curr_path
.
peek
():
if
right_path
==
curr_path
.
peek
():
curr_path
.
next
()
curr_path
.
next
()
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"add to path
%
d(
%
g,
%
g)"
\
print
"add to path
%
d(
%
g,
%
g)"
\
%
(
right_path
.
id
,
right_point
.
x
,
right_point
.
y
)
%
(
right_path
.
id
,
right_point
[
0
],
right_point
[
1
]
)
winding
=
right_path
.
winding
winding
=
right_path
.
winding
prev_point
.
next
()
prev_point
.
next
()
curr_point
.
next
()
curr_point
.
next
()
...
@@ -690,8 +690,8 @@ class PolygonExtractor(object):
...
@@ -690,8 +690,8 @@ class PolygonExtractor(object):
if
DEBUG_POLYGONEXTRACTOR
:
if
DEBUG_POLYGONEXTRACTOR
:
print
"active paths: "
,
print
"active paths: "
,
for
path
in
self
.
curr_path_list
:
for
path
in
self
.
curr_path_list
:
print
"
%
d(
%
g,
%
g,w=
%
d)"
%
(
path
.
id
,
path
.
points
[
-
1
]
.
x
,
print
"
%
d(
%
g,
%
g,w=
%
d)"
%
(
path
.
id
,
path
.
points
[
-
1
]
[
0
]
,
path
.
points
[
-
1
]
.
y
,
path
.
winding
),
path
.
points
[
-
1
]
[
1
]
,
path
.
winding
),
print
print
self
.
prev_line
=
scanline
self
.
prev_line
=
scanline
...
@@ -702,26 +702,26 @@ class PolygonExtractor(object):
...
@@ -702,26 +702,26 @@ class PolygonExtractor(object):
hor_path_list
=
[]
hor_path_list
=
[]
for
s
in
self
.
hor_path_list
:
for
s
in
self
.
hor_path_list
:
allsame
=
True
allsame
=
True
miny
=
s
.
points
[
0
]
.
y
miny
=
s
.
points
[
0
]
[
1
]
maxy
=
s
.
points
[
0
]
.
y
maxy
=
s
.
points
[
0
]
[
1
]
for
p
in
s
.
points
:
for
p
in
s
.
points
:
if
not
p
.
x
==
s
.
points
[
0
]
.
x
:
if
not
p
[
0
]
==
s
.
points
[
0
][
0
]
:
allsame
=
False
allsame
=
False
if
p
.
y
<
miny
:
if
p
[
1
]
<
miny
:
miny
=
p
.
y
miny
=
p
[
1
]
if
p
.
y
>
maxy
:
if
p
[
1
]
>
maxy
:
maxy
=
p
.
y
maxy
=
p
[
1
]
if
allsame
:
if
allsame
:
if
DEBUG_POLYGONEXTRACTOR2
:
if
DEBUG_POLYGONEXTRACTOR2
:
print
"all same !"
print
"all same !"
s0
=
Path
()
s0
=
Path
()
for
p
in
s
.
points
:
for
p
in
s
.
points
:
if
p
.
y
==
miny
:
if
p
[
1
]
==
miny
:
s0
.
append
(
p
)
s0
.
append
(
p
)
hor_path_list
.
append
(
s0
)
hor_path_list
.
append
(
s0
)
s1
=
Path
()
s1
=
Path
()
for
p
in
s
.
points
:
for
p
in
s
.
points
:
if
p
.
y
==
maxy
:
if
p
[
1
]
==
maxy
:
s1
.
append
(
p
)
s1
.
append
(
p
)
hor_path_list
.
append
(
s1
)
hor_path_list
.
append
(
s1
)
continue
continue
...
@@ -729,28 +729,28 @@ class PolygonExtractor(object):
...
@@ -729,28 +729,28 @@ class PolygonExtractor(object):
p_iter
=
CyclicIterator
(
s
.
points
)
p_iter
=
CyclicIterator
(
s
.
points
)
p
=
s
.
points
[
0
]
p
=
s
.
points
[
0
]
next_p
=
p_iter
.
next
()
next_p
=
p_iter
.
next
()
while
not
((
prev
.
x
>=
p
.
x
)
and
(
next_p
.
x
>
p
.
x
)):
while
not
((
prev
[
0
]
>=
p
[
0
])
and
(
next_p
[
0
]
>
p
[
0
]
)):
p
=
next_p
p
=
next_p
next_p
=
p_iter
.
next
()
next_p
=
p_iter
.
next
()
count
=
0
count
=
0
while
count
<
len
(
s
.
points
):
while
count
<
len
(
s
.
points
):
s0
=
Path
()
s0
=
Path
()
while
next_p
.
x
>=
p
.
x
:
while
next_p
[
0
]
>=
p
[
0
]
:
s0
.
append
(
p
)
s0
.
append
(
p
)
p
=
next_p
p
=
next_p
next_p
=
p_iter
.
next
()
next_p
=
p_iter
.
next
()
count
+=
1
count
+=
1
s0
.
append
(
p
)
s0
.
append
(
p
)
while
(
len
(
s0
.
points
)
>
1
)
\
while
(
len
(
s0
.
points
)
>
1
)
\
and
(
s0
.
points
[
0
]
.
x
==
s0
.
points
[
1
]
.
x
):
and
(
s0
.
points
[
0
]
[
0
]
==
s0
.
points
[
1
][
0
]
):
s0
.
points
=
s0
.
points
[
1
:]
s0
.
points
=
s0
.
points
[
1
:]
while
(
len
(
s0
.
points
)
>
1
)
\
while
(
len
(
s0
.
points
)
>
1
)
\
and
(
s0
.
points
[
-
2
]
.
x
==
s0
.
points
[
-
1
]
.
x
):
and
(
s0
.
points
[
-
2
]
[
0
]
==
s0
.
points
[
-
1
][
0
]
):
s0
.
points
=
s0
.
points
[
0
:
-
1
]
s0
.
points
=
s0
.
points
[
0
:
-
1
]
hor_path_list
.
append
(
s0
)
hor_path_list
.
append
(
s0
)
s1
=
Path
()
s1
=
Path
()
while
next_p
.
x
<=
p
.
x
:
while
next_p
[
0
]
<=
p
[
0
]
:
s1
.
append
(
p
)
s1
.
append
(
p
)
p
=
next_p
p
=
next_p
next_p
=
p_iter
.
next
()
next_p
=
p_iter
.
next
()
...
@@ -758,13 +758,13 @@ class PolygonExtractor(object):
...
@@ -758,13 +758,13 @@ class PolygonExtractor(object):
s1
.
append
(
p
)
s1
.
append
(
p
)
s1
.
reverse
()
s1
.
reverse
()
while
(
len
(
s1
.
points
)
>
1
)
\
while
(
len
(
s1
.
points
)
>
1
)
\
and
(
s1
.
points
[
0
]
.
x
==
s1
.
points
[
1
]
.
x
):
and
(
s1
.
points
[
0
]
[
0
]
==
s1
.
points
[
1
][
0
]
):
s1
.
points
=
s1
.
points
[
1
:]
s1
.
points
=
s1
.
points
[
1
:]
while
(
len
(
s1
.
points
)
>
1
)
\
while
(
len
(
s1
.
points
)
>
1
)
\
and
(
s1
.
points
[
-
2
]
.
x
==
s1
.
points
[
-
1
]
.
x
):
and
(
s1
.
points
[
-
2
]
[
0
]
==
s1
.
points
[
-
1
][
0
]
):
s1
.
points
=
s1
.
points
[:
-
1
]
s1
.
points
=
s1
.
points
[:
-
1
]
hor_path_list
.
append
(
s1
)
hor_path_list
.
append
(
s1
)
hor_path_list
.
sort
(
cmp
=
lambda
a
,
b
:
cmp
(
a
.
points
[
0
]
.
x
,
b
.
points
[
0
]
.
x
))
hor_path_list
.
sort
(
cmp
=
lambda
a
,
b
:
cmp
(
a
.
points
[
0
]
[
0
],
b
.
points
[
0
][
0
]
))
if
DEBUG_POLYGONEXTRACTOR2
:
if
DEBUG_POLYGONEXTRACTOR2
:
print
"ver_hor_path_list = "
,
hor_path_list
print
"ver_hor_path_list = "
,
hor_path_list
for
s
in
hor_path_list
:
for
s
in
hor_path_list
:
...
@@ -785,12 +785,12 @@ class PolygonExtractor(object):
...
@@ -785,12 +785,12 @@ class PolygonExtractor(object):
next_x
=
INFINITE
next_x
=
INFINITE
if
self
.
ver_hor_path_list
\
if
self
.
ver_hor_path_list
\
and
(
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
.
x
<
next_x
):
and
(
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
[
0
]
<
next_x
):
next_x
=
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
.
x
next_x
=
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
[
0
]
if
self
.
act_hor_path_list
\
if
self
.
act_hor_path_list
\
and
(
self
.
act_hor_path_list
[
0
]
.
points
[
0
]
.
x
<
next_x
):
and
(
self
.
act_hor_path_list
[
0
]
.
points
[
0
]
[
0
]
<
next_x
):
next_x
=
self
.
act_hor_path_list
[
0
]
.
points
[
0
]
.
x
next_x
=
self
.
act_hor_path_list
[
0
]
.
points
[
0
]
[
0
]
if
next_x
>=
_next_x
:
if
next_x
>=
_next_x
:
return
return
...
@@ -801,13 +801,13 @@ class PolygonExtractor(object):
...
@@ -801,13 +801,13 @@ class PolygonExtractor(object):
print
"next_x ="
,
next_x
print
"next_x ="
,
next_x
if
self
.
ver_hor_path_list
\
if
self
.
ver_hor_path_list
\
and
(
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
.
x
<=
next_x
):
and
(
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
[
0
]
<=
next_x
):
while
self
.
ver_hor_path_list
\
while
self
.
ver_hor_path_list
\
and
(
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
.
x
<=
next_x
):
and
(
self
.
ver_hor_path_list
[
0
]
.
points
[
0
]
[
0
]
<=
next_x
):
self
.
act_hor_path_list
.
append
(
self
.
ver_hor_path_list
[
0
])
self
.
act_hor_path_list
.
append
(
self
.
ver_hor_path_list
[
0
])
self
.
ver_hor_path_list
=
self
.
ver_hor_path_list
[
1
:]
self
.
ver_hor_path_list
=
self
.
ver_hor_path_list
[
1
:]
self
.
act_hor_path_list
.
sort
(
cmp
=
lambda
a
,
b
:
self
.
act_hor_path_list
.
sort
(
cmp
=
lambda
a
,
b
:
cmp
(
a
.
points
[
0
]
.
x
,
b
.
points
[
0
]
.
x
))
cmp
(
a
.
points
[
0
]
[
0
],
b
.
points
[
0
][
0
]
))
scanline
=
[]
scanline
=
[]
i
=
0
i
=
0
...
@@ -816,7 +816,7 @@ class PolygonExtractor(object):
...
@@ -816,7 +816,7 @@ class PolygonExtractor(object):
if
DEBUG_POLYGONEXTRACTOR2
:
if
DEBUG_POLYGONEXTRACTOR2
:
print
"s ="
,
s
print
"s ="
,
s
scanline
.
append
(
s
.
points
[
0
])
scanline
.
append
(
s
.
points
[
0
])
if
s
.
points
[
0
]
.
x
<=
next_x
:
if
s
.
points
[
0
]
[
0
]
<=
next_x
:
if
len
(
s
.
points
)
<=
1
:
if
len
(
s
.
points
)
<=
1
:
if
DEBUG_POLYGONEXTRACTOR2
:
if
DEBUG_POLYGONEXTRACTOR2
:
print
"remove list"
print
"remove list"
...
@@ -830,17 +830,17 @@ class PolygonExtractor(object):
...
@@ -830,17 +830,17 @@ class PolygonExtractor(object):
if
DEBUG_POLYGONEXTRACTOR2
:
if
DEBUG_POLYGONEXTRACTOR2
:
print
"remove point"
,
s
.
points
[
0
]
print
"remove point"
,
s
.
points
[
0
]
s
.
points
=
s
.
points
[
1
:]
s
.
points
=
s
.
points
[
1
:]
if
len
(
s
.
points
)
>
0
and
s
.
points
[
0
]
.
x
==
next_x
:
if
len
(
s
.
points
)
>
0
and
s
.
points
[
0
]
[
0
]
==
next_x
:
# TODO: the variable "repeat" is never used.
# TODO: the variable "repeat" is never used.
# Any idea?
# Any idea?
repeat
=
True
repeat
=
True
i
+=
1
i
+=
1
self
.
act_hor_path_list
.
sort
(
cmp
=
lambda
a
,
b
:
self
.
act_hor_path_list
.
sort
(
cmp
=
lambda
a
,
b
:
cmp
(
a
.
points
[
0
]
.
x
,
b
.
points
[
0
]
.
x
))
cmp
(
a
.
points
[
0
]
[
0
],
b
.
points
[
0
][
0
]
))
if
len
(
scanline
)
==
0
:
if
len
(
scanline
)
==
0
:
return
return
scanline
.
sort
(
cmp
=
lambda
a
,
b
:
cmp
(
a
.
y
,
b
.
y
))
scanline
.
sort
(
cmp
=
lambda
a
,
b
:
cmp
(
a
[
1
],
b
[
1
]
))
if
DEBUG_POLYGONEXTRACTOR2
:
if
DEBUG_POLYGONEXTRACTOR2
:
print
"scanline' ="
,
scanline
print
"scanline' ="
,
scanline
print
"ver_hor_path_list ="
,
self
.
ver_hor_path_list
print
"ver_hor_path_list ="
,
self
.
ver_hor_path_list
...
...
pycam/Geometry/Triangle.py
View file @
73cb1bb0
...
@@ -65,26 +65,18 @@ class Triangle(IDGenerator, TransformableContainer):
...
@@ -65,26 +65,18 @@ class Triangle(IDGenerator, TransformableContainer):
# calculate normal, if p1-p2-pe are in clockwise order
# calculate normal, if p1-p2-pe are in clockwise order
if
self
.
normal
is
None
:
if
self
.
normal
is
None
:
self
.
normal
=
pnormalized
(
pcross
(
psub
(
self
.
p3
,
self
.
p1
),
psub
(
self
.
p2
,
self
.
p1
)))
self
.
normal
=
pnormalized
(
pcross
(
psub
(
self
.
p3
,
self
.
p1
),
psub
(
self
.
p2
,
self
.
p1
)))
#self.normal = self.p3.sub(self.p1).cross(self.p2.sub( \
# self.p1)).normalized()
if
not
len
(
self
.
normal
)
>
3
:
if
not
len
(
self
.
normal
)
>
3
:
self
.
normal
=
(
self
.
normal
[
0
],
self
.
normal
[
1
],
self
.
normal
[
2
],
'v'
)
self
.
normal
=
(
self
.
normal
[
0
],
self
.
normal
[
1
],
self
.
normal
[
2
],
'v'
)
self
.
center
=
pdiv
(
padd
(
padd
(
self
.
p1
,
self
.
p2
),
self
.
p3
),
3
)
self
.
center
=
pdiv
(
padd
(
padd
(
self
.
p1
,
self
.
p2
),
self
.
p3
),
3
)
# self.center = self.p1.add(self.p2).add(self.p3).div(3)
self
.
plane
=
Plane
(
self
.
center
,
self
.
normal
)
self
.
plane
=
Plane
(
self
.
center
,
self
.
normal
)
# calculate circumcircle (resulting in radius and middle)
# calculate circumcircle (resulting in radius and middle)
denom
=
pnorm
(
pcross
(
psub
(
self
.
p2
,
self
.
p1
),
psub
(
self
.
p3
,
self
.
p2
)))
denom
=
pnorm
(
pcross
(
psub
(
self
.
p2
,
self
.
p1
),
psub
(
self
.
p3
,
self
.
p2
)))
#denom = self.p2.sub(self.p1).cross(self.p3.sub(self.p2)).norm
self
.
radius
=
(
pnorm
(
psub
(
self
.
p2
,
self
.
p1
))
*
pnorm
(
psub
(
self
.
p3
,
self
.
p2
))
*
pnorm
(
psub
(
self
.
p3
,
self
.
p1
)))
/
(
2
*
denom
)
self
.
radius
=
(
pnorm
(
psub
(
self
.
p2
,
self
.
p1
))
*
pnorm
(
psub
(
self
.
p3
,
self
.
p2
))
*
pnorm
(
psub
(
self
.
p3
,
self
.
p1
)))
/
(
2
*
denom
)
#self.radius = (self.p2.sub(self.p1).norm * self.p3.sub(self.p2).norm * self.p3.sub(self.p1).norm) / (2 * denom)
self
.
radiussq
=
self
.
radius
**
2
self
.
radiussq
=
self
.
radius
**
2
denom2
=
2
*
denom
*
denom
denom2
=
2
*
denom
*
denom
alpha
=
pnormsq
(
psub
(
self
.
p3
,
self
.
p2
))
*
pdot
(
psub
(
self
.
p1
,
self
.
p2
),
psub
(
self
.
p1
,
self
.
p3
))
/
denom2
alpha
=
pnormsq
(
psub
(
self
.
p3
,
self
.
p2
))
*
pdot
(
psub
(
self
.
p1
,
self
.
p2
),
psub
(
self
.
p1
,
self
.
p3
))
/
denom2
#alpha = self.p3.sub(self.p2).normsq * self.p1.sub(self.p2).dot(self.p1.sub(self.p3)) / denom2
beta
=
pnormsq
(
psub
(
self
.
p1
,
self
.
p3
))
*
pdot
(
psub
(
self
.
p2
,
self
.
p1
),
psub
(
self
.
p2
,
self
.
p3
))
/
denom2
beta
=
pnormsq
(
psub
(
self
.
p1
,
self
.
p3
))
*
pdot
(
psub
(
self
.
p2
,
self
.
p1
),
psub
(
self
.
p2
,
self
.
p3
))
/
denom2
#beta = self.p1.sub(self.p3).normsq * self.p2.sub(self.p1).dot(self.p2.sub(self.p3)) / denom2
gamma
=
pnormsq
(
psub
(
self
.
p1
,
self
.
p2
))
*
pdot
(
psub
(
self
.
p3
,
self
.
p1
),
psub
(
self
.
p3
,
self
.
p2
))
/
denom2
gamma
=
pnormsq
(
psub
(
self
.
p1
,
self
.
p2
))
*
pdot
(
psub
(
self
.
p3
,
self
.
p1
),
psub
(
self
.
p3
,
self
.
p2
))
/
denom2
#gamma = self.p1.sub(self.p2).normsq * self.p3.sub(self.p1).dot(self.p3.sub(self.p2)) / denom2
self
.
middle
=
(
self
.
p1
[
0
]
*
alpha
+
self
.
p2
[
0
]
*
beta
+
self
.
p3
[
0
]
*
gamma
,
self
.
middle
=
(
self
.
p1
[
0
]
*
alpha
+
self
.
p2
[
0
]
*
beta
+
self
.
p3
[
0
]
*
gamma
,
self
.
p1
[
1
]
*
alpha
+
self
.
p2
[
1
]
*
beta
+
self
.
p3
[
1
]
*
gamma
,
self
.
p1
[
1
]
*
alpha
+
self
.
p2
[
1
]
*
beta
+
self
.
p3
[
1
]
*
gamma
,
self
.
p1
[
2
]
*
alpha
+
self
.
p2
[
2
]
*
beta
+
self
.
p3
[
2
]
*
gamma
)
self
.
p1
[
2
]
*
alpha
+
self
.
p2
[
2
]
*
beta
+
self
.
p3
[
2
]
*
gamma
)
...
@@ -145,17 +137,12 @@ class Triangle(IDGenerator, TransformableContainer):
...
@@ -145,17 +137,12 @@ class Triangle(IDGenerator, TransformableContainer):
c
=
self
.
center
c
=
self
.
center
GL
.
glTranslate
(
c
[
0
],
c
[
1
],
c
[
2
])
GL
.
glTranslate
(
c
[
0
],
c
[
1
],
c
[
2
])
p12
=
pmul
(
padd
(
self
.
p1
,
self
.
p2
),
0.5
)
p12
=
pmul
(
padd
(
self
.
p1
,
self
.
p2
),
0.5
)
#p12 = self.p1.add(self.p2).mul(0.5)
p3_12
=
pnormalized
(
psub
(
self
.
p3
,
p12
))
p3_12
=
pnormalized
(
psub
(
self
.
p3
,
p12
))
#p3_12 = self.p3.sub(p12).normalized()
p2_1
=
pnormalized
(
psub
(
self
.
p1
,
self
.
p2
))
p2_1
=
pnormalized
(
psub
(
self
.
p1
,
self
.
p2
))
#p2_1 = self.p1.sub(self.p2).normalized()
pn
=
pcross
(
p2_1
,
p3_12
)
pn
=
pcross
(
p2_1
,
p3_12
)
#pn = p2_1.cross(p3_12)
GL
.
glMultMatrixf
((
p2_1
[
0
],
p2_1
[
1
],
p2_1
[
2
],
0
,
p3_12
[
0
],
p3_12
[
1
],
GL
.
glMultMatrixf
((
p2_1
[
0
],
p2_1
[
1
],
p2_1
[
2
],
0
,
p3_12
[
0
],
p3_12
[
1
],
p3_12
[
2
],
0
,
pn
[
0
],
pn
[
1
],
pn
[
2
],
0
,
0
,
0
,
0
,
1
))
p3_12
[
2
],
0
,
pn
[
0
],
pn
[
1
],
pn
[
2
],
0
,
0
,
0
,
0
,
1
))
n
=
pmul
(
self
.
normal
,
0.01
)
n
=
pmul
(
self
.
normal
,
0.01
)
#n = self.normal.mul(0.01)
GL
.
glTranslatef
(
n
[
0
],
n
[
1
],
n
[
2
])
GL
.
glTranslatef
(
n
[
0
],
n
[
1
],
n
[
2
])
maxdim
=
max
((
self
.
maxx
-
self
.
minx
),
(
self
.
maxy
-
self
.
miny
),
maxdim
=
max
((
self
.
maxx
-
self
.
minx
),
(
self
.
maxy
-
self
.
miny
),
(
self
.
maxz
-
self
.
minz
))
(
self
.
maxz
-
self
.
minz
))
...
@@ -172,19 +159,13 @@ class Triangle(IDGenerator, TransformableContainer):
...
@@ -172,19 +159,13 @@ class Triangle(IDGenerator, TransformableContainer):
if
False
:
# draw point id on triangle face
if
False
:
# draw point id on triangle face
c
=
self
.
center
c
=
self
.
center
p12
=
pmul
(
padd
(
self
.
p1
,
self
.
p2
),
0.5
)
p12
=
pmul
(
padd
(
self
.
p1
,
self
.
p2
),
0.5
)
#p12 = self.p1.add(self.p2).mul(0.5)
p3_12
=
pnormalized
(
psub
(
self
.
p3
,
p12
))
p3_12
=
pnormalized
(
psub
(
self
.
p3
,
p12
))
#p3_12 = self.p3.sub(p12).normalized()
p2_1
=
pnormalized
(
psub
(
self
.
p1
,
self
.
p2
))
p2_1
=
pnormalized
(
psub
(
self
.
p1
,
self
.
p2
))
#p2_1 = self.p1.sub(self.p2).normalized()
pn
=
pcross
(
p2_1
,
p3_12
)
pn
=
pcross
(
p2_1
,
p3_12
)
#pn = p2_1.cross(p3_12)
n
=
pmul
(
self
.
normal
,
0.01
)
n
=
pmul
(
self
.
normal
,
0.01
)
#n = self.normal.mul(0.01)
for
p
in
(
self
.
p1
,
self
.
p2
,
self
.
p3
):
for
p
in
(
self
.
p1
,
self
.
p2
,
self
.
p3
):
GL
.
glPushMatrix
()
GL
.
glPushMatrix
()
pp
=
psub
(
p
,
pmul
(
psub
(
p
,
c
),
0.3
))
pp
=
psub
(
p
,
pmul
(
psub
(
p
,
c
),
0.3
))
#pp = p.sub(p.sub(c).mul(0.3))
GL
.
glTranslate
(
pp
[
0
],
pp
[
1
],
pp
[
2
])
GL
.
glTranslate
(
pp
[
0
],
pp
[
1
],
pp
[
2
])
GL
.
glMultMatrixf
((
p2_1
[
0
],
p2_1
[
1
],
p2_1
[
2
],
0
,
p3_12
[
0
],
p3_12
[
1
],
GL
.
glMultMatrixf
((
p2_1
[
0
],
p2_1
[
1
],
p2_1
[
2
],
0
,
p3_12
[
0
],
p3_12
[
1
],
p3_12
[
2
],
0
,
pn
[
0
],
pn
[
1
],
pn
[
2
],
0
,
0
,
0
,
0
,
1
))
p3_12
[
2
],
0
,
pn
[
0
],
pn
[
1
],
pn
[
2
],
0
,
0
,
0
,
0
,
1
))
...
@@ -202,17 +183,14 @@ class Triangle(IDGenerator, TransformableContainer):
...
@@ -202,17 +183,14 @@ class Triangle(IDGenerator, TransformableContainer):
# http://www.blackpawn.com/texts/pointinpoly/default.html
# http://www.blackpawn.com/texts/pointinpoly/default.html
# Compute vectors
# Compute vectors
v0
=
psub
(
self
.
p3
,
self
.
p1
)
v0
=
psub
(
self
.
p3
,
self
.
p1
)
#v0 = self.p3.sub(self.p1)
v1
=
psub
(
self
.
p2
,
self
.
p1
)
v1
=
psub
(
self
.
p2
,
self
.
p1
)
#v1 = self.p2.sub(self.p1)
v2
=
psub
(
p
,
self
.
p1
)
v2
=
psub
(
p
,
self
.
p1
)
#v2 = p.sub(self.p1)
# Compute dot products
# Compute dot products
dot00
=
pdot
(
v0
,
v0
)
# dot00 = v0.dot(v0)
dot00
=
pdot
(
v0
,
v0
)
dot01
=
pdot
(
v0
,
v1
)
# dot01 = v0.dot(v1)
dot01
=
pdot
(
v0
,
v1
)
dot02
=
pdot
(
v0
,
v2
)
# dot02 = v0.dot(v2)
dot02
=
pdot
(
v0
,
v2
)
dot11
=
pdot
(
v1
,
v1
)
# dot11 = v1.dot(v1)
dot11
=
pdot
(
v1
,
v1
)
dot12
=
pdot
(
v1
,
v2
)
# dot12 = v1.dot(v2)
dot12
=
pdot
(
v1
,
v2
)
# Compute barycentric coordinates
# Compute barycentric coordinates
denom
=
dot00
*
dot11
-
dot01
*
dot01
denom
=
dot00
*
dot11
-
dot01
*
dot01
if
denom
==
0
:
if
denom
==
0
:
...
@@ -232,11 +210,8 @@ class Triangle(IDGenerator, TransformableContainer):
...
@@ -232,11 +210,8 @@ class Triangle(IDGenerator, TransformableContainer):
sub
.
append
(
self
)
sub
.
append
(
self
)
else
:
else
:
p4
=
pdiv
(
padd
(
self
.
p1
,
self
.
p2
),
2
)
p4
=
pdiv
(
padd
(
self
.
p1
,
self
.
p2
),
2
)
#p4 = self.p1.add(self.p2).div(2)
p5
=
pdiv
(
padd
(
self
.
p2
,
self
.
p3
),
2
)
p5
=
pdiv
(
padd
(
self
.
p2
,
self
.
p3
),
2
)
#p5 = self.p2.add(self.p3).div(2)
p6
=
pdiv
(
padd
(
self
.
p3
,
self
.
p1
),
2
)
p6
=
pdiv
(
padd
(
self
.
p3
,
self
.
p1
),
2
)
#p6 = self.p3.add(self.p1).div(2)
sub
+=
Triangle
(
self
.
p1
,
p4
,
p6
)
.
subdivide
(
depth
-
1
)
sub
+=
Triangle
(
self
.
p1
,
p4
,
p6
)
.
subdivide
(
depth
-
1
)
sub
+=
Triangle
(
p6
,
p5
,
self
.
p3
)
.
subdivide
(
depth
-
1
)
sub
+=
Triangle
(
p6
,
p5
,
self
.
p3
)
.
subdivide
(
depth
-
1
)
sub
+=
Triangle
(
p6
,
p4
,
p5
)
.
subdivide
(
depth
-
1
)
sub
+=
Triangle
(
p6
,
p4
,
p5
)
.
subdivide
(
depth
-
1
)
...
@@ -245,6 +220,5 @@ class Triangle(IDGenerator, TransformableContainer):
...
@@ -245,6 +220,5 @@ class Triangle(IDGenerator, TransformableContainer):
def
get_area
(
self
):
def
get_area
(
self
):
cross
=
pcross
(
psub
(
self
.
p2
,
self
.
p1
),
psub
(
self
.
p3
,
self
.
p1
))
cross
=
pcross
(
psub
(
self
.
p2
,
self
.
p1
),
psub
(
self
.
p3
,
self
.
p1
))
#cross = self.p2.sub(self.p1).cross(self.p3.sub(self.p1))
return
pnorm
(
cross
)
/
2
return
pnorm
(
cross
)
/
2
pycam/Geometry/__init__.py
View file @
73cb1bb0
...
@@ -38,23 +38,16 @@ def get_bisector(p1, p2, p3, up_vector):
...
@@ -38,23 +38,16 @@ def get_bisector(p1, p2, p3, up_vector):
of the angle.
of the angle.
"""
"""
d1
=
pnormalized
(
psub
(
p2
,
p1
))
d1
=
pnormalized
(
psub
(
p2
,
p1
))
#d1 = p2.sub(p1).normalized()
d2
=
pnormalized
(
psub
(
p2
,
p3
))
d2
=
pnormalized
(
psub
(
p2
,
p3
))
#d2 = p2.sub(p3).normalized()
bisector_dir
=
pnormalized
(
padd
(
d1
,
d2
))
bisector_dir
=
pnormalized
(
padd
(
d1
,
d2
))
#bisector_dir = d1.add(d2).normalized()
if
bisector_dir
is
None
:
if
bisector_dir
is
None
:
# the two vectors pointed to opposite directions
# the two vectors pointed to opposite directions
bisector_dir
=
pnormalized
(
pcross
(
d1
,
up_vector
))
bisector_dir
=
pnormalized
(
pcross
(
d1
,
up_vector
))
#bisector_dir = d1.cross(up_vector).normalized()
else
:
else
:
skel_up_vector
=
pcross
(
bisector_dir
,
psub
(
p2
,
p1
))
skel_up_vector
=
pcross
(
bisector_dir
,
psub
(
p2
,
p1
))
#skel_up_vector = bisector_dir.cross(p2.sub(p1))
#if up_vector.dot(skel_up_vector) < 0:
if
pdot
(
up_vector
,
skel_up_vector
)
<
0
:
if
pdot
(
up_vector
,
skel_up_vector
)
<
0
:
# reverse the skeleton vector to point outwards
# reverse the skeleton vector to point outwards
bisector_dir
=
pmul
(
bisector_dir
,
-
1
)
bisector_dir
=
pmul
(
bisector_dir
,
-
1
)
#bisector_dir = bisector_dir.mul(-1)
return
bisector_dir
return
bisector_dir
def
get_angle_pi
(
p1
,
p2
,
p3
,
up_vector
,
pi_factor
=
False
):
def
get_angle_pi
(
p1
,
p2
,
p3
,
up_vector
,
pi_factor
=
False
):
...
@@ -69,13 +62,10 @@ def get_angle_pi(p1, p2, p3, up_vector, pi_factor=False):
...
@@ -69,13 +62,10 @@ def get_angle_pi(p1, p2, p3, up_vector, pi_factor=False):
The result is in a range between 0 and 2*PI.
The result is in a range between 0 and 2*PI.
"""
"""
d1
=
pnormalized
(
psub
(
p2
,
p1
))
d1
=
pnormalized
(
psub
(
p2
,
p1
))
#d1 = p2.sub(p1).normalized()
d2
=
pnormalized
(
psub
(
p2
,
p3
))
d2
=
pnormalized
(
psub
(
p2
,
p3
))
#d2 = p2.sub(p3).normalized()
if
(
d1
is
None
)
or
(
d2
is
None
):
if
(
d1
is
None
)
or
(
d2
is
None
):
return
2
*
math
.
pi
return
2
*
math
.
pi
angle
=
math
.
acos
(
pdot
(
d1
,
d2
))
angle
=
math
.
acos
(
pdot
(
d1
,
d2
))
#angle = math.acos(d1.dot(d2))
# check the direction of the points (clockwise/anti)
# check the direction of the points (clockwise/anti)
# The code is taken from Polygon.get_area
# The code is taken from Polygon.get_area
value
=
[
0
,
0
,
0
]
value
=
[
0
,
0
,
0
]
...
@@ -145,7 +135,6 @@ def get_bezier_lines(points_with_bulge, segments=32):
...
@@ -145,7 +135,6 @@ def get_bezier_lines(points_with_bulge, segments=32):
# straight line
# straight line
return
[
Line
.
Line
(
p1
,
p2
)]
return
[
Line
.
Line
(
p1
,
p2
)]
straight_dir
=
pnormalized
(
psub
(
p2
,
p1
))
straight_dir
=
pnormalized
(
psub
(
p2
,
p1
))
#straight_dir = p2.sub(p1).normalized()
#bulge1 = max(-1.0, min(1.0, bulge1))
#bulge1 = max(-1.0, min(1.0, bulge1))
bulge1
=
math
.
atan
(
bulge1
)
bulge1
=
math
.
atan
(
bulge1
)
rot_matrix
=
Matrix
.
get_rotation_matrix_axis_angle
((
0
,
0
,
1
),
rot_matrix
=
Matrix
.
get_rotation_matrix_axis_angle
((
0
,
0
,
1
),
...
@@ -170,7 +159,6 @@ def get_bezier_lines(points_with_bulge, segments=32):
...
@@ -170,7 +159,6 @@ def get_bezier_lines(points_with_bulge, segments=32):
# and a bulge of 1 is a semicircle.
# and a bulge of 1 is a semicircle.
alpha
=
2
*
(
abs
(
bulge1
)
+
abs
(
bulge2
))
alpha
=
2
*
(
abs
(
bulge1
)
+
abs
(
bulge2
))
dist
=
pnorm
(
psub
(
p2
,
p1
))
dist
=
pnorm
(
psub
(
p2
,
p1
))
#dist = p2.sub(p1).norm
# calculate the radius of the circumcircle - avoiding divide-by-zero
# calculate the radius of the circumcircle - avoiding divide-by-zero
if
(
abs
(
alpha
)
<
epsilon
)
or
(
abs
(
math
.
pi
-
alpha
)
<
epsilon
):
if
(
abs
(
alpha
)
<
epsilon
)
or
(
abs
(
math
.
pi
-
alpha
)
<
epsilon
):
radius
=
dist
/
2.0
radius
=
dist
/
2.0
...
@@ -181,20 +169,11 @@ def get_bezier_lines(points_with_bulge, segments=32):
...
@@ -181,20 +169,11 @@ def get_bezier_lines(points_with_bulge, segments=32):
# seems to work well.
# seems to work well.
factor
=
4
*
radius
*
math
.
tan
(
alpha
/
4.0
)
factor
=
4
*
radius
*
math
.
tan
(
alpha
/
4.0
)
dir1
=
pmul
(
dir1
,
factor
)
dir1
=
pmul
(
dir1
,
factor
)
#dir1 = dir1.mul(factor)
dir2
=
pmul
(
dir2
,
factor
)
dir2
=
pmul
(
dir2
,
factor
)
#dir2 = dir2.mul(factor)
for
index
in
range
(
segments
+
1
):
for
index
in
range
(
segments
+
1
):
# t: 0..1
# t: 0..1
t
=
float
(
index
)
/
segments
t
=
float
(
index
)
/
segments
# see: http://en.wikipedia.org/wiki/Cubic_Hermite_spline
# see: http://en.wikipedia.org/wiki/Cubic_Hermite_spline
#p = p1.mul(2 * t ** 3 - 3 * t ** 2 + 1).add(
# dir1.mul(t ** 3 - 2 * t ** 2 + t).add(
# p2.mul(-2 * t ** 3 + 3 * t ** 2).add(
# dir2.mul(t ** 3 - t ** 2)
# )
# )
#)
p
=
padd
(
pmul
(
p1
,
2
*
t
**
3
-
3
*
t
**
2
+
1
)
,
padd
(
pmul
(
dir1
,
t
**
3
-
2
*
t
**
2
+
t
),
padd
(
pmul
(
p2
,
-
2
*
t
**
3
+
3
*
t
**
2
)
,
pmul
(
dir2
,
t
**
3
-
t
**
2
))))
p
=
padd
(
pmul
(
p1
,
2
*
t
**
3
-
3
*
t
**
2
+
1
)
,
padd
(
pmul
(
dir1
,
t
**
3
-
2
*
t
**
2
+
t
),
padd
(
pmul
(
p2
,
-
2
*
t
**
3
+
3
*
t
**
2
)
,
pmul
(
dir2
,
t
**
3
-
t
**
2
))))
result_points
.
append
(
p
)
result_points
.
append
(
p
)
# create lines
# create lines
...
...
pycam/Geometry/intersection.py
View file @
73cb1bb0
...
@@ -61,16 +61,13 @@ def intersect_lines(xl, zl, nxl, nzl, xm, zm, nxm, nzm):
...
@@ -61,16 +61,13 @@ def intersect_lines(xl, zl, nxl, nzl, xm, zm, nxm, nzm):
def
intersect_cylinder_point
(
center
,
axis
,
radius
,
radiussq
,
direction
,
point
):
def
intersect_cylinder_point
(
center
,
axis
,
radius
,
radiussq
,
direction
,
point
):
# take a plane along direction and axis
# take a plane along direction and axis
n
=
pnormalized
(
pcross
(
direction
,
axis
))
n
=
pnormalized
(
pcross
(
direction
,
axis
))
#n = direction.cross(axis).normalized()
# distance of the point to this plane
# distance of the point to this plane
d
=
pdot
(
n
,
point
)
-
pdot
(
n
,
center
)
d
=
pdot
(
n
,
point
)
-
pdot
(
n
,
center
)
#d = n.dot(point) - n.dot(center)
if
abs
(
d
)
>
radius
-
epsilon
:
if
abs
(
d
)
>
radius
-
epsilon
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
# ccl is on cylinder
# ccl is on cylinder
d2
=
sqrt
(
radiussq
-
d
*
d
)
d2
=
sqrt
(
radiussq
-
d
*
d
)
ccl
=
padd
(
padd
(
center
,
pmul
(
n
,
d
)),
pmul
(
direction
,
d2
))
ccl
=
padd
(
padd
(
center
,
pmul
(
n
,
d
)),
pmul
(
direction
,
d2
))
#ccl = center.add(n.mul(d)).add(direction.mul(d2))
# take plane through ccl and axis
# take plane through ccl and axis
plane
=
Plane
(
ccl
,
direction
)
plane
=
Plane
(
ccl
,
direction
)
# intersect point with plane
# intersect point with plane
...
@@ -81,7 +78,6 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
...
@@ -81,7 +78,6 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
d
=
edge
.
dir
d
=
edge
.
dir
# take a plane throught the line and along the cylinder axis (1)
# take a plane throught the line and along the cylinder axis (1)
n
=
pcross
(
d
,
axis
)
n
=
pcross
(
d
,
axis
)
#n = d.cross(axis)
if
pnorm
(
n
)
==
0
:
if
pnorm
(
n
)
==
0
:
# no contact point, but should check here if cylinder *always*
# no contact point, but should check here if cylinder *always*
# intersects line...
# intersects line...
...
@@ -90,22 +86,17 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
...
@@ -90,22 +86,17 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
# the contact line between the cylinder and this plane (1)
# the contact line between the cylinder and this plane (1)
# is where the surface normal is perpendicular to the plane
# is where the surface normal is perpendicular to the plane
# so line := ccl + \lambda * axis
# so line := ccl + \lambda * axis
#if n.dot(direction) < 0:
if
pdot
(
n
,
direction
)
<
0
:
if
pdot
(
n
,
direction
)
<
0
:
ccl
=
psub
(
center
,
pmul
(
n
,
radius
))
ccl
=
psub
(
center
,
pmul
(
n
,
radius
))
#ccl = center.sub(n.mul(radius))
else
:
else
:
ccl
=
padd
(
center
,
pmul
(
n
,
radius
))
ccl
=
padd
(
center
,
pmul
(
n
,
radius
))
#ccl = center.add(n.mul(radius))
# now extrude the contact line along the direction, this is a plane (2)
# now extrude the contact line along the direction, this is a plane (2)
n2
=
pcross
(
direction
,
axis
)
n2
=
pcross
(
direction
,
axis
)
#n2 = direction.cross(axis)
if
pnorm
(
n2
)
==
0
:
if
pnorm
(
n2
)
==
0
:
# no contact point, but should check here if cylinder *always*
# no contact point, but should check here if cylinder *always*
# intersects line...
# intersects line...
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
n2
=
pnormalized
(
n2
)
n2
=
pnormalized
(
n2
)
#n2 = n2.normalized()
plane1
=
Plane
(
ccl
,
n2
)
plane1
=
Plane
(
ccl
,
n2
)
# intersect this plane with the line, this gives us the contact point
# intersect this plane with the line, this gives us the contact point
(
cp
,
l
)
=
plane1
.
intersect_point
(
d
,
edge
.
p1
)
(
cp
,
l
)
=
plane1
.
intersect_point
(
d
,
edge
.
p1
)
...
@@ -118,7 +109,6 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
...
@@ -118,7 +109,6 @@ def intersect_cylinder_line(center, axis, radius, radiussq, direction, edge):
# gives us the cutter contact point
# gives us the cutter contact point
(
ccp
,
l
)
=
plane2
.
intersect_point
(
direction
,
cp
)
(
ccp
,
l
)
=
plane2
.
intersect_point
(
direction
,
cp
)
cp
=
padd
(
ccp
,
pmul
(
direction
,
-
l
))
cp
=
padd
(
ccp
,
pmul
(
direction
,
-
l
))
#cp = ccp.add(direction.mul(-l))
return
(
ccp
,
cp
,
-
l
)
return
(
ccp
,
cp
,
-
l
)
def
intersect_circle_plane
(
center
,
radius
,
direction
,
triangle
):
def
intersect_circle_plane
(
center
,
radius
,
direction
,
triangle
):
...
@@ -131,13 +121,10 @@ def intersect_circle_plane(center, radius, direction, triangle):
...
@@ -131,13 +121,10 @@ def intersect_circle_plane(center, radius, direction, triangle):
if
pnorm
(
n2
)
==
0
:
if
pnorm
(
n2
)
==
0
:
(
cp
,
d
)
=
triangle
.
plane
.
intersect_point
(
direction
,
center
)
(
cp
,
d
)
=
triangle
.
plane
.
intersect_point
(
direction
,
center
)
ccp
=
psub
(
cp
,
pmul
(
direction
,
d
))
ccp
=
psub
(
cp
,
pmul
(
direction
,
d
))
#ccp = cp.sub(direction.mul(d))
return
(
ccp
,
cp
,
d
)
return
(
ccp
,
cp
,
d
)
n2
=
pnormalized
(
n2
)
n2
=
pnormalized
(
n2
)
#n2 = n2.normalized()
# the cutter contact point is on the circle, where the surface normal is n
# the cutter contact point is on the circle, where the surface normal is n
ccp
=
padd
(
center
,
pmul
(
n2
,
-
radius
))
ccp
=
padd
(
center
,
pmul
(
n2
,
-
radius
))
#ccp = center.add(n2.mul(-radius))
# intersect the plane with a line through the contact point
# intersect the plane with a line through the contact point
(
cp
,
d
)
=
triangle
.
plane
.
intersect_point
(
direction
,
ccp
)
(
cp
,
d
)
=
triangle
.
plane
.
intersect_point
(
direction
,
ccp
)
return
(
ccp
,
cp
,
d
)
return
(
ccp
,
cp
,
d
)
...
@@ -148,7 +135,6 @@ def intersect_circle_point(center, axis, radius, radiussq, direction, point):
...
@@ -148,7 +135,6 @@ def intersect_circle_point(center, axis, radius, radiussq, direction, point):
# intersect with line gives ccp
# intersect with line gives ccp
(
ccp
,
l
)
=
plane
.
intersect_point
(
direction
,
point
)
(
ccp
,
l
)
=
plane
.
intersect_point
(
direction
,
point
)
# check if inside circle
# check if inside circle
#if ccp and (center.sub(ccp).normsq < radiussq - epsilon):
if
ccp
and
(
pnormsq
(
psub
(
center
,
ccp
))
<
radiussq
-
epsilon
):
if
ccp
and
(
pnormsq
(
psub
(
center
,
ccp
))
<
radiussq
-
epsilon
):
return
(
ccp
,
point
,
-
l
)
return
(
ccp
,
point
,
-
l
)
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
...
@@ -164,38 +150,30 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
...
@@ -164,38 +150,30 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
(
p2
,
l
)
=
plane
.
intersect_point
(
direction
,
edge
.
p2
)
(
p2
,
l
)
=
plane
.
intersect_point
(
direction
,
edge
.
p2
)
pc
=
Line
(
p1
,
p2
)
.
closest_point
(
center
)
pc
=
Line
(
p1
,
p2
)
.
closest_point
(
center
)
d_sq
=
pnormsq
(
psub
(
pc
,
center
))
d_sq
=
pnormsq
(
psub
(
pc
,
center
))
#d_sq = pc.sub(center).normsq
if
d_sq
>=
radiussq
:
if
d_sq
>=
radiussq
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
a
=
sqrt
(
radiussq
-
d_sq
)
a
=
sqrt
(
radiussq
-
d_sq
)
d1
=
pdot
(
psub
(
p1
,
pc
),
d
)
d1
=
pdot
(
psub
(
p1
,
pc
),
d
)
#d1 = p1.sub(pc).dot(d)
d2
=
pdot
(
psub
(
p2
,
pc
),
d
)
d2
=
pdot
(
psub
(
p2
,
pc
),
d
)
#d2 = p2.sub(pc).dot(d)
ccp
=
None
ccp
=
None
cp
=
None
cp
=
None
if
abs
(
d1
)
<
a
-
epsilon
:
if
abs
(
d1
)
<
a
-
epsilon
:
ccp
=
p1
ccp
=
p1
cp
=
psub
(
p1
,
pmul
(
direction
,
l
))
cp
=
psub
(
p1
,
pmul
(
direction
,
l
))
#cp = p1.sub(direction.mul(l))
elif
abs
(
d2
)
<
a
-
epsilon
:
elif
abs
(
d2
)
<
a
-
epsilon
:
ccp
=
p2
ccp
=
p2
cp
=
psub
(
p2
,
pmul
(
direction
,
l
))
cp
=
psub
(
p2
,
pmul
(
direction
,
l
))
#cp = p2.sub(direction.mul(l))
elif
((
d1
<
-
a
+
epsilon
)
and
(
d2
>
a
-
epsilon
))
\
elif
((
d1
<
-
a
+
epsilon
)
and
(
d2
>
a
-
epsilon
))
\
or
((
d2
<
-
a
+
epsilon
)
and
(
d1
>
a
-
epsilon
)):
or
((
d2
<
-
a
+
epsilon
)
and
(
d1
>
a
-
epsilon
)):
ccp
=
pc
ccp
=
pc
cp
=
psub
(
pc
,
pmul
(
direction
,
l
))
cp
=
psub
(
pc
,
pmul
(
direction
,
l
))
#cp = pc.sub(direction.mul(l))
return
(
ccp
,
cp
,
-
l
)
return
(
ccp
,
cp
,
-
l
)
n
=
pcross
(
d
,
direction
)
n
=
pcross
(
d
,
direction
)
#n = d.cross(direction)
if
pnorm
(
n
)
==
0
:
if
pnorm
(
n
)
==
0
:
# no contact point, but should check here if circle *always* intersects
# no contact point, but should check here if circle *always* intersects
# line...
# line...
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
n
=
pnormalized
(
n
)
n
=
pnormalized
(
n
)
#n = n.normalized()
# take a plane through the base
# take a plane through the base
plane
=
Plane
(
center
,
axis
)
plane
=
Plane
(
center
,
axis
)
# intersect base with line
# intersect base with line
...
@@ -204,21 +182,16 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
...
@@ -204,21 +182,16 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
# intersection of 2 planes: lp + \lambda v
# intersection of 2 planes: lp + \lambda v
v
=
pcross
(
axis
,
n
)
v
=
pcross
(
axis
,
n
)
#v = axis.cross(n)
if
pnorm
(
v
)
==
0
:
if
pnorm
(
v
)
==
0
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
v
=
pnormalized
(
v
)
v
=
pnormalized
(
v
)
#v = v.normalized()
# take plane through intersection line and parallel to axis
# take plane through intersection line and parallel to axis
n2
=
pcross
(
v
,
axis
)
n2
=
pcross
(
v
,
axis
)
#n2 = v.cross(axis)
if
pnorm
(
n2
)
==
0
:
if
pnorm
(
n2
)
==
0
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
n2
=
pnormalized
(
n2
)
n2
=
pnormalized
(
n2
)
#n2 = n2.normalized()
# distance from center to this plane
# distance from center to this plane
dist
=
pdot
(
n2
,
center
)
-
pdot
(
n2
,
lp
)
dist
=
pdot
(
n2
,
center
)
-
pdot
(
n2
,
lp
)
#dist = n2.dot(center) - n2.dot(lp)
distsq
=
dist
*
dist
distsq
=
dist
*
dist
if
distsq
>
radiussq
-
epsilon
:
if
distsq
>
radiussq
-
epsilon
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
...
@@ -227,9 +200,7 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
...
@@ -227,9 +200,7 @@ def intersect_circle_line(center, axis, radius, radiussq, direction, edge):
if
pdot
(
d
,
axis
)
<
0
:
if
pdot
(
d
,
axis
)
<
0
:
dist2
=
-
dist2
dist2
=
-
dist2
ccp
=
psub
(
center
,
psub
(
pmul
(
n2
,
dist
),
pmul
(
v
,
dist2
)))
ccp
=
psub
(
center
,
psub
(
pmul
(
n2
,
dist
),
pmul
(
v
,
dist2
)))
#ccp = center.sub(n2.mul(dist)).sub(v.mul(dist2))
plane
=
Plane
(
edge
.
p1
,
pcross
(
pcross
(
d
,
direction
),
d
))
plane
=
Plane
(
edge
.
p1
,
pcross
(
pcross
(
d
,
direction
),
d
))
#plane = Plane(edge.p1, d.cross(direction).cross(d))
(
cp
,
l
)
=
plane
.
intersect_point
(
direction
,
ccp
)
(
cp
,
l
)
=
plane
.
intersect_point
(
direction
,
ccp
)
return
(
ccp
,
cp
,
l
)
return
(
ccp
,
cp
,
l
)
...
@@ -241,10 +212,8 @@ def intersect_sphere_plane(center, radius, direction, triangle):
...
@@ -241,10 +212,8 @@ def intersect_sphere_plane(center, radius, direction, triangle):
# the cutter contact point is on the sphere, where the surface normal is n
# the cutter contact point is on the sphere, where the surface normal is n
if
pdot
(
n
,
direction
)
<
0
:
if
pdot
(
n
,
direction
)
<
0
:
ccp
=
psub
(
center
,
pmul
(
n
,
radius
))
ccp
=
psub
(
center
,
pmul
(
n
,
radius
))
#ccp = center.sub(n.mul(radius))
else
:
else
:
ccp
=
padd
(
center
,
pmul
(
n
,
radius
))
ccp
=
padd
(
center
,
pmul
(
n
,
radius
))
#ccp = center.add(n.mul(radius))
# intersect the plane with a line through the contact point
# intersect the plane with a line through the contact point
(
cp
,
d
)
=
triangle
.
plane
.
intersect_point
(
direction
,
ccp
)
(
cp
,
d
)
=
triangle
.
plane
.
intersect_point
(
direction
,
ccp
)
return
(
ccp
,
cp
,
d
)
return
(
ccp
,
cp
,
d
)
...
@@ -256,9 +225,7 @@ def intersect_sphere_point(center, radius, radiussq, direction, point):
...
@@ -256,9 +225,7 @@ def intersect_sphere_point(center, radius, radiussq, direction, point):
# (2) (x-x_0)^2 = R^2
# (2) (x-x_0)^2 = R^2
# (1) in (2) gives a quadratic in \lambda
# (1) in (2) gives a quadratic in \lambda
p0_x0
=
psub
(
center
,
point
)
p0_x0
=
psub
(
center
,
point
)
#p0_x0 = center.sub(point)
a
=
pnormsq
(
direction
)
a
=
pnormsq
(
direction
)
#a = direction.normsq
b
=
2
*
pdot
(
p0_x0
,
direction
)
b
=
2
*
pdot
(
p0_x0
,
direction
)
c
=
pnormsq
(
p0_x0
)
-
radiussq
c
=
pnormsq
(
p0_x0
)
-
radiussq
d
=
b
*
b
-
4
*
a
*
c
d
=
b
*
b
-
4
*
a
*
c
...
@@ -270,24 +237,20 @@ def intersect_sphere_point(center, radius, radiussq, direction, point):
...
@@ -270,24 +237,20 @@ def intersect_sphere_point(center, radius, radiussq, direction, point):
l
=
(
-
b
-
sqrt
(
d
))
/
(
2
*
a
)
l
=
(
-
b
-
sqrt
(
d
))
/
(
2
*
a
)
# cutter contact point
# cutter contact point
ccp
=
padd
(
point
,
pmul
(
direction
,
-
l
))
ccp
=
padd
(
point
,
pmul
(
direction
,
-
l
))
#ccp = point.add(direction.mul(-l))
return
(
ccp
,
point
,
l
)
return
(
ccp
,
point
,
l
)
def
intersect_sphere_line
(
center
,
radius
,
radiussq
,
direction
,
edge
):
def
intersect_sphere_line
(
center
,
radius
,
radiussq
,
direction
,
edge
):
# make a plane by sliding the line along the direction (1)
# make a plane by sliding the line along the direction (1)
d
=
edge
.
dir
d
=
edge
.
dir
n
=
pcross
(
n
,
direction
)
n
=
pcross
(
n
,
direction
)
#n = d.cross(direction)
if
pnorm
(
n
)
==
0
:
if
pnorm
(
n
)
==
0
:
# no contact point, but should check here if sphere *always* intersects
# no contact point, but should check here if sphere *always* intersects
# line...
# line...
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
n
=
pnormalized
(
n
)
n
=
pnormalized
(
n
)
#n = n.normalized()
# calculate the distance from the sphere center to the plane
# calculate the distance from the sphere center to the plane
dist
=
-
pdot
(
center
,
n
)
+
pdot
(
edge
.
p1
,
n
)
dist
=
-
pdot
(
center
,
n
)
+
pdot
(
edge
.
p1
,
n
)
#dist = - center.dot(n) + edge.p1.dot(n)
if
abs
(
dist
)
>
radius
-
epsilon
:
if
abs
(
dist
)
>
radius
-
epsilon
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
# this gives us the intersection circle on the sphere
# this gives us the intersection circle on the sphere
...
@@ -297,14 +260,12 @@ def intersect_sphere_line(center, radius, radiussq, direction, edge):
...
@@ -297,14 +260,12 @@ def intersect_sphere_line(center, radius, radiussq, direction, edge):
# which means the other component is perpendicular to this plane (2)
# which means the other component is perpendicular to this plane (2)
n2
=
pnormalized
(
pcross
(
n
,
d
))
n2
=
pnormalized
(
pcross
(
n
,
d
))
#n2 = n.cross(d).normalized()
# the contact point is on a big circle through the sphere...
# the contact point is on a big circle through the sphere...
dist2
=
sqrt
(
radiussq
-
dist
*
dist
)
dist2
=
sqrt
(
radiussq
-
dist
*
dist
)
# ... and it's on the plane (1)
# ... and it's on the plane (1)
ccp
=
padd
(
center
,
padd
(
pmul
(
n
,
dist
),
pmul
(
n2
,
dist2
)))
ccp
=
padd
(
center
,
padd
(
pmul
(
n
,
dist
),
pmul
(
n2
,
dist2
)))
#ccp = center.add(n.mul(dist)).add(n2.mul(dist2))
# now intersect a line through this point with the plane (2)
# now intersect a line through this point with the plane (2)
plane
=
Plane
(
edge
.
p1
,
n2
)
plane
=
Plane
(
edge
.
p1
,
n2
)
...
@@ -321,17 +282,13 @@ def intersect_torus_plane(center, axis, majorradius, minorradius, direction,
...
@@ -321,17 +282,13 @@ def intersect_torus_plane(center, axis, majorradius, minorradius, direction,
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
# find place on torus where surface normal is n
# find place on torus where surface normal is n
b
=
pmul
(
n
,
-
1
)
b
=
pmul
(
n
,
-
1
)
#b = n.mul(-1)
z
=
axis
z
=
axis
a
=
psub
(
b
,
pmul
(
z
,
pdot
(
z
,
b
)))
a
=
psub
(
b
,
pmul
(
z
,
pdot
(
z
,
b
)))
#a = b.sub(z.mul(z.dot(b)))
a_sq
=
pnormsq
(
a
)
a_sq
=
pnormsq
(
a
)
if
a_sq
<=
0
:
if
a_sq
<=
0
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
a
=
pdiv
(
a
,
sqrt
(
a_sq
))
a
=
pdiv
(
a
,
sqrt
(
a_sq
))
#a = a.div(sqrt(a_sq))
ccp
=
padd
(
padd
(
center
,
pmul
(
a
,
majorradius
)),
pmul
(
b
,
minorradius
))
ccp
=
padd
(
padd
(
center
,
pmul
(
a
,
majorradius
)),
pmul
(
b
,
minorradius
))
#ccp = center.add(a.mul(majorradius)).add(b.mul(minorradius))
# find intersection with plane
# find intersection with plane
(
cp
,
l
)
=
triangle
.
plane
.
intersect_point
(
direction
,
ccp
)
(
cp
,
l
)
=
triangle
.
plane
.
intersect_point
(
direction
,
ccp
)
return
(
ccp
,
cp
,
l
)
return
(
ccp
,
cp
,
l
)
...
@@ -360,38 +317,24 @@ def intersect_torus_point(center, axis, majorradius, minorradius, majorradiussq,
...
@@ -360,38 +317,24 @@ def intersect_torus_point(center, axis, majorradius, minorradius, majorradiussq,
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
l
=
majorradius
+
sqrt
(
minorradiussq
-
z
*
z
)
l
=
majorradius
+
sqrt
(
minorradiussq
-
z
*
z
)
n
=
pcross
(
axis
,
direction
)
n
=
pcross
(
axis
,
direction
)
#n = axis.cross(direction)
d
=
pdot
(
n
,
point
)
-
pdot
(
n
,
center
)
d
=
pdot
(
n
,
point
)
-
pdot
(
n
,
center
)
#d = n.dot(point) - n.dot(center)
if
abs
(
d
)
>
l
-
epsilon
:
if
abs
(
d
)
>
l
-
epsilon
:
return
(
None
,
None
,
INFINITE
)
return
(
None
,
None
,
INFINITE
)
a
=
sqrt
(
l
*
l
-
d
*
d
)
a
=
sqrt
(
l
*
l
-
d
*
d
)
ccp
=
padd
(
padd
(
center
,
pmul
(
n
,
d
)),
pmul
(
direction
,
a
))
ccp
=
padd
(
padd
(
center
,
pmul
(
n
,
d
)),
pmul
(
direction
,
a
))
#ccp = center.add(n.mul(d).add(direction.mul(a)))
ccp
=
(
ccp
[
0
],
ccp
[
1
],
point
[
2
])
ccp
=
(
ccp
[
0
],
ccp
[
1
],
point
[
2
])
#ccp.z = point.z
dist
=
pdot
(
psub
(
point
,
ccp
),
direction
)
dist
=
pdot
(
psub
(
point
,
ccp
),
direction
)
#dist = point.sub(ccp).dot(direction)
else
:
else
:
# general case
# general case
x
=
psub
(
point
,
center
)
x
=
psub
(
point
,
center
)
#x = point.sub(center)
v
=
pmul
(
direction
,
-
1
)
v
=
pmul
(
direction
,
-
1
)
#v = direction.mul(-1)
x_x
=
pdot
(
x
,
x
)
x_x
=
pdot
(
x
,
x
)
#x_x = x.dot(x)
x_v
=
pdot
(
x
,
v
)
x_v
=
pdot
(
x
,
v
)
#x_v = x.dot(v)
x1
=
(
x
[
0
],
x
[
1
],
0
)
x1
=
(
x
[
0
],
x
[
1
],
0
)
#x1 = Point(x.x, x.y, 0)
v1
=
(
v
[
0
],
v
[
1
],
0
)
v1
=
(
v
[
0
],
v
[
1
],
0
)
#v1 = Point(v.x, v.y, 0)
x1_x1
=
pdot
(
x1
,
x1
)
x1_x1
=
pdot
(
x1
,
x1
)
#x1_x1 = x1.dot(x1)
x1_v1
=
pdot
(
x1
,
v1
)
x1_v1
=
pdot
(
x1
,
v1
)
#x1_v1 = x1.dot(v1)
v1_v1
=
pdot
(
v1
,
v1
)
v1_v1
=
pdot
(
v1
,
v1
)
#v1_v1 = v1.dot(v1)
R2
=
majorradiussq
R2
=
majorradiussq
r2
=
minorradiussq
r2
=
minorradiussq
a
=
1.0
a
=
1.0
...
@@ -405,7 +348,6 @@ def intersect_torus_point(center, axis, majorradius, minorradius, majorradiussq,
...
@@ -405,7 +348,6 @@ def intersect_torus_point(center, axis, majorradius, minorradius, majorradiussq,
else
:
else
:
l
=
min
(
r
)
l
=
min
(
r
)
ccp
=
padd
(
point
,
pmul
(
direction
,
-
l
))
ccp
=
padd
(
point
,
pmul
(
direction
,
-
l
))
#ccp = point.add(direction.mul(-l))
dist
=
l
dist
=
l
return
(
ccp
,
point
,
dist
)
return
(
ccp
,
point
,
dist
)
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