Revert "Use Vector in some places where it improves the clarity of the code" (#2215)

* Revert most of "Use Vector in some places where it improves the clarity of the code (#2206)"

This reverts most of commit 0d3ce2cafc6f604fc46d4d3bfbab34a5bc59e27b.
This commit is contained in:
Just van Rossum 2021-03-04 20:15:24 +01:00 committed by GitHub
parent 0d3ce2cafc
commit 6a8821d91c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 69 deletions

View File

@ -4,7 +4,6 @@
from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea
from fontTools.misc.transform import Offset, Identity from fontTools.misc.transform import Offset, Identity
from fontTools.misc.vector import Vector
from fontTools.misc.py23 import * from fontTools.misc.py23 import *
import math import math
from collections import namedtuple from collections import namedtuple
@ -244,15 +243,16 @@ def calcQuadraticBounds(pt1, pt2, pt3):
>>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100))
(0.0, 0.0, 100, 100) (0.0, 0.0, 100, 100)
""" """
a, b, c = calcQuadraticParameters(pt1, pt2, pt3) (ax, ay), (bx, by), (cx, cy) = calcQuadraticParameters(pt1, pt2, pt3)
ax2, ay2 = a * 2 ax2 = ax * 2.0
ay2 = ay * 2.0
roots = [] roots = []
if ax2 != 0: if ax2 != 0:
roots.append(-b[0] / ax2) roots.append(-bx / ax2)
if ay2 != 0: if ay2 != 0:
roots.append(-b[1] / ay2) roots.append(-by / ay2)
points = [ points = [
a * (t * t) + b * t + c (ax * t * t + bx * t + cx, ay * t * t + by * t + cy)
for t in roots for t in roots
if 0 <= t < 1 if 0 <= t < 1
] + [pt1, pt3] ] + [pt1, pt3]
@ -343,17 +343,21 @@ def calcCubicBounds(pt1, pt2, pt3, pt4):
>>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0))) >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0)))
35.566243 0.000000 64.433757 75.000000 35.566243 0.000000 64.433757 75.000000
""" """
a, b, c, d = calcCubicParameters(pt1, pt2, pt3, pt4) (ax, ay), (bx, by), (cx, cy), (dx, dy) = calcCubicParameters(pt1, pt2, pt3, pt4)
# calc first derivative # calc first derivative
ax3, ay3 = a * 3.0 ax3 = ax * 3.0
bx2, by2 = b * 2.0 ay3 = ay * 3.0
cx, cy = c bx2 = bx * 2.0
by2 = by * 2.0
xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1] xRoots = [t for t in solveQuadratic(ax3, bx2, cx) if 0 <= t < 1]
yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1] yRoots = [t for t in solveQuadratic(ay3, by2, cy) if 0 <= t < 1]
roots = xRoots + yRoots roots = xRoots + yRoots
points = [ points = [
a * (t * t * t) + b * (t * t) + c * t + d (
ax * t * t * t + bx * t * t + cx * t + dx,
ay * t * t * t + by * t * t + cy * t + dy,
)
for t in roots for t in roots
] + [pt1, pt4] ] + [pt1, pt4]
return calcBounds(points) return calcBounds(points)
@ -395,17 +399,22 @@ def splitLine(pt1, pt2, where, isHorizontal):
((0, 100), (0, 50)) ((0, 100), (0, 50))
((0, 50), (0, 0)) ((0, 50), (0, 0))
""" """
pt1 = Vector(pt1) pt1x, pt1y = pt1
pt2 = Vector(pt2) pt2x, pt2y = pt2
a = pt2 - pt1 ax = pt2x - pt1x
b = pt1 ay = pt2y - pt1y
if a[isHorizontal] == 0: bx = pt1x
by = pt1y
a = (ax, ay)[isHorizontal]
if a == 0:
return [(pt1, pt2)] return [(pt1, pt2)]
t = (where - b[isHorizontal]) / a[isHorizontal] t = (where - (bx, by)[isHorizontal]) / a
if 0 <= t < 1: if 0 <= t < 1:
midPt = a * t + b midPt = ax * t + bx, ay * t + by
return [(pt1, midPt), (midPt, pt2)] return [(pt1, midPt), (midPt, pt2)]
else: else:
return [(pt1, pt2)] return [(pt1, pt2)]
@ -546,18 +555,24 @@ def _splitQuadraticAtT(a, b, c, *ts):
segments = [] segments = []
ts.insert(0, 0.0) ts.insert(0, 0.0)
ts.append(1.0) ts.append(1.0)
ax, ay = a
bx, by = b
cx, cy = c
for i in range(len(ts) - 1): for i in range(len(ts) - 1):
t1 = ts[i] t1 = ts[i]
t2 = ts[i + 1] t2 = ts[i + 1]
delta = t2 - t1 delta = t2 - t1
# calc new a, b and c # calc new a, b and c
delta_2 = delta * delta delta_2 = delta * delta
a1 = a * delta_2 a1x = ax * delta_2
b1 = (2 * a * t1 + b) * delta a1y = ay * delta_2
b1x = (2 * ax * t1 + bx) * delta
b1y = (2 * ay * t1 + by) * delta
t1_2 = t1 * t1 t1_2 = t1 * t1
c1 = a * t1_2 + b * t1 + c c1x = ax * t1_2 + bx * t1 + cx
c1y = ay * t1_2 + by * t1 + cy
pt1, pt2, pt3 = calcQuadraticPoints(a1, b1, c1) pt1, pt2, pt3 = calcQuadraticPoints((a1x, a1y), (b1x, b1y), (c1x, c1y))
segments.append((pt1, pt2, pt3)) segments.append((pt1, pt2, pt3))
return segments return segments
@ -567,6 +582,10 @@ def _splitCubicAtT(a, b, c, d, *ts):
ts.insert(0, 0.0) ts.insert(0, 0.0)
ts.append(1.0) ts.append(1.0)
segments = [] segments = []
ax, ay = a
bx, by = b
cx, cy = c
dx, dy = d
for i in range(len(ts) - 1): for i in range(len(ts) - 1):
t1 = ts[i] t1 = ts[i]
t2 = ts[i + 1] t2 = ts[i + 1]
@ -578,11 +597,17 @@ def _splitCubicAtT(a, b, c, d, *ts):
t1_3 = t1 * t1_2 t1_3 = t1 * t1_2
# calc new a, b, c and d # calc new a, b, c and d
a1 = a * delta_3 a1x = ax * delta_3
b1 = (3 * a * t1 + b) * delta_2 a1y = ay * delta_3
c1 = (2 * b * t1 + c + 3 * a * t1_2) * delta b1x = (3 * ax * t1 + bx) * delta_2
d1 = a * t1_3 + b * t1_2 + c * t1 + d b1y = (3 * ay * t1 + by) * delta_2
pt1, pt2, pt3, pt4 = calcCubicPoints(a1, b1, c1, d1) c1x = (2 * bx * t1 + cx + 3 * ax * t1_2) * delta
c1y = (2 * by * t1 + cy + 3 * ay * t1_2) * delta
d1x = ax * t1_3 + bx * t1_2 + cx * t1 + dx
d1y = ay * t1_3 + by * t1_2 + cy * t1 + dy
pt1, pt2, pt3, pt4 = calcCubicPoints(
(a1x, a1y), (b1x, b1y), (c1x, c1y), (d1x, d1y)
)
segments.append((pt1, pt2, pt3, pt4)) segments.append((pt1, pt2, pt3, pt4))
return segments return segments
@ -725,37 +750,57 @@ def solveCubic(a, b, c, d):
def calcQuadraticParameters(pt1, pt2, pt3): def calcQuadraticParameters(pt1, pt2, pt3):
pt1, pt2, pt3 = (Vector(pt) for pt in (pt1, pt2, pt3)) x2, y2 = pt2
c = pt1 x3, y3 = pt3
b = (pt2 - c) * 2.0 cx, cy = pt1
a = pt3 - c - b bx = (x2 - cx) * 2.0
return a, b, c by = (y2 - cy) * 2.0
ax = x3 - cx - bx
ay = y3 - cy - by
return (ax, ay), (bx, by), (cx, cy)
def calcCubicParameters(pt1, pt2, pt3, pt4): def calcCubicParameters(pt1, pt2, pt3, pt4):
pt1, pt2, pt3, pt4 = (Vector(pt) for pt in (pt1, pt2, pt3, pt4)) x2, y2 = pt2
d = pt1 x3, y3 = pt3
c = (pt2 - d) * 3.0 x4, y4 = pt4
b = (pt3 - pt2) * 3.0 - c dx, dy = pt1
a = pt4 - d - c - b cx = (x2 - dx) * 3.0
return a, b, c, d cy = (y2 - dy) * 3.0
bx = (x3 - x2) * 3.0 - cx
by = (y3 - y2) * 3.0 - cy
ax = x4 - dx - cx - bx
ay = y4 - dy - cy - by
return (ax, ay), (bx, by), (cx, cy), (dx, dy)
def calcQuadraticPoints(a, b, c): def calcQuadraticPoints(a, b, c):
a, b, c = (Vector(coeff) for coeff in (a, b, c)) ax, ay = a
pt1 = c bx, by = b
pt2 = (b * 0.5) + c cx, cy = c
pt3 = a + b + c x1 = cx
return pt1, pt2, pt3 y1 = cy
x2 = (bx * 0.5) + cx
y2 = (by * 0.5) + cy
x3 = ax + bx + cx
y3 = ay + by + cy
return (x1, y1), (x2, y2), (x3, y3)
def calcCubicPoints(a, b, c, d): def calcCubicPoints(a, b, c, d):
a, b, c, d = (Vector(coeff) for coeff in (a, b, c, d)) ax, ay = a
pt1 = d bx, by = b
pt2 = (c / 3.0) + d cx, cy = c
pt3 = (b + c) / 3.0 + pt2 dx, dy = d
pt4 = a + d + c + b x1 = dx
return pt1, pt2, pt3, pt4 y1 = dy
x2 = (cx / 3.0) + dx
y2 = (cy / 3.0) + dy
x3 = (bx + cx) / 3.0 + x2
y3 = (by + cy) / 3.0 + y2
x4 = ax + dx + cx + bx
y4 = ay + dy + cy + by
return (x1, y1), (x2, y2), (x3, y3), (x4, y4)
# #
@ -773,7 +818,7 @@ def linePointAtT(pt1, pt2, t):
Returns: Returns:
A 2D tuple with the coordinates of the point. A 2D tuple with the coordinates of the point.
""" """
return (Vector(pt1) * (1 - t) + Vector(pt2) * t) return ((pt1[0] * (1 - t) + pt2[0] * t), (pt1[1] * (1 - t) + pt2[1] * t))
def quadraticPointAtT(pt1, pt2, pt3, t): def quadraticPointAtT(pt1, pt2, pt3, t):
@ -786,9 +831,9 @@ def quadraticPointAtT(pt1, pt2, pt3, t):
Returns: Returns:
A 2D tuple with the coordinates of the point. A 2D tuple with the coordinates of the point.
""" """
pt1, pt2, pt3 = (Vector(pt) for pt in (pt1, pt2, pt3)) x = (1 - t) * (1 - t) * pt1[0] + 2 * (1 - t) * t * pt2[0] + t * t * pt3[0]
t1 = 1 - t y = (1 - t) * (1 - t) * pt1[1] + 2 * (1 - t) * t * pt2[1] + t * t * pt3[1]
return t1 * t1 * pt1 + 2 * t1 * t * pt2 + t * t * pt3 return (x, y)
def cubicPointAtT(pt1, pt2, pt3, pt4, t): def cubicPointAtT(pt1, pt2, pt3, pt4, t):
@ -801,14 +846,19 @@ def cubicPointAtT(pt1, pt2, pt3, pt4, t):
Returns: Returns:
A 2D tuple with the coordinates of the point. A 2D tuple with the coordinates of the point.
""" """
pt1, pt2, pt3, pt4 = (Vector(pt) for pt in (pt1, pt2, pt3, pt4)) x = (
t1 = 1 - t (1 - t) * (1 - t) * (1 - t) * pt1[0]
return ( + 3 * (1 - t) * (1 - t) * t * pt2[0]
t1 * t1 * t1 * pt1 + 3 * (1 - t) * t * t * pt3[0]
+ 3 * t1 * t1 * t * pt2 + t * t * t * pt4[0]
+ 3 * t1 * t * t * pt3
+ t * t * t * pt4
) )
y = (
(1 - t) * (1 - t) * (1 - t) * pt1[1]
+ 3 * (1 - t) * (1 - t) * t * pt2[1]
+ 3 * (1 - t) * t * t * pt3[1]
+ t * t * t * pt4[1]
)
return (x, y)
def segmentPointAtT(seg, t): def segmentPointAtT(seg, t):
@ -863,7 +913,7 @@ def lineLineIntersections(s1, e1, s2, e2):
1 1
>>> intersection = a[0] >>> intersection = a[0]
>>> intersection.pt >>> intersection.pt
Vector((374.44882952482897, 313.73458370177315)) (374.44882952482897, 313.73458370177315)
>>> (intersection.t1, intersection.t2) >>> (intersection.t1, intersection.t2)
(0.45069111555824454, 0.5408153767394238) (0.45069111555824454, 0.5408153767394238)
""" """
@ -887,7 +937,7 @@ def lineLineIntersections(s1, e1, s2, e2):
x = s1x x = s1x
slope34 = (e2y - s2y) / (e2x - s2x) slope34 = (e2y - s2y) / (e2x - s2x)
y = slope34 * (x - s2x) + s2y y = slope34 * (x - s2x) + s2y
pt = Vector((x, y)) pt = (x, y)
return [ return [
Intersection( Intersection(
pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt)
@ -897,7 +947,7 @@ def lineLineIntersections(s1, e1, s2, e2):
x = s2x x = s2x
slope12 = (e1y - s1y) / (e1x - s1x) slope12 = (e1y - s1y) / (e1x - s1x)
y = slope12 * (x - s1x) + s1y y = slope12 * (x - s1x) + s1y
pt = Vector((x, y)) pt = (x, y)
return [ return [
Intersection( Intersection(
pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt) pt=pt, t1=_line_t_of_pt(s1, e1, pt), t2=_line_t_of_pt(s2, e2, pt)
@ -910,7 +960,7 @@ def lineLineIntersections(s1, e1, s2, e2):
return [] return []
x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34) x = (slope12 * s1x - s1y - slope34 * s2x + s2y) / (slope12 - slope34)
y = slope12 * (x - s1x) + s1y y = slope12 * (x - s1x) + s1y
pt = Vector((x, y)) pt = (x, y)
if _both_points_are_on_same_side_of_origin( if _both_points_are_on_same_side_of_origin(
pt, e1, s1 pt, e1, s1
) and _both_points_are_on_same_side_of_origin(pt, s2, e2): ) and _both_points_are_on_same_side_of_origin(pt, s2, e2):
@ -964,7 +1014,7 @@ def curveLineIntersections(curve, line):
>>> len(intersections) >>> len(intersections)
3 3
>>> intersections[0].pt >>> intersections[0].pt
Vector((84.90010344084885, 189.87306176459828)) (84.90010344084885, 189.87306176459828)
""" """
if len(curve) == 3: if len(curve) == 3:
pointFinder = quadraticPointAtT pointFinder = quadraticPointAtT
@ -1085,7 +1135,7 @@ def curveCurveIntersections(curve1, curve2):
>>> len(intersections) >>> len(intersections)
3 3
>>> intersections[0].pt >>> intersections[0].pt
Vector((81.7831487395506, 109.88904552375288)) (81.7831487395506, 109.88904552375288)
""" """
intersection_ts = _curve_curve_intersections_t(curve1, curve2) intersection_ts = _curve_curve_intersections_t(curve1, curve2)
return [ return [
@ -1113,14 +1163,14 @@ def segmentSegmentIntersections(seg1, seg2):
>>> len(intersections) >>> len(intersections)
3 3
>>> intersections[0].pt >>> intersections[0].pt
Vector((81.7831487395506, 109.88904552375288)) (81.7831487395506, 109.88904552375288)
>>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ] >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ]
>>> line = [ (25, 260), (230, 20) ] >>> line = [ (25, 260), (230, 20) ]
>>> intersections = segmentSegmentIntersections(curve3, line) >>> intersections = segmentSegmentIntersections(curve3, line)
>>> len(intersections) >>> len(intersections)
3 3
>>> intersections[0].pt >>> intersections[0].pt
Vector((84.90010344084885, 189.87306176459828)) (84.90010344084885, 189.87306176459828)
""" """
# Arrange by degree # Arrange by degree

View File

@ -132,7 +132,6 @@ def test_solveCubic():
assert solveCubic(9.0, 0.0, 0.0, -7.62939453125e-05) == [-0.0, -0.0, -0.0] assert solveCubic(9.0, 0.0, 0.0, -7.62939453125e-05) == [-0.0, -0.0, -0.0]
_segmentPointAtT_testData = [ _segmentPointAtT_testData = [
([(0, 10), (200, 100)], 0.0, (0, 10)), ([(0, 10), (200, 100)], 0.0, (0, 10)),
([(0, 10), (200, 100)], 0.5, (100, 55)), ([(0, 10), (200, 100)], 0.5, (100, 55)),