mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
8f9e194c0c
commit
bb3abdea1d
22 files changed
+322
-122
No files matched your search
@@ -116,7 +116,7 @@ func centerArc(start Point, arc Segment) (geometryArc, error) {
|
||||
}
|
||||
angle := math.Mod(arc.Rotation, 360) * math.Pi / 180
|
||||
sine, cosine := math.Sincos(angle)
|
||||
dx, dy := (start.X-arc.End.X)/2, (start.Y-arc.End.Y)/2
|
||||
dx, dy := arcCoordinateMean(start.X, -arc.End.X), arcCoordinateMean(start.Y, -arc.End.Y)
|
||||
x, y := cosine*dx+sine*dy, -sine*dx+cosine*dy
|
||||
scale := math.Hypot(x/rx, y/ry)
|
||||
if scale > 1 {
|
||||
@@ -139,13 +139,24 @@ func centerArc(start Point, arc Segment) (geometryArc, error) {
|
||||
if !arc.Sweep && delta > 0 {
|
||||
delta -= 2 * math.Pi
|
||||
}
|
||||
center := Point{cosine*cx - sine*cy + (start.X+arc.End.X)/2, sine*cx + cosine*cy + (start.Y+arc.End.Y)/2}
|
||||
center := Point{cosine*cx - sine*cy + arcCoordinateMean(start.X, arc.End.X), sine*cx + cosine*cy + arcCoordinateMean(start.Y, arc.End.Y)}
|
||||
if !finite(center.X) || !finite(center.Y) || !finite(rx) || !finite(ry) || !finite(delta) || !finite(theta) || delta == 0 {
|
||||
return geometryArc{}, fmt.Errorf("invalid arc extent")
|
||||
}
|
||||
return geometryArc{center, Point{rx * cosine, rx * sine}, Point{-ry * sine, ry * cosine}, theta, delta}, nil
|
||||
}
|
||||
|
||||
// arcCoordinateMean 计算有限坐标均值,仅在求和溢出时先减半,避免微小坐标提前下溢
|
||||
// 入参: a 第一个坐标, b 第二个坐标
|
||||
// 返回: float64 坐标均值
|
||||
func arcCoordinateMean(a, b float64) float64 {
|
||||
value := (a + b) / 2
|
||||
if math.IsInf(value, 0) {
|
||||
return a/2 + b/2
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// point 计算椭圆参数对应的坐标
|
||||
// 入参: angle 参数角
|
||||
// 返回: Point 椭圆上的点
|
||||
|
||||
@@ -125,7 +125,7 @@ func (m Matrix) Invert() (Matrix, bool) {
|
||||
return n, true
|
||||
}
|
||||
|
||||
// matrixProductDifference 计算两个乘积之差,检查溢出、下溢及相消造成的精度损失
|
||||
// matrixProductDifference 补偿乘积相减的舍入残差,检查溢出、下溢及严重相消
|
||||
// 入参: a 第一个乘数, b 第二个乘数, c 第三个乘数, d 第四个乘数
|
||||
// 返回: float64 乘积之差, bool 是否可直接用于求逆
|
||||
func matrixProductDifference(a, b, c, d float64) (float64, bool) {
|
||||
@@ -134,6 +134,9 @@ func matrixProductDifference(a, b, c, d float64) (float64, bool) {
|
||||
if !finite(value) || x == 0 && a != 0 && b != 0 || y == 0 && c != 0 && d != 0 {
|
||||
return value, false
|
||||
}
|
||||
if x != 0 && y != 0 {
|
||||
value = math.FMA(a, b, -y) + math.FMA(-c, d, y)
|
||||
}
|
||||
return value, x == 0 && y == 0 || math.Abs(value) >= 0x1p-1022 && math.Abs(value) >= 0x1p-48*math.Max(math.Abs(x), math.Abs(y))
|
||||
}
|
||||
|
||||
@@ -169,7 +172,7 @@ func TranslationMatrix(x, y float64) Matrix {
|
||||
// YScale 获取Y轴缩放比例
|
||||
// 返回: float64 缩放比例
|
||||
func (m Matrix) YScale() float64 {
|
||||
return math.Sqrt(m.c*m.c + m.d*m.d)
|
||||
return math.Hypot(m.c, m.d)
|
||||
}
|
||||
|
||||
// Equal 比较毫米坐标,使用固定绝对误差,不受绘图库全局精度影响
|
||||
|
||||
@@ -33,10 +33,7 @@ func (p Path) Transform(matrix Matrix) (Path, error) {
|
||||
}
|
||||
}
|
||||
matrixScale := math.Max(math.Max(math.Abs(matrix.a), math.Abs(matrix.b)), math.Max(math.Abs(matrix.c), math.Abs(matrix.d)))
|
||||
determinant := 0.0
|
||||
if matrixScale != 0 {
|
||||
determinant = (matrix.a/matrixScale)*(matrix.d/matrixScale) - (matrix.b/matrixScale)*(matrix.c/matrixScale)
|
||||
}
|
||||
determinant, _ := matrixProductSum(matrix.a, matrix.d, -matrix.b, matrix.c)
|
||||
transform := func(p Point) Point {
|
||||
x, y := matrix.Transform(p.X, p.Y)
|
||||
return Point{x, y}
|
||||
|
||||
Reference in new issue
Block a user