在iOS中的两条线之间绘制垂直线

时间:2019-09-06 10:35:42

标签: ios swift

我想在P1和P2之间画一条与P3相对应的垂直线。 我有P1和P2,当我触摸UIView时将显示P3。 现在,我想从P3绘制与P1和P2相对应的垂直线。

enter image description here

2 个答案:

答案 0 :(得分:1)

我相信这是一个几何问题。无论如何,给定一条被分割为P1P2的线,您想从名为P3的外部点绘制一条垂直线。

您可以找到垂直线与P1P2相交的点,如下所示:

令P1的坐标为(x1,y1),P2的坐标为(x2,y2),P3的坐标为(x3,y3)和(x4,y4)的坐标为与直线相交的点。

x4和y4可以通过以下方式确定:

k = ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) / ((y2-y1)^2 + (x2-x1)^2)
x4 = x3 - k * (y2-y1)
y4 = y3 + k * (x2-x1)

一旦确定了x4和y4,现在就可以绘制从P3到(x4,y4)的垂直线。

这是几何形状;使用UIKit绘制线或获取点的坐标是另一回事。

答案 1 :(得分:1)

因此,您需要一点数学...从理论上讲,您需要从P3XP1P2之间的一点画一条线。 P1X之间的向量实际上是P3-P1P1P2描述的线的投影。所以:

X = P1 + (P3-P1)*((P2-P1)/(|P2-P1|)) * ((P2-P1)/(|P2-P1|))

要使用CGPoint,可以这样做:

func projectedPoint(_ point: CGPoint, toLine line: (a: CGPoint, b: CGPoint)) -> CGPoint {

    guard line.a != line.b else { return .zero } // Not a line

    let direction: CGPoint = {
        // A direction of line with a distance of 1
        let a = line.a
        let b = line.b
        let subtraction = CGPoint(x: b.x - a.x, y: b.y - a.y)
        let distance = sqrt(subtraction.x*subtraction.x + subtraction.y*subtraction.y)
        return CGPoint(x: subtraction.x/distance, y: subtraction.y/distance)
    }()

    let projectionDistance: CGFloat = {
        let vector = CGPoint(x: point.x-line.a.x, y: point.y-line.a.y) // From A to POINT
        return vector.x*direction.x + vector.y*direction.y // A simple dot product
    }()

    return CGPoint(x: line.a.x + direction.x*projectionDistance, y: line.a.y + direction.y*projectionDistance)
}

所以在您的情况下:

X = projectedPoint(P3, toLine:(P1, P2))

现在,您只需在XP3之间划一条线即可。

或者,如果您希望它具有更多功能,则应执行以下操作。将它移植到任何使用2D向量运行的系统上也应该很容易,该系统通常已经包括所有提供的功能:

func projectedPoint(_ point: CGPoint, toLine line: (a: CGPoint, b: CGPoint)) -> CGPoint {

    guard line.a != line.b else { return .zero } // Not a line

    func add(_ a: CGPoint, _ b: CGPoint) -> CGPoint { return CGPoint(x: a.x + b.x, y: a.y + b.y) }
    func subtract(_ a: CGPoint, _ b: CGPoint) -> CGPoint { return CGPoint(x: a.x - b.x, y: a.y - b.y) }
    func scale(_ a: CGPoint, _ b: CGFloat) -> CGPoint { return CGPoint(x: a.x*b, y: a.y*b) }
    func dot(_ a: CGPoint, _ b: CGPoint) -> CGFloat { return a.x*b.x + a.y*b.y }
    func length(_ a: CGPoint) -> CGFloat { return sqrt(a.x*a.x + a.y*a.y) }
    func normalize(_ a: CGPoint) -> CGPoint { return scale(a, 1.0/length(a)) }

    let direction: CGPoint = normalize(subtract(line.b, line.a))
    let projectionDistance = dot(subtract(point, line.a), direction)

    return add(line.a, scale(direction, projectionDistance))
}
相关问题