说明
三角形的外心,就是外接圆的圆心,是三条边垂直平分线的交点,也就是到各个顶点距离相等的点。
几何
外心同样利用重心坐标进行计算,根据书上公式:
我们对重心坐标公式中的项目进行展开合并,以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
}