我正在尝试制作一个以3点作为参数的函数。其中的前两个代表直线上的两个点。第三个代表该线之外的另一点。假设在前两个点所定义的直线上穿过第三个点的垂直线。现在我想做的就是计算该交点。到目前为止,我已经提出了此过程,但是以某种方式,它只能在50%的时间内起作用。有人可以找出我在做什么错吗?
def calculateIntersection(p1: (Double, Double), p2: (Double, Double), c: (Double, Double)): (Double, Double) = {
var intersection: (Double, Double) = null
// CASE 1: line is vertical
if(p1._1 == p2._1) {
intersection = (p1._1, c._2)
}
// CASE 2: line is horizontal
else if(p1._2 == p2._2) {
intersection = (c._1, p1._2)
}
// CASE 3: line is neither vertical, nor horizontal
else {
val slope1: Double = (p2._2 - p1._2) / (p2._1 - p1._1) // slope of the line
val slope2: Double = pow(slope1, -1) * -1 // slope of the perpendicular
val intercept1: Double = p1._2 - (slope1 * p1._1) // y-intercept of the line
val intercept2: Double = c._2 - (slope2 * c._1) // y-intercept of the perpendicular
intersection = ((intercept2 - intercept1) / (slope1 - slope2),
slope1 * ((intercept2 - intercept1) / (slope1 - slope2)) + intercept1)
}
intersection
}
答案 0 :(得分:3)
给出以下定义:
type Point = (Double, Double)
implicit class PointOps(p: Point) {
def +(other: Point) = (p._1 + other._1, p._2 + other._2)
def -(other: Point) = (p._1 - other._1, p._2 - other._2)
def dot(other: Point) = p._1 * other._1 + p._2 * other._2
def *(scalar: Double) = (p._1 * scalar, p._2 * scalar)
def normSquare: Double = p._1 * p._1 + p._2 * p._2
}
表示
a + b // is vector addition
a - b // is vector subtraction
a dot b // is the dot product (scalar product)
a * f // is multiplication of a vector `a` with a scalar factor `f`
a.normSquare // is the squared length of a vector
您将获得点p
在通过点line1
和line2
的直线上的投影,如下所示:
/** Projects point `p` on line going through two points `line1` and `line2`. */
def projectPointOnLine(line1: Point, line2: Point, p: Point): Point = {
val v = p - line1
val d = line2 - line1
line1 + d * ((v dot d) / d.normSquare)
}
示例:
println(projectPointOnLine((-1.0, 10.0), (7.0, 4.0), (6.0, 11.0)))
给予
(3.0, 7.0)
这在3D(或n-D)中的工作方式完全相同。
其背后的一些数学运算法则(如何从头算起)
(如上所述)
我们有三个点:l1
和l2
代表直线,p
代表目标点。
我们想将点p
正交投影到经过l1
和l2
的直线上(假设l1 != l2
)。
让d = l2 - l1
为从l1
到l2
的方向。那么线上的每个点都可以表示为
l1 + d * t
具有标量因子t
。现在我们要找到一个t
,使得连接p
和l1 + d * t
的向量与d
正交,即:
(p - (l1 + d * t)) dot d == 0
回想一下
(v1 + v2) dot v3 = (v1 dot v3) + (v2 dot v3)
对于所有向量v1, v2, v3
,以及
(v1 * s) dot v2 = (v1 dot v2) * s
标量因子s
。使用此定义和定义v.normSquared = v dot v
,我们获得:
(p - l1 - d * t) dot d
= (p - l1) dot d - (d dot d) * t
= (p - l1) dot d - d.normSquare * t
,它应该变成0
。解决t
可以得出:
t = ((p - l1) dot d) / d.normSquare
这正是代码中使用的公式。
(感谢SergGr添加了派生的初始草图)