feat(文件拆分): 拆分几何三维基础能力
build.yaml / build (push) Successful in 48s

This commit is contained in:
xiaoqidun committed 2026-10-14 00:44:44 +08:00
1 parent 64f9ec4241
commit 0be872691d
76 files changed
+1926 -1307

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
// Copyright 2025-2026 肖其顿 (XIAO QI DUN)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package geom
import (
"math"
)
// ConvexContains 判断单个非退化凸直线区域是否包含另一闭合直线区域
// 入参: outer 外部区域, inner 内部区域
// 返回: bool 是否完全包含,曲线及多轮廓返回false
func ConvexContains(outer, inner Path) bool {
a, b := geometryPolygonPoints(outer), geometryPolygonPoints(inner)
if len(a) < 3 || len(b) < 3 {
return false
}
nondegenerate := false
for i, start := range a {
end := a[(i+1)%len(a)]
dx, dy := end.X-start.X, end.Y-start.Y
length := math.Hypot(dx, dy)
if !finite(length) {
return false
}
if length == 0 {
continue
}
dx, dy = dx/length, dy/length
distance := func(point Point) float64 {
x, y := point.X-start.X, point.Y-start.Y
value := math.FMA(dx, y, -dy*x)
bound := (math.Abs(dx*y) + math.Abs(dy*x) + math.Abs(dx)*(math.Abs(point.Y)+math.Abs(start.Y)) + math.Abs(dy)*(math.Abs(point.X)+math.Abs(start.X))) * 0x1p-49
if finite(bound) && math.Abs(value) <= bound {
return 0
}
return value
}
sign := 0.0
for _, point := range a {
value := distance(point)
if !finite(value) || sign*value < 0 {
return false
}
if value != 0 {
sign, nondegenerate = math.Copysign(1, value), true
}
}
for _, point := range b {
value := distance(point)
if !finite(value) || sign*value < 0 {
return false
}
}
}
return nondegenerate
}
// geometryPolygonPoints 读取单个显式闭合直线轮廓的顶点,不修改原路径
// 入参: path 直线轮廓
// 返回: []Point 独立顶点,其他路径返回nil
func geometryPolygonPoints(path Path) []Point {
if len(path) < 4 || path[0].Verb != Move || path[len(path)-1].Verb != ClosePath {
return nil
}
for i, segment := range path[:len(path)-1] {
if i > 0 && segment.Verb != Line || !finite(segment.End.X) || !finite(segment.End.Y) {
return nil
}
}
points := make([]Point, len(path)-1)
for i := range points {
points[i] = path[i].End
}
return points
}