Revert "[interpolatableTestStartingPoint] Try to rationalize the extended case"

This reverts commit b950447e491ddf1e1a739d06711755db01ad5e4e.
This commit is contained in:
Behdad Esfahbod 2023-12-05 15:10:19 -07:00
parent 90a84d25ca
commit d88292b742
2 changed files with 68 additions and 33 deletions

View File

@ -42,9 +42,7 @@ class Glyph:
"controlVectors",
"nodeTypes",
"isomorphisms",
"isomorphismsNormalized",
"points",
"pointsNormalized",
"openContours",
)
@ -95,12 +93,12 @@ class Glyph:
# Save a "normalized" version of the outlines
try:
rpen = DecomposingRecordingPen(glyphset)
transform = transform_from_stats(greenStats, inverse=True)
tpen = TransformPen(rpen, transform)
tpen = TransformPen(
rpen, transform_from_stats(greenStats, inverse=True)
)
contour.replay(tpen)
self.recordingsNormalized.append(rpen)
except ZeroDivisionError:
transform = Transform()
self.recordingsNormalized.append(None)
greenStats = StatisticsPen(glyphset=glyphset)
@ -114,7 +112,6 @@ class Glyph:
assert nodeTypes[0] == "moveTo"
assert nodeTypes[-1] in ("closePath", "endPath")
points = SimpleRecordingPointPen()
converter = SegmentToPointPen(points, False)
contour.replay(converter)
@ -123,26 +120,14 @@ class Glyph:
# possible starting points.
self.points.append(points.value)
pointsNormalized = SimpleRecordingPointPen()
converter = SegmentToPointPen(pointsNormalized, False)
converter = TransformPen(converter, transform)
contour.replay(converter)
self.pointsNormalized.append(pointsNormalized.value)
isomorphisms = []
self.isomorphisms.append(isomorphisms)
# Add rotations
add_isomorphisms(points.value, isomorphisms, False)
# Add mirrored rotations
add_isomorphisms(points.value, isomorphisms, True)
isomorphisms = []
self.isomorphismsNormalized.append(isomorphisms)
# Add rotations
add_isomorphisms(pointsNormalized.value, isomorphisms, False)
# Add mirrored rotations
add_isomorphisms(pointsNormalized.value, isomorphisms, True)
def draw(self, pen, countor_idx=None):
if countor_idx is None:
for contour in self.recordings:

View File

@ -9,6 +9,10 @@ def test_starting_point(glyph0, glyph1, ix, tolerance, matching):
m0Vectors = glyph0.greenVectors
m1Vectors = [glyph1.greenVectors[i] for i in matching]
proposed_point = 0
reverse = False
min_cost = first_cost = 1
c0 = contour0[0]
# Next few lines duplicated below.
costs = [vdiff_hypot2_complex(c0[0], c1[0]) for c1 in contour1]
@ -17,7 +21,6 @@ def test_starting_point(glyph0, glyph1, ix, tolerance, matching):
proposed_point = contour1[min_cost_idx][1]
reverse = contour1[min_cost_idx][2]
this_tolerance = min_cost / first_cost if first_cost else 1
if min_cost < first_cost * tolerance:
# c0 is the first isomorphism of the m0 master
@ -37,22 +40,69 @@ def test_starting_point(glyph0, glyph1, ix, tolerance, matching):
# pass.
num_points = len(glyph1.points[ix])
leeway = num_points // 4
if proposed_point <= leeway or proposed_point >= num_points - leeway:
leeway = 3
if not reverse and (
proposed_point <= leeway or proposed_point >= num_points - leeway
):
# Try harder
contour0 = glyph0.isomorphismsNormalized[ix]
contour1 = glyph1.isomorphismsNormalized[matching[ix]]
c0 = contour0[0]
costs = [vdiff_hypot2_complex(c0[0], c1[0]) for c1 in contour1]
new_min_cost_idx, new_min_cost = min(enumerate(costs), key=lambda x: x[1])
new_first_cost = costs[0]
new_this_tolerance = new_min_cost / new_first_cost if new_first_cost else 1
if new_this_tolerance > this_tolerance:
proposed_point = contour1[new_min_cost_idx][1]
reverse = contour1[new_min_cost_idx][2]
this_tolerance = new_this_tolerance
# Recover the covariance matrix from the GreenVectors.
# This is a 2x2 matrix.
transforms = []
for vector in (m0Vectors[ix], m1Vectors[ix]):
meanX = vector[1]
meanY = vector[2]
stddevX = vector[3] * 0.5
stddevY = vector[4] * 0.5
correlation = vector[5] / abs(vector[0])
# https://cookierobotics.com/007/
a = stddevX * stddevX # VarianceX
c = stddevY * stddevY # VarianceY
b = correlation * stddevX * stddevY # Covariance
delta = (((a - c) * 0.5) ** 2 + b * b) ** 0.5
lambda1 = (a + c) * 0.5 + delta # Major eigenvalue
lambda2 = (a + c) * 0.5 - delta # Minor eigenvalue
theta = atan2(lambda1 - a, b) if b != 0 else (pi * 0.5 if a < c else 0)
trans = Transform()
# Don't translate here. We are working on the complex-vector
# that includes more than just the points. It's horrible what
# we are doing anyway...
# trans = trans.translate(meanX, meanY)
trans = trans.rotate(theta)
trans = trans.scale(sqrt(lambda1), sqrt(lambda2))
transforms.append(trans)
trans = transforms[0]
new_c0 = (
[complex(*trans.transformPoint((pt.real, pt.imag))) for pt in c0[0]],
) + c0[1:]
trans = transforms[1]
new_contour1 = []
for c1 in contour1:
new_c1 = (
[
complex(*trans.transformPoint((pt.real, pt.imag)))
for pt in c1[0]
],
) + c1[1:]
new_contour1.append(new_c1)
# Next few lines duplicate from above.
costs = [
vdiff_hypot2_complex(new_c0[0], new_c1[0]) for new_c1 in new_contour1
]
min_cost_idx, min_cost = min(enumerate(costs), key=lambda x: x[1])
first_cost = costs[0]
if min_cost < first_cost * tolerance:
# Don't report this
# min_cost = first_cost
# reverse = False
# proposed_point = 0 # new_contour1[min_cost_idx][1]
pass
this_tolerance = min_cost / first_cost if first_cost else 1
log.debug(
"test-starting-point: tolerance %g",
this_tolerance,