mirror of
https://github.com/skishore/makemeahanzi.git
synced 2025-11-03 22:18:19 +08:00
Add cusp merging logic
This commit is contained in:
39
getchar.py
39
getchar.py
@ -13,8 +13,9 @@ SVG_DIR = 'derived'
|
|||||||
TRANSFORM = 'scale({0:.2g}, -{0:0.2g}) translate(0, -900)'.format(SCALE)
|
TRANSFORM = 'scale({0:.2g}, -{0:0.2g}) translate(0, -900)'.format(SCALE)
|
||||||
|
|
||||||
# Constants controlling our stroke extraction algorithm.
|
# Constants controlling our stroke extraction algorithm.
|
||||||
MIN_CROSSING_ANGLE = 0.1*math.pi
|
|
||||||
MAX_CROSSING_DISTANCE = 64
|
MAX_CROSSING_DISTANCE = 64
|
||||||
|
MAX_CUSP_MERGE_DISTANCE = 15
|
||||||
|
MIN_CUSP_ANGLE = 0.1*math.pi
|
||||||
|
|
||||||
|
|
||||||
class Cusp(object):
|
class Cusp(object):
|
||||||
@ -27,12 +28,36 @@ class Cusp(object):
|
|||||||
self.angle = self._get_angle(self.tangent1, self.tangent2)
|
self.angle = self._get_angle(self.tangent1, self.tangent2)
|
||||||
|
|
||||||
def connect(self, other):
|
def connect(self, other):
|
||||||
|
# Returns true if a troke continues from this cusp point to the other.
|
||||||
if other.index == self.index:
|
if other.index == self.index:
|
||||||
return False
|
return False
|
||||||
if other.index[0] == self.index[0]:
|
if other.index[0] == self.index[0]:
|
||||||
return self._try_connect(other)
|
return self._try_connect(other)
|
||||||
return self._try_connect(other) or self._try_connect(other, True)
|
return self._try_connect(other) or self._try_connect(other, True)
|
||||||
|
|
||||||
|
def merge(self, other):
|
||||||
|
# Returns true if this cusp point is close enough to the next one that
|
||||||
|
# they should be combined into one cusp point. If this method returns
|
||||||
|
# true, other will be populated with the merged cusp data.
|
||||||
|
assert other.index[0] == self.index[0], 'merge called for different paths!'
|
||||||
|
if abs(other.point - self.point) > MAX_CUSP_MERGE_DISTANCE:
|
||||||
|
return False
|
||||||
|
distance = 0
|
||||||
|
j = self.index[1]
|
||||||
|
path = self.paths[self.index[0]]
|
||||||
|
while j != other.index[1]:
|
||||||
|
j = (j + 1) % len(path)
|
||||||
|
distance += abs(path[j].end - path[j].start)
|
||||||
|
if distance > MAX_CUSP_MERGE_DISTANCE:
|
||||||
|
return False
|
||||||
|
# We should merge. Check which point is the real cusp and update other.
|
||||||
|
if abs(self.angle) > abs(other.angle):
|
||||||
|
other.index = self.index
|
||||||
|
other.point = self.point
|
||||||
|
other.tangent1 = self.tangent1
|
||||||
|
other.angle = other._get_angle(other.tangent1, other.tangent2)
|
||||||
|
return True
|
||||||
|
|
||||||
def _get_angle(self, vector1, vector2):
|
def _get_angle(self, vector1, vector2):
|
||||||
if not vector1 or not vector2:
|
if not vector1 or not vector2:
|
||||||
return 0
|
return 0
|
||||||
@ -113,10 +138,18 @@ def break_path(path):
|
|||||||
def get_cusps(paths):
|
def get_cusps(paths):
|
||||||
result = []
|
result = []
|
||||||
for i, path in enumerate(paths):
|
for i, path in enumerate(paths):
|
||||||
|
cusps = []
|
||||||
for j, element in enumerate(path):
|
for j, element in enumerate(path):
|
||||||
cusp = Cusp(paths, (i, j))
|
cusp = Cusp(paths, (i, j))
|
||||||
if abs(cusp.angle) > MIN_CROSSING_ANGLE:
|
if abs(cusp.angle) > MIN_CUSP_ANGLE:
|
||||||
result.append(cusp)
|
cusps.append(cusp)
|
||||||
|
j = 0
|
||||||
|
while j < len(cusps):
|
||||||
|
if cusps[j].merge(cusps[(j + 1) % len(cusps)]):
|
||||||
|
cusps.pop(j)
|
||||||
|
else:
|
||||||
|
j += 1
|
||||||
|
result.extend(cusps)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_svg_path_data(glyph):
|
def get_svg_path_data(glyph):
|
||||||
|
|||||||
Reference in New Issue
Block a user