[interpolatable] Add (unused) transform_from_stats
This commit is contained in:
parent
e23fa9195c
commit
13ef1ba2f0
@ -322,6 +322,41 @@ def _find_parents_and_order(glyphsets, locations):
|
|||||||
return parents, order
|
return parents, order
|
||||||
|
|
||||||
|
|
||||||
|
def _transform_from_stats(stats, inverse=False):
|
||||||
|
# https://cookierobotics.com/007/
|
||||||
|
a = stats.varianceX
|
||||||
|
b = stats.covariance
|
||||||
|
c = stats.varianceY
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
if lambda2 < 0:
|
||||||
|
# XXX This is a hack.
|
||||||
|
# The problem is that the covariance matrix is singular.
|
||||||
|
# This happens when the contour is a line, or a circle.
|
||||||
|
# In that case, the covariance matrix is not a good
|
||||||
|
# representation of the contour.
|
||||||
|
# We should probably detect this earlier and avoid
|
||||||
|
# computing the covariance matrix in the first place.
|
||||||
|
# But for now, we just avoid the division by zero.
|
||||||
|
lambda2 = 0
|
||||||
|
|
||||||
|
if inverse:
|
||||||
|
trans = trans.translate(-stats.meanX, -stats.meanY)
|
||||||
|
trans = trans.rotate(-theta)
|
||||||
|
trans = trans.scale(1 / sqrt(lambda1), 1 / sqrt(lambda2))
|
||||||
|
else:
|
||||||
|
trans = trans.scale(sqrt(lambda1), sqrt(lambda2))
|
||||||
|
trans = trans.rotate(theta)
|
||||||
|
trans = trans.translate(stats.meanX, stats.meanY)
|
||||||
|
|
||||||
|
return trans
|
||||||
|
|
||||||
|
|
||||||
def lerp_recordings(recording1, recording2, factor=0.5):
|
def lerp_recordings(recording1, recording2, factor=0.5):
|
||||||
pen = RecordingPen()
|
pen = RecordingPen()
|
||||||
value = pen.value
|
value = pen.value
|
||||||
|
Loading…
x
Reference in New Issue
Block a user