This repository was archived by the owner on Dec 5, 2025. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathjmath.go
More file actions
208 lines (170 loc) · 5.09 KB
/
Copy pathjmath.go
File metadata and controls
208 lines (170 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// Copyright 2022 the Vello Authors
// Copyright 2024 Dominik Honnef and contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
package jmath
import (
"math"
"structs"
"golang.org/x/exp/constraints"
"honnef.co/go/curve"
)
const Epsilon = 1e-12
func AbsInt32(x int32) int32 {
if x < 0 {
return -x
}
return x
}
func Abs32(f float32) float32 {
return float32(math.Abs(float64(f)))
}
func Floor32(f float32) float32 {
return float32(math.Floor(float64(f)))
}
func Ceil32(f float32) float32 {
return float32(math.Ceil(float64(f)))
}
func Round32(f float32) float32 {
return float32(math.Round(float64(f)))
}
func Copysign32(f, sign float32) float32 {
return float32(math.Copysign(float64(f), float64(sign)))
}
func Clamp[T constraints.Integer | constraints.Float](x, minv, maxv T) T {
return min(max(x, minv), maxv)
}
func Sqrt32(f float32) float32 {
return float32(math.Sqrt(float64(f)))
}
func Hypot32(a, b float32) float32 {
return float32(math.Hypot(float64(a), float64(b)))
}
func Acos32(x float32) float32 {
return float32(math.Acos(float64(x)))
}
func Sincos32(x float32) (float32, float32) {
a, b := math.Sincos(float64(x))
return float32(a), float32(b)
}
func Atan232(y, x float32) float32 {
return float32(math.Atan2(float64(y), float64(x)))
}
func Cos32(x float32) float32 {
return float32(math.Cos(float64(x)))
}
func Sin32(x float32) float32 {
return float32(math.Sin(float64(x)))
}
func Pow32(x, y float32) float32 {
return float32(math.Pow(float64(x), float64(y)))
}
func Asin32(x float32) float32 {
return float32(math.Asin(float64(x)))
}
func Cbrt32(x float32) float32 {
return float32(math.Cbrt(float64(x)))
}
type Transform struct {
_ structs.HostLayout
Matrix [4]float32
Translation [2]float32
}
var Identity = Transform{
Matrix: [4]float32{1, 0, 0, 1},
}
func (t Transform) Mul(other Transform) Transform {
return Transform{
Matrix: [4]float32{
t.Matrix[0]*other.Matrix[0] + t.Matrix[2]*other.Matrix[1],
t.Matrix[1]*other.Matrix[0] + t.Matrix[3]*other.Matrix[1],
t.Matrix[0]*other.Matrix[2] + t.Matrix[2]*other.Matrix[3],
t.Matrix[1]*other.Matrix[2] + t.Matrix[3]*other.Matrix[3],
},
Translation: [2]float32{
t.Matrix[0]*other.Translation[0] +
t.Matrix[2]*other.Translation[1] +
t.Translation[0],
t.Matrix[1]*other.Translation[0] +
t.Matrix[3]*other.Translation[1] +
t.Translation[1],
},
}
}
type Float16 = uint16
// Float16bits converts a float32 to IEEE-754 binary16 format represented as the bits of a u16.
// This implementation was adapted from Fabian Giesen's `float_to_half_fast3`()
// function which can be found at <https://gist.github.com/rygorous/2156668#file-gistfile1-cpp-L285>
func Float16bits(val float32) Float16 {
const inf32 uint32 = 255 << 23
const inf16 uint32 = 31 << 23
const magic uint32 = 15 << 23
const signMask uint32 = 0x8000_0000
const roundMask uint32 = ^uint32(0xFFF)
u := math.Float32bits(val)
sign := u & signMask
u = u ^ sign
// NOTE all the integer compares in this function can be safely
// compiled into signed compares since all operands are below
// 0x80000000. Important if you want fast straight SSE2 code
// (since there's no unsigned PCMPGTD).
// Inf or NaN (all exponent bits set)
var output uint16
if u >= inf32 {
// NaN -> qNaN and Inf->Inf
if u > inf32 {
output = 0x7E00
} else {
output = 0x7C00
}
} else {
// (De)normalized number or zero
u := u & roundMask
u = math.Float32bits(math.Float32frombits(u) * math.Float32frombits(magic))
u = u - roundMask
// Clamp to signed infinity if exponent overflowed
if u > inf16 {
u = inf16
}
output = uint16(u >> 13) // Take the bits!
}
return output | uint16(sign>>16)
}
// Float16frombits converts a 16-bit precision IEEE-754 binary16 float to float32.
//
// This implementation was adapted from Fabian Giesen's `half_to_float()`
// function which can be found at <https://gist.github.com/rygorous/2156668#file-gistfile1-cpp-L574>
func Float16frombits(val Float16) float32 {
bits := uint32(val)
const magic uint32 = 113 << 23
const shiftedExp uint32 = 0x7c00 << 13 // exponent mask after shift
o := (bits & 0x7fff) << 13 // exponent/mantissa bits
exp := shiftedExp & o // just the exponent
o += (127 - 15) << 23 // exponent adjust
// handle exponent special cases
switch exp {
case shiftedExp:
// Inf/NaN?
o += (128 - 16) << 23 // extra exp adjust
case 0:
// Zero/Denormal?
o += 1 << 23 // extra exp adjust
o = math.Float32bits(math.Float32frombits(o) - math.Float32frombits(magic)) // normalize
}
return math.Float32frombits(o | ((bits & 0x8000) << 16)) // sign bit
}
func TransformFromKurbo(transform curve.Affine) Transform {
c := transform.Coefficients()
return Transform{
Matrix: [4]float32{float32(c[0]), float32(c[1]), float32(c[2]), float32(c[3])},
Translation: [2]float32{float32(c[4]), float32(c[5])},
}
}
func AlignUp[Int constraints.Integer](len Int, alignment Int) Int {
return (len + alignment - 1) & -alignment
}
func PointToF32(p curve.Point) [2]float32 {
return [2]float32{
float32(p.X),
float32(p.Y),
}
}