長方形の1つの角を原点として選択します。それに接続された2つのエッジがベースになります(u
およびv
、は互いに垂直である必要があります)。最初にそれらを正規化する必要があります。
u
座標から原点を引き、スケーリングベクトル( )と他のベクトル( )を使用して内積を計算しv
ます。これはあなたにいくらを与え、コーディネートu
にv
貢献します。
次に、必要なコンポーネントをスケーリングします。最終的な座標を取得するには、(現在スケーリングされている)コンポーネントにそれぞれのベクトルを掛けて、それらを足し合わせます。
例えば:
Points: p1 = (3,5) and p2 = (6,4)
Selection corners: (0,2),(8,0),(9,4),(1,6)
selected origin = (8,0)
u = ((0,2)-(8,0))/|(0,2)-(8,0)| = <-0.970, 0.242>
v = <-0.242, -0.970>
(v
ですがu
、座標が反転しており、そのうちの1つが否定されています)
p1´ = p1 - origin = (-5, 5)
p2´ = p2 - origin = (-2, 4)
p1_u = p1´ . u = -0.970 * (-5) + 0.242 * 5 = 6.063
p1_v = p1´ . v = -0.242 * (-5) - 0.970 * 5 = -3.638
Scale p1_u by 0.5: 3.038
p1_u * u + p1_v * v + origin = <5.941, 4.265>
Same for p2: <7.412, 3.647>
ご覧のとおり、原点として0.5でスケーリングしたため(8,0)
、線に向かって移動しています。(9,4)
(0,8)
編集:これは私が予想したよりも説明するのが少し難しいことがわかりました。
Pythonコードでは、次のようになります。
def scale(points, origin, u, scale):
# normalize
len_u = (u[0]**2 + u[1]**2) ** 0.5
u = (u[0]/len_u, u[1]/len_u)
# create v
v = (-u[1],u[0])
ret = []
for x,y in points:
# subtract origin
x, y = x - origin[0], y - origin[1]
# calculate dot product
pu = x * u[0] + y * u[1]
pv = x * v[0] + y * v[1]
# scale
pu = pu * scale
# transform back to normal space
x = pu * u[0] + pv * v[0] + origin[0]
y = pu * u[1] + pv * v[1] + origin[1]
ret.append((x,y))
return ret
>>> scale([(3,5),(6,4)],(8,0),(-8,2),0.5)
[(5.9411764705882355, 4.2647058823529411), (7.4117647058823533, 3.6470588235294117)]