阅读 419

S02E16:三角形外心(外接圆圆心)

说明

三角形的外心,就是外接圆的圆心,是三条边垂直平分线的交点,也就是到各个顶点距离相等的点。

几何

外心同样利用重心坐标进行计算,根据书上公式:

我们对重心坐标公式中的项目进行展开合并,以c2 + c3为例:

c2 + c3 = d3d1 + d1d2 = -dot(e1, e2) * -dot(e2, e3) + -dot(e2, e3) * -dot(e3, e1)
// 由于点乘的结果是一个数字,故抵消上面的负号后,满足乘法结合律,进行重新组合
=  dot(e2, e3) * (dot(e1, e2) + dot(e3, e1))
// 点乘运算本身也是满足乘法结合律,和交换律的,故可以再次重新组合
= dot(e2, e3) * dot(e1, (e2+e3) ) = dot(e2, e3) * dot(e1, -e1) =  dot(e2, e3) * -lengthSquared(e1)
复制代码

同样道理,对c = c1 + c2 +c3进行处理:

2c = 2*(c1 + c2 +c3) = c2 + c3 + c3 + c1 + c1 + c2
= dot(e2, e3) * -lengthSquared(e1) + dot(e3, e1) * -lengthSquared(e2) + dot(e1, e2) * -lengthSquared(e3)

// 这里我们让 v = simd_float3(dot(e2, e3), dot(e3, e1), dot(e1, e2)), u = simd_float3(lengthSquared(e1), lengthSquared(e2), lengthSquared(e3))

= -dot(v, u)
复制代码

最后得到重心坐标为:

(dot(e2, e3) * -lengthSquared(e1) , dot(e1, e3) * -lengthSquared(e2), dot(e1, e2) * -lengthSquared(e3)) / -dot(v, u)
// 抵消负号,用向量表示分子,得到外心的重心坐标
= v * u / dot(v, u)
复制代码

外接圆半径也可以根据下面的公式直接得到:

代码

///三角形外心的重心坐标
static func circumcenterInBarycentricCoordinate(triangle:Triangle) -> simd_float3 {
    let e1 = triangle.point3 - triangle.point2
    let e2 = triangle.point1 - triangle.point3
    let e3 = triangle.point2 - triangle.point1
    
    let edgesSquared = edgesLengthSquared(triangle: triangle)
    let v = simd_float3(dot(e2,e3), dot(e3,e1), dot(e1,e2))
    let t = v * edgesSquared
    let d = dot(v, edgesSquared)
    return t / d
}

///三角形外心、三点距离相等点
static func circumcenter(triangle:Triangle) -> simd_float3 {
    let coor = circumcenterInBarycentricCoordinate(triangle: triangle)
    let s = triangle.points * coor
    return s
}
///三角形外切圆半径
static func circumcenterRadius(triangle:Triangle) -> Float {
    let edges = edgesLength(triangle: triangle)
    let A = area(edgesLength: edges)
    let ss = edges.x * edges.y * edges.z / 4 / A
    return ss
}
复制代码
文章分类
iOS
文章标签