aboutsummaryrefslogtreecommitdiff
path: root/examples/vectors/vectors.tm
blob: 3f07e500b771c764000cc0b90df1efe8d33ddb2f (plain)
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
# A math vector library for 2D and 3D vectors of Nums or Ints

struct Vec2(x,y:Num):
    ZERO := Vec2(0, 0)
    func plus(a,b:Vec2->Vec2; inline):
        return Vec2(a.x+b.x, a.y+b.y)
    func minus(a,b:Vec2->Vec2; inline):
        return Vec2(a.x-b.x, a.y-b.y)
    func times(a,b:Vec2->Vec2; inline):
        return Vec2(a.x*b.x, a.y*b.y)
    func negative(v:Vec2->Vec2; inline):
        return Vec2(-v.x, -v.y)
    func dot(a,b:Vec2->Num; inline):
        return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)
    func cross(a,b:Vec2->Num; inline):
        return a.x*b.y - a.y*b.x
    func scaled_by(v:Vec2, k:Num->Vec2; inline):
        return Vec2(v.x*k, v.y*k)
    func divided_by(v:Vec2, divisor:Num->Vec2; inline):
        return Vec2(v.x/divisor, v.y/divisor)
    func length(v:Vec2->Num; inline):
        return (v.x*v.x + v.y*v.y)!:sqrt()
    func dist(a,b:Vec2->Num; inline):
        return a:minus(b):length()
    func angle(v:Vec2->Num; inline):
        return Num.atan2(v.y, v.x)
    func norm(v:Vec2->Vec2; inline):
        if v.x == 0 and v.y == 0:
            return v
        len := v:length()
        return Vec2(v.x/len, v.y/len)
    func rotated(v:Vec2, radians:Num -> Vec2):
        cos := radians:cos() or return v
        sin := radians:sin() or return v
        return Vec2(cos*v.x - sin*v.y, sin*v.x + cos*v.y)
    func mix(a,b:Vec2, amount:Num -> Vec2):
        return Vec2(
            amount:mix(a.x, b.x),
            amount:mix(a.y, b.y),
        )

struct Vec3(x,y,z:Num):
    ZERO := Vec3(0, 0, 0)
    func plus(a,b:Vec3->Vec3; inline):
        return Vec3(a.x+b.x, a.y+b.y, a.z+b.z)
    func minus(a,b:Vec3->Vec3; inline):
        return Vec3(a.x-b.x, a.y-b.y, a.z-b.z)
    func times(a,b:Vec3->Vec3; inline):
        return Vec3(a.x*b.x, a.y*b.y, a.z*b.z)
    func negative(v:Vec3->Vec3; inline):
        return Vec3(-v.x, -v.y, -v.z)
    func dot(a,b:Vec3->Num; inline):
        return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z)
    func cross(a,b:Vec3->Vec3; inline):
        return Vec3(a.y*b.z - a.z-b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x)
    func scaled_by(v:Vec3, k:Num->Vec3; inline):
        return Vec3(v.x*k, v.y*k, v.z*k)
    func divided_by(v:Vec3, divisor:Num->Vec3; inline):
        return Vec3(v.x/divisor, v.y/divisor, v.z/divisor)
    func length(v:Vec3->Num; inline):
        return (v.x*v.x + v.y*v.y + v.z*v.z)!:sqrt()
    func dist(a,b:Vec3->Num; inline):
        return a:minus(b):length()
    func norm(v:Vec3->Vec3; inline):
        if v.x == 0 and v.y == 0 and v.z == 0:
            return v
        len := v:length()
        return Vec3(v.x/len, v.y/len, v.z/len)
    func mix(a,b:Vec3, amount:Num -> Vec3):
        return Vec3(
            amount:mix(a.x, b.x),
            amount:mix(a.y, b.y),
            amount:mix(a.z, b.z),
        )


struct IVec2(x,y:Int):
    ZERO := IVec2(0, 0)
    func plus(a,b:IVec2->IVec2; inline):
        return IVec2(a.x+b.x, a.y+b.y)
    func minus(a,b:IVec2->IVec2; inline):
        return IVec2(a.x-b.x, a.y-b.y)
    func times(a,b:IVec2->IVec2; inline):
        return IVec2(a.x*b.x, a.y*b.y)
    func negative(v:IVec2->IVec2; inline):
        return IVec2(-v.x, -v.y)
    func dot(a,b:IVec2->Int; inline):
        return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)
    func cross(a,b:IVec2->Int; inline):
        return a.x*b.y - a.y*b.x
    func scaled_by(v:IVec2, k:Int->IVec2; inline):
        return IVec2(v.x*k, v.y*k)
    func divided_by(v:IVec2, divisor:Int->IVec2; inline):
        return IVec2(v.x/divisor, v.y/divisor)
    func length(v:IVec2->Num; inline):
        x := Num(v.x)
        y := Num(v.y)
        return Num.sqrt(x*x + y*y)
    func dist(a,b:IVec2->Num; inline):
        return a:minus(b):length()
    func angle(v:IVec2->Num; inline):
        return Num.atan2(Num(v.y), Num(v.x))

struct IVec3(x,y,z:Int):
    ZERO := IVec3(0, 0, 0)
    func plus(a,b:IVec3->IVec3; inline):
        return IVec3(a.x+b.x, a.y+b.y, a.z+b.z)
    func minus(a,b:IVec3->IVec3; inline):
        return IVec3(a.x-b.x, a.y-b.y, a.z-b.z)
    func times(a,b:IVec3->IVec3; inline):
        return IVec3(a.x*b.x, a.y*b.y, a.z*b.z)
    func negative(v:IVec3->IVec3; inline):
        return IVec3(-v.x, -v.y, -v.z)
    func dot(a,b:IVec3->Int; inline):
        return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z)
    func cross(a,b:IVec3->IVec3; inline):
        return IVec3(a.y*b.z - a.z-b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x)
    func scaled_by(v:IVec3, k:Int->IVec3; inline):
        return IVec3(v.x*k, v.y*k, v.z*k)
    func divided_by(v:IVec3, divisor:Int->IVec3; inline):
        return IVec3(v.x/divisor, v.y/divisor, v.z/divisor)
    func length(v:IVec3->Num; inline):
        x := Num(v.x)
        y := Num(v.y)
        z := Num(v.z)
        return Num.sqrt(x*x + y*y + z*z)
    func dist(a,b:IVec3->Num; inline):
        return a:minus(b):length()

func main():
    >> Vec2(10, 20)
    >> Vec2(10, 20) + Vec2(100, 100)
    = Vec2(x=110, y=120)
    >> Vec3(10, 20, 30)
    >> Vec2.ZERO