# S02E16：三角形外心（外接圆圆心）

## 几何

``````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)

``````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