Skip to content

Commit fce5f89

Browse files
committed
First working version of Math::Vector.
1 parent 08622a8 commit fce5f89

File tree

4 files changed

+90
-82
lines changed

4 files changed

+90
-82
lines changed

CREDITS

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
Vector was originally written by "SF" (http://lastofthecarelessmen.blogspot.com/).
1+
Vector was originally written by "SF" (http://lastofthecarelessmen.blogspot.com/)
2+
last.of.the.careless.men@gmail.com
23

3-
Solomon Foster (Rakudo * port)
4+
Solomon Foster (Rakudo * port, switch to Math::Vector)
5+
colomon@gmail.com

README

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
This is a simple attempt to create a working Vector class. Initially intended
2+
to support 3D vectors, it turned out to be easier to support vectors of
3+
any dimension.
4+
5+
Math::Vector requires Rakudo from 7/25/2010 or later.
6+
7+
Build sequence:
8+
9+
ufo
10+
make
11+
make test
12+

lib/Math/Vector.pm

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ class Math::Vector
3636
@.coordinates.elems;
3737
}
3838

39-
our multi sub infix:<>(Vector $a, Vector $b where { $a.Dim == $b.Dim }) is export(:DEFAULT) # is tighter(&infix:<+>) (NYI)
39+
our multi sub infix:<>(Math::Vector $a, Math::Vector $b where { $a.Dim == $b.Dim }) is export(:DEFAULT) # is tighter(&infix:<+>) (NYI)
4040
{
4141
[+]($a.coordinates »*« $b.coordinates);
4242
}
4343

44-
our multi sub infix:<dot>(Vector $a, Vector $b) is export(:DEFAULT)
44+
our multi sub infix:<dot>(Math::Vector $a, Math::Vector $b) is export(:DEFAULT)
4545
{
4646
$a$b;
4747
}
@@ -61,54 +61,54 @@ class Math::Vector
6161
my $length = self.Length;
6262
if $length > 1e-10
6363
{
64-
return Vector.new(@.coordinates >>/>> $length);
64+
return Math::Vector.new(@.coordinates >>/>> $length);
6565
}
6666
else
6767
{
68-
return Vector.new(@.coordinates);
68+
return Math::Vector.new(@.coordinates);
6969
}
7070
}
7171

72-
multi sub infix:<+> (Vector $a, Vector $b where { $a.Dim == $b.Dim }) is export(:DEFAULT)
72+
multi sub infix:<+> (Math::Vector $a, Math::Vector $b where { $a.Dim == $b.Dim }) is export(:DEFAULT)
7373
{
74-
Vector.new($a.coordinates »+« $b.coordinates);
74+
Math::Vector.new($a.coordinates »+« $b.coordinates);
7575
}
7676

77-
multi sub infix:<->(Vector $a, Vector $b where { $a.Dim == $b.Dim }) is export(:DEFAULT)
77+
multi sub infix:<->(Math::Vector $a, Math::Vector $b where { $a.Dim == $b.Dim }) is export(:DEFAULT)
7878
{
79-
Vector.new($a.coordinates »-« $b.coordinates);
79+
Math::Vector.new($a.coordinates »-« $b.coordinates);
8080
}
8181

82-
multi sub prefix:<->(Vector $a) is export(:DEFAULT)
82+
multi sub prefix:<->(Math::Vector $a) is export(:DEFAULT)
8383
{
84-
Vector.new(0 <<-<< $a.coordinates);
84+
Math::Vector.new(0 <<-<< $a.coordinates);
8585
}
8686

87-
multi sub infix:<*>(Vector $a, $b) is export(:DEFAULT)
87+
multi sub infix:<*>(Math::Vector $a, $b) is export(:DEFAULT)
8888
{
89-
Vector.new($a.coordinates >>*>> $b);
89+
Math::Vector.new($a.coordinates >>*>> $b);
9090
}
9191

92-
multi sub infix:<*>($a, Vector $b) is export(:DEFAULT)
92+
multi sub infix:<*>($a, Math::Vector $b) is export(:DEFAULT)
9393
{
94-
Vector.new($a <<*<< $b.coordinates);
94+
Math::Vector.new($a <<*<< $b.coordinates);
9595
}
9696

97-
multi sub infix:</>(Vector $a, $b) is export(:DEFAULT)
97+
multi sub infix:</>(Math::Vector $a, $b) is export(:DEFAULT)
9898
{
99-
Vector.new($a.coordinates >>/>> $b);
99+
Math::Vector.new($a.coordinates >>/>> $b);
100100
}
101101

102-
multi sub infix:<×>(Vector $a where { $a.Dim == 3 }, Vector $b where { $b.Dim == 3 }) is export(:DEFAULT)
102+
multi sub infix:<×>(Math::Vector $a where { $a.Dim == 3 }, Math::Vector $b where { $b.Dim == 3 }) is export(:DEFAULT)
103103
{
104-
Vector.new($a.coordinates[1] * $b.coordinates[2] - $a.coordinates[2] * $b.coordinates[1],
104+
Math::Vector.new($a.coordinates[1] * $b.coordinates[2] - $a.coordinates[2] * $b.coordinates[1],
105105
$a.coordinates[2] * $b.coordinates[0] - $a.coordinates[0] * $b.coordinates[2],
106106
$a.coordinates[0] * $b.coordinates[1] - $a.coordinates[1] * $b.coordinates[0]);
107107
}
108108

109-
multi sub infix:<×>(Vector $a where { $a.Dim == 7 }, Vector $b where { $b.Dim == 7 }) is export(:DEFAULT)
109+
multi sub infix:<×>(Math::Vector $a where { $a.Dim == 7 }, Math::Vector $b where { $b.Dim == 7 }) is export(:DEFAULT)
110110
{
111-
Vector.new($a.coordinates[1] * $b.coordinates[3] - $a.coordinates[3] * $b.coordinates[1]
111+
Math::Vector.new($a.coordinates[1] * $b.coordinates[3] - $a.coordinates[3] * $b.coordinates[1]
112112
+ $a.coordinates[2] * $b.coordinates[6] - $a.coordinates[6] * $b.coordinates[2]
113113
+ $a.coordinates[4] * $b.coordinates[5] - $a.coordinates[5] * $b.coordinates[4],
114114
$a.coordinates[2] * $b.coordinates[4] - $a.coordinates[4] * $b.coordinates[2]
@@ -131,25 +131,20 @@ class Math::Vector
131131
+ $a.coordinates[3] * $b.coordinates[4] - $a.coordinates[4] * $b.coordinates[3]);
132132
}
133133

134-
multi sub infix:<cross>(Vector $a, Vector $b) is export(:DEFAULT)
134+
multi sub infix:<cross>(Math::Vector $a, Math::Vector $b) is export(:DEFAULT)
135135
{
136136
$a × $b;
137137
}
138138

139-
multi sub circumfix:<⎡ ⎤>(Vector $a) is export(:DEFAULT)
139+
multi sub circumfix:<⎡ ⎤>(Math::Vector $a) is export(:DEFAULT)
140140
{
141141
$a.Length;
142142
}
143143

144-
sub is_approx_vector(Vector $a, Vector $b, $desc) is export(:DEFAULT)
144+
sub is_approx_vector(Math::Vector $a, Math::Vector $b, $desc) is export(:DEFAULT)
145145
{
146146
ok(($a - $b).Length < 0.00001, $desc);
147147
}
148148
}
149149

150-
# multi sub prefix:<+>(Vector $a)
151-
# {
152-
# $a;
153-
# }
154-
155-
subset UnitVector of Vector where { (1 - 1e-10) < $^v.Length < (1 + 1e-10) };
150+
subset Math::UnitVector of Math::Vector where { (1 - 1e-10) < $^v.Length < (1 + 1e-10) };

t/01-basics.t

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
use v6;
2-
use Vector;
2+
use Math::Vector;
33
use Test;
44

55
plan *;
66

7-
my $v1 = Vector.new(1, 2, 3);
8-
my Vector $v2 = Vector.new(3, 4, 0);
7+
my $v1 = Math::Vector.new(1, 2, 3);
8+
my Math::Vector $v2 = Math::Vector.new(3, 4, 0);
99
my @v3 = (-1, 0, 2);
10-
my Vector $v3 = Vector.new(@v3);
11-
my Vector $origin3d = Vector.new(0, 0, 0);
12-
my Vector $v5 = Vector.new(1,2,3,4,5);
13-
my Vector $v6 = Vector.new(0,0,1,0,0);
14-
my Vector $v7 = Vector.new(1,0,0,0,0,0,0);
15-
my Vector $v8 = Vector.new(0,1,0,0,0,0,0);
16-
my Vector $v9 = Vector.new(1..7);
17-
my Vector $v10 = Vector.new(10,20,1,10,20,10,30);
18-
my Vector $vcrazy = Vector.new(Vector.new(1, 2, 3), Vector.new(-1, 0, -1));
10+
my Math::Vector $v3 = Math::Vector.new(@v3);
11+
my Math::Vector $origin3d = Math::Vector.new(0, 0, 0);
12+
my Math::Vector $v5 = Math::Vector.new(1,2,3,4,5);
13+
my Math::Vector $v6 = Math::Vector.new(0,0,1,0,0);
14+
my Math::Vector $v7 = Math::Vector.new(1,0,0,0,0,0,0);
15+
my Math::Vector $v8 = Math::Vector.new(0,1,0,0,0,0,0);
16+
my Math::Vector $v9 = Math::Vector.new(1..7);
17+
my Math::Vector $v10 = Math::Vector.new(10,20,1,10,20,10,30);
18+
my Math::Vector $vcrazy = Math::Vector.new(Math::Vector.new(1, 2, 3), Math::Vector.new(-1, 0, -1));
1919

2020
my @vectors = ($v1, $v2, $v3, $origin3d, $v5, $v6, $v7, $v8, $v9, $v10);
2121

22-
isa_ok($v1, Vector, "Variable is of type Vector");
23-
isa_ok($v2, Vector, "Variable is of type Vector");
24-
isa_ok($v3, Vector, "Variable is of type Vector");
25-
isa_ok($v5, Vector, "Variable is of type Vector");
26-
isa_ok($v7, Vector, "Variable is of type Vector");
27-
isa_ok($vcrazy, Vector, "Variable is of type Vector");
22+
isa_ok($v1, Math::Vector, "Variable is of type Math::Vector");
23+
isa_ok($v2, Math::Vector, "Variable is of type Math::Vector");
24+
isa_ok($v3, Math::Vector, "Variable is of type Math::Vector");
25+
isa_ok($v5, Math::Vector, "Variable is of type Math::Vector");
26+
isa_ok($v7, Math::Vector, "Variable is of type Math::Vector");
27+
isa_ok($vcrazy, Math::Vector, "Variable is of type Math::Vector");
2828

2929
is(~$v1, "(1, 2, 3)", "Stringify works");
3030
is(~$v3, "(-1, 0, 2)", "Stringify works");
@@ -36,11 +36,11 @@ is(~eval($v1.perl), ~$v1, ".perl works");
3636
is(~eval($v9.perl), ~$v9, ".perl works");
3737
is(~eval($vcrazy.perl), ~$vcrazy, ".perl works");
3838

39-
is($v1.Dim, 3, "Dim works for 3D Vector");
40-
is($v5.Dim, 5, "Dim works for 5D Vector");
41-
is($v7.Dim, 7, "Dim works for 7D Vector");
39+
is($v1.Dim, 3, "Dim works for 3D Math::Vector");
40+
is($v5.Dim, 5, "Dim works for 5D Math::Vector");
41+
is($v7.Dim, 7, "Dim works for 7D Math::Vector");
4242

43-
is_approx($v7$v8, 0, "Perpendicular vectors have 0 dot product");
43+
is_approx($v7$v8, 0, "Perpendicular Math::Vectors have 0 dot product");
4444

4545

4646
#basic math tests
@@ -51,7 +51,7 @@ is(($v1 + $v2) + $v3, $v1 + ($v2 + $v3), "Addition is associative");
5151
is($v1 + $origin3d, $v1, "Addition with origin leaves original");
5252

5353
# {
54-
# my Vector $a = $v1;
54+
# my Math::Vector $a = $v1;
5555
# $a += $v2;
5656
# is(~($v1 + $v2), ~$a, "+= works");
5757
# }
@@ -63,7 +63,7 @@ is($v1 - $origin3d, $v1, "Subtracting the origin leaves original");
6363
is(-$origin3d, $origin3d, "Negating the origin leaves the origin");
6464
is(~(-$v2), "(-3, -4, 0)", "Negating works");
6565
# {
66-
# my Vector $a = $v1;
66+
# my Math::Vector $a = $v1;
6767
# $a -= $v2;
6868
# is(~($v1 - $v2), ~$a, "+= works");
6969
# }
@@ -82,22 +82,22 @@ for @vectors -> $v
8282

8383
for @vectors -> $v
8484
{
85-
my Vector $vn = $v * 4.5;
86-
is_approx($vn.Length, $v.Length * 4.5, "Scalar by Vector multiply gets proper length");
87-
is_approx_vector($vn.Unitize, $v.Unitize, "Scalar by Vector multiply gets proper direction");
88-
is_approx_vector($vn, 4.5 * $v, "Scalar by Vector multiply is commutative");
85+
my Math::Vector $vn = $v * 4.5;
86+
is_approx($vn.Length, $v.Length * 4.5, "Scalar by Math::Vector multiply gets proper length");
87+
is_approx_vector($vn.Unitize, $v.Unitize, "Scalar by Math::Vector multiply gets proper direction");
88+
is_approx_vector($vn, 4.5 * $v, "Scalar by Math::Vector multiply is commutative");
8989
}
9090

9191
for @vectors -> $v
9292
{
93-
my Vector $vn = $v / 4.5;
94-
is_approx($vn.Length, $v.Length / 4.5, "Vector by Scalar divide gets proper length");
95-
is_approx_vector($vn.Unitize, $v.Unitize, "Vector by Scalar divide gets proper direction");
96-
is_approx_vector($vn, $v * (1.0 / 4.5), "Vector by Scalar divide is equal to multiplication by reciprocal");
93+
my Math::Vector $vn = $v / 4.5;
94+
is_approx($vn.Length, $v.Length / 4.5, "Math::Vector by Scalar divide gets proper length");
95+
is_approx_vector($vn.Unitize, $v.Unitize, "Math::Vector by Scalar divide gets proper direction");
96+
is_approx_vector($vn, $v * (1.0 / 4.5), "Math::Vector by Scalar divide is equal to multiplication by reciprocal");
9797
}
9898

9999
#dot product tests
100-
is_approx($v7 dot $v8, 0, "Perpendicular vectors have 0 dot product");
100+
is_approx($v7 dot $v8, 0, "Perpendicular Math::Vectors have 0 dot product");
101101

102102
for ($v1, $v2, $v3) X ($v1, $v2, $v3) -> $x, $y
103103
{
@@ -121,8 +121,8 @@ dies_ok( { $v7 dot $v5 }, "You can't do dot products of different dimensions");
121121
# }
122122

123123
# {
124-
# my Vector $a = $v1;
125-
# dies_ok( { $a ⋅= $v2; }, "You can't do dot= on a Vector variable");
124+
# my Math::Vector $a = $v1;
125+
# dies_ok( { $a ⋅= $v2; }, "You can't do dot= on a Math::Vector variable");
126126
# }
127127

128128
#cross product tests
@@ -160,30 +160,29 @@ dies_ok( { $v5 cross $v6 }, "You can't do 5D cross products");
160160
# is_approx($v1 × $v2, $a, "×= works");
161161
# }
162162

163-
# UnitVector tests
164-
{
165-
my UnitVector $a = Vector.new(1, 0, 0);
166-
# isa_ok($a, UnitVector, "Variable is of type UnitVector");
167-
isa_ok($a, Vector, "Variable is of type Vector");
168-
}
163+
# Math::UnitVector tests
164+
# {
165+
# my Math::UnitVector $a = Math::Vector.new(1, 0, 0);
166+
# isa_ok($a, Math::Vector, "Variable is of type Math::Vector");
167+
# }
169168

170169
# {
171-
# my UnitVector $a = UnitVector.new(1, 0, 0);
170+
# my Math::UnitVector $a = Math::UnitVector.new(1, 0, 0);
172171
# my $b = $a;
173172
# $b += $v2;
174-
# is_approx($a + $v2, $b, "+= works on UnitVector");
173+
# is_approx($a + $v2, $b, "+= works on Math::UnitVector");
175174
# }
176175
# {
177-
# my UnitVector $a = Vector.new(1, 0, 0);
178-
# dies_ok( { $a += $v2; }, "Catch if += violates the UnitVector constraint");
176+
# my Math::UnitVector $a = Math::Vector.new(1, 0, 0);
177+
# dies_ok( { $a += $v2; }, "Catch if += violates the Math::UnitVector constraint");
179178
# }
180179

181180
# test prefix plus
182-
# isa_ok(+$v1, Vector, "Prefix + works on the Vector class");
183-
dies_ok( { $v1.Num; }, "Make sure .Num does not work on 3D vector");
181+
# isa_ok(+$v1, Math::Vector, "Prefix + works on the Math::Vector class");
182+
dies_ok( { $v1.Num; }, "Make sure .Num does not work on 3D Math::Vector");
184183

185184
# test extensions
186-
class VectorWithLength is Vector
185+
class Math::VectorWithLength is Math::Vector
187186
{
188187
has $.length;
189188

@@ -203,9 +202,9 @@ class VectorWithLength is Vector
203202
}
204203
}
205204

206-
my VectorWithLength $vl = VectorWithLength.new($v7.coordinates);
207-
isa_ok($vl, VectorWithLength, "Variable is of type VectorWithLength");
205+
my Math::VectorWithLength $vl = Math::VectorWithLength.new($v7.coordinates);
206+
isa_ok($vl, Math::VectorWithLength, "Variable is of type Math::VectorWithLength");
208207
my $vlc = eval($vl.perl);
209-
isa_ok($vlc, VectorWithLength, "eval'd perl'd variable is of type VectorWithLength");
208+
isa_ok($vlc, Math::VectorWithLength, "eval'd perl'd variable is of type Math::VectorWithLength");
210209

211210
done_testing;

0 commit comments

Comments
 (0)