-
Notifications
You must be signed in to change notification settings - Fork 0
/
circle.go
84 lines (72 loc) · 2.09 KB
/
circle.go
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
package geometry
import (
"github.com/boundedinfinity/go-commoner/idiomatic/mather"
"github.com/boundedinfinity/go-commoner/idiomatic/mather/internal"
)
func NewCircle[T geometryNumber](center CartesianCoordinate[T], radius T) Circle[T] {
return Circle[T]{
Center: center,
Radius: radius,
}
}
func NewCircleXY[T geometryNumber](x, y, radius T) Circle[T] {
return NewCircle[T](CartesianCoordinate[T]{X: x, Y: y}, radius)
}
type Circle[T geometryNumber] struct {
Center CartesianCoordinate[T]
Radius T
}
func (t Circle[T]) Diameter() T {
return t.Radius * T(2)
}
func (t Circle[T]) PointOnCircumference(angle Angle[T]) CartesianCoordinate[T] {
var theta T
fn := func(theta float64) float64 { return 360 - theta }
switch angle.Direction {
case AngleDirections.CounterClockwise:
theta = internal.SingleToSingle[T, T](theta, fn)
default:
theta = angle.Magnitude
}
return CartesianCoordinate[T]{
X: internal.TripleToSingle[T](t.Radius, theta, t.Center.X, func(radius, theta, x float64) float64 {
return radius*mather.Cos(theta) + x
}),
Y: internal.TripleToSingle[T](t.Radius, theta, t.Center.Y, func(radius, theta, y float64) float64 {
return radius*mather.Sin(theta) + y
}),
}
}
func (t Circle[T]) PointOnDiameter(percent T) CartesianCoordinate[T] {
leftPoint := t.PointOnCircumference(Angle[T]{Magnitude: 180})
x := leftPoint.X * t.Diameter() * percent
return t.YCoordinate(x)
}
// (x – h)^2 + (y – k)^2 = r^2
//
// (y – k)^2 = r^2 - (x – h)^2
// y – k = √(r^2 - (x – h)^2)
// y = k + √(r^2 - (x – h)^2)
func (t Circle[T]) YCoordinate(x T) CartesianCoordinate[T] {
h := t.Center.X
k := t.Center.Y
r := t.Radius
return CartesianCoordinate[T]{
X: x,
Y: k + mather.Sqrt(mather.Square(r)-mather.Square(x-h)),
}
}
// (x – h)^2 + (y – k)^2 = r^2
//
// (x – h)^2 = r^2 - (y – k)^2
// x - h = √(r^2 - (y – k)^2)
// x = h + √(r^2 - (y – k)^2)
func (t Circle[T]) XCoordinate(y T) CartesianCoordinate[T] {
h := t.Center.X
k := t.Center.Y
r := t.Radius
return CartesianCoordinate[T]{
X: h + mather.Sqrt(mather.Square(r)-mather.Square(y-k)),
Y: y,
}
}