簡體   English   中英

在另一條線的一點畫一條固定長度的垂線

[英]Draw perpendicular line of fixed length at a point of another line

我有兩點 A (10,20) 和 B (15,30)。 這些點生成一條線 AB。 我需要在 Python 的 B 點上畫一條長度為 6(每個方向 3 個單位)的垂線 CD。

我已經使用以下代碼獲得了 AB 線的一些屬性:

from scipy import stats
x = [10,15]
y = [20,30]
slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)

如何計算 C 和 D 的位置。我需要它們的 X 和 Y 值。 在此處輸入圖像描述

C 和 D 的值將用於使用 Shapely 庫完成另一個目標。

如果slope是AB的斜率,則CD的斜率是-1/slope 這等於垂直變化與水平變化: dy/dx = -1/slope 得出dx = -slope*dx 根據畢達哥拉斯定理,您有3**2 = dy**2+dx**2 代替dx ,您會得到

3**2 = (-slope*dy)**2+dy**2
3**2 = (slope**2 + 1)*dy**2
dy**2 = 3**2/(slope**2+1)
dy = math.sqrt(3**2/(slope**2+1))

然后可以得到dx = -slope*dy 最后,您可以使用dxdy獲得C和D。因此代碼如下:

import math
dy = math.sqrt(3**2/(slope**2+1))
dx = -slope*dy
C[0] = B[0] + dx
C[1] = B[1] + dy
D[0] = B[0] - dx
D[1] = B[1] - dy

(請注意,盡管math.sqrt僅返回一個數字,但通常會有一個正負平方根。C對應正平方根,D對應負數)。

您可能應該使用向量來計算點的位置。

  • 創建vector AB
  • 計算其normalized perpendicular
  • 加或減3倍於B

在一個簡單的,可重復使用的Vector class的幫助下,該計算是微不足道的,並且讀起來像英語:

在距B3處找到垂直於AB點:
P1 = B + (BA).perp().normalized() * 3 P2 = B + (BA).perp().normalized() * 3

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __sub__(self, other):
        return Vector(self.x - other.x, self.y - other.y)
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    def dot(self, other):
        return self.x * other.x + self.y * other.y
    def norm(self):
        return self.dot(self)**0.5
    def normalized(self):
        norm = self.norm()
        return Vector(self.x / norm, self.y / norm)
    def perp(self):
        return Vector(1, -self.x / self.y)
    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    def __str__(self):
        return f'({self.x}, {self.y})'


A = Vector(10, 20)
B = Vector(15, 30)

AB = B - A  
AB_perp_normed = AB.perp().normalized()
P1 = B + AB_perp_normed * 3
P2 = B - AB_perp_normed * 3

print(f'Point{P1}, and Point{P2}')

輸出:

Point(17.683281572999746, 28.658359213500127), and Point(12.316718427000252, 31.341640786499873)

因為您對使用Shapely感興趣,所以獲得我能想到的垂直線的最簡單方法是使用parallel_offset方法將兩條平行線連接到AB,並將它們的端點連接起來:

from shapely.geometry import LineString

a = (10, 20)
b = (15, 30)
cd_length = 6

ab = LineString([a, b])
left = ab.parallel_offset(cd_length / 2, 'left')
right = ab.parallel_offset(cd_length / 2, 'right')
c = left.boundary[1]
d = right.boundary[0]  # note the different orientation for right offset
cd = LineString([c, d])

在此處輸入圖片說明

和CD的坐標:

>>> c.x, c.y
(12.316718427000252, 31.341640786499873)
>>> d.x, d.y
(17.683281572999746, 28.658359213500127)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM