Skip to content

Commit

Permalink
Calculate selection segments
Browse files Browse the repository at this point in the history
Split encroached edges at point on selection segment with worst discretisation error
Vertex-Number multiplication is now commutative
  • Loading branch information
jdugge committed Mar 24, 2016
1 parent bf7468a commit 61d8c5b
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 7 deletions.
35 changes: 35 additions & 0 deletions quadedge.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,35 @@ def is_boundary(self):
def as_line_segment(self):
return [self.origin.pos, self.destination.pos]

def selection_segment(self, v):
"""
When the edge is encroached by a vertex v, there is a segment of the
edge along which the edge can be split to solve the encroachment, the
"selection segment".
:param v: Encroaching vertex
:return: The start and end vertices of the selection segment
"""
a = self.origin
b = self.destination

# Find the start of the selection segment
av = v - a
ab = b - a

p = min(av.norm**2/(av * ab), 1)
p = p if p >= 0 else 1
s0 = a + p * ab

# Find the end of the selection segment
bv = v - b
ba = a - b

q = bv.norm**2/(bv * ba)
q = q if q >= 0 else 1
s1 = b + q * ba

return s0, s1

def __lt__(self, other):
self.length < other.length

Expand Down Expand Up @@ -234,6 +263,12 @@ def __mul__(self, other):
else:
return NotImplemented

def __rmul__(self, other):
if isinstance(other, Number):
return Vertex(self.x * other, self.y * other, self.z * other)
else:
return NotImplemented

def __truediv__(self, other):
if isinstance(other, Number):
return Vertex(self.x / other, self.y / other, self.z / other)
Expand Down
68 changes: 61 additions & 7 deletions triangulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,37 @@ def scan_triangle_line(self, t, y, x_a, x_b, interpolation_map=None):
t.candidate_error = error
t.candidate.pos = (x, y, z_map)

def scan_segment(self, e, s0, s1):
"""
Find the point along the selection segment of an edge that has the worst
discretisation error
:param e: edge containing the segment
:param s0: starting vertex of selection segment
:param s1: ending vertex of selection segment
:return: vertex at the 2D position with the worst discretisation error
"""

a = s1 - s0
d = ceil(a.norm)

step = 1 / d

max_error = 0
worst_vertex = None

for i in range(d):
v = s0 + i * step * a
x = round(v.x)
y = round(v.y)

z_map = self.Hmap[y, x]
interpolation = e.triangle.interpolate(x, y)
error = abs(interpolation - z_map)
if error > max_error:
max_error = error
worst_vertex = Vertex(x, y)
return worst_vertex

def insert_point(self, v, e=None):
"""
Insert a new vertex into the triangulation and scan the newly created
Expand Down Expand Up @@ -429,28 +460,51 @@ def split_edge(self, e):
e = e.sym
self.insert_point(new_v, e)

def split_all_encroached_edges(self):
def worst_encroached_edge(self):
"""
For all boundary edges, check if they are encroached. Split the longest
encroached boundary edge and repeat until no more boundary edges are
encroached
:return: The longest encroached edge and the encroaching vertex
"""
while True:
max_length = 0
worst_edge = None
encroaching_vertex = None
for e in self.undirected_edges:
encroaching_vertex_candidate = None
if e.is_boundary or e.sym.is_boundary:
if e.o_next.destination.encroaches(e) or \
e.o_prev.destination.encroaches(e):
p = e.o_next.destination
q = e.o_prev.destination
if p.encroaches(e):
encroaching_vertex_candidate = p
elif q.encroaches(e):
encroaching_vertex_candidate = q

if encroaching_vertex_candidate is not None:
if e.length > max_length:
max_length = e.length
worst_edge = e
encroaching_vertex = encroaching_vertex_candidate

if worst_edge is None:
logging.debug("No more encroached edges")
return None, None
else:
return worst_edge, encroaching_vertex

def split_all_encroached_edges(self):
"""
For all boundary edges, check if they are encroached. Split the longest
encroached boundary edge and repeat until no more boundary edges are
encroached
"""
while True:
worst_edge, v = self.worst_encroached_edge()
if worst_edge is None:
break
else:
logging.debug("Splitting edge {}".format(worst_edge))
self.split_edge(worst_edge)
s0, s1 = worst_edge.selection_segment(v)
split = self.scan_segment(worst_edge, s0, s1)
self.insert_point(split)

def interpolated_map(self):
"""
Expand Down

0 comments on commit 61d8c5b

Please sign in to comment.