-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
line.go
82 lines (68 loc) · 1.76 KB
/
line.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
package normals
import (
"image/color"
"image/draw"
"math"
"github.com/EliCDavis/vector/vector2"
"github.com/EliCDavis/vector/vector3"
)
type Line struct {
Start vector2.Float64
End vector2.Float64
Width float64
NormalDirection Direction
}
func (l Line) normalLine(src draw.Image, start, end vector2.Float64) {
line := end.Sub(start)
len := line.Length()
dir := line.Normalized()
// a = center.X()
// b := 0
// c := 0
// r := len
circleYMultiplier := 1.
if l.NormalDirection == Subtractive {
circleYMultiplier = -1
}
// Equation of a Sphere
// (x - a)^2 + (y - b)^2 + (z - c)^2 = r^2
// (y - b)^2 = r^2 - (x - a)^2 - (z - c)^2
// y - b = math.sqrt(r^2 - (x - a)^2 - (z - c)^2)
// y = math.sqrt(r^2 - (x - a)^2 - (z - c)^2) + b
// y = math.sqrt(r^2 - (x - a)^2)
rr := len * len
for i := len; i >= 0; i -= 0.5 {
p := dir.Scale(i)
circleY := math.Sqrt(rr-(i*i)) * circleYMultiplier
pixNormal := vector3.New(p.X(), circleY, p.Y()).
Normalized().
MultByVector(vector3.Fill(circleYMultiplier)).
Scale(127).
Clamp(-128, 127).
RoundToInt()
c := color.RGBA{
R: byte(128 + pixNormal.X()),
G: byte(128 - pixNormal.Z()),
B: byte(128 + pixNormal.Y()),
A: 255,
}
pix := start.Add(dir.Scale(i)).FloorToInt()
src.Set(pix.X(), pix.Y(), c)
}
}
// Dir is end point - starting point
func (l Line) Dir() vector2.Float64 {
return l.End.Sub(l.Start)
}
func (l Line) Round(src draw.Image) {
dir := l.Dir()
n := dir.Normalized()
perp := n.Perpendicular().Scale(l.Width / 2)
length := dir.Length()
start := l.Start
for i := 0.; i < length; i += 0.5 {
newStart := start.Add(n.Scale(float64(i)))
l.normalLine(src, newStart, newStart.Add(perp))
l.normalLine(src, newStart, newStart.Sub(perp))
}
}