Commit 73cb1bb0 authored by Whitham D. Reeve II's avatar Whitham D. Reeve II

Removed old commented out code and converted PolygonExtractor.py to new Point tuple style.

parent d45b6dcb
...@@ -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)
......
...@@ -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
......
...@@ -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],
......
...@@ -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)
......
...@@ -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)
......
...@@ -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)
......
...@@ -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
......
...@@ -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
...@@ -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
......
...@@ -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)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment