Skip to content

Commit a342cc7

Browse files
committed
Add libvector
1 parent 2f838a4 commit a342cc7

File tree

5 files changed

+295
-11
lines changed

5 files changed

+295
-11
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Go to the programs' directories to get the docs and the information on what the
1414
* `camera` — a program that can draw what the Computronics' camera sees.
1515
* `libthread` — an easy-to-use multithreading library.
1616
* `libqr` — a QR code generator library.
17+
* `libvector` — a vector library.
1718

1819

1920
## A not-so-important-but-good-to-know message

libvector/.vector.lua.swp

16 KB
Binary file not shown.

libvector/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# libvector
2+
3+
This library provides mathematical vectors with unlimited amount of dimensions.
4+
5+
## Authors
6+
* Ktlo
7+
8+
## Description
9+
The library returns the function that's called like this: `vector(x: number, y: number, z: number, ...)`.
10+
11+
A vector stores dimensions (and corresponding values) in a table. Each vector also has the `n` field, the amount of dimensions.
12+
13+
```lua
14+
local vector = require("vector")
15+
local a = vector(1, 5, 89, 6)
16+
print(a.n)
17+
--> 4
18+
```
19+
20+
All methods create a new vector instead of overriding the old one.
21+
22+
### Arithmetic operations
23+
```lua
24+
local vector = require("vector")
25+
local a = vector(5, 8, 9)
26+
local b = vector(78, 3, -13, 56)
27+
28+
print(a + b)
29+
--> {83; 11; -4; 56}
30+
31+
print(a - b)
32+
--> {-73; 5; 22; -56}
33+
34+
print(a * 8) -- we could also write this as 8 * a
35+
--> {40; 64; 72}
36+
37+
print(b / 42)
38+
--> {1.857; 0.071; -0.310; 1.333}
39+
40+
print(a * b) -- cross product
41+
--> {-131; 767; -609}
42+
43+
print(a == b)
44+
--> false
45+
46+
print(#a, #b) -- vector lengths
47+
--> 13.038404810405 96.943282387177
48+
```
49+
50+
### Methods
51+
* `vector:tostring([precision: number])` — the same as `tostring(vector)`, but also accepts the optional decimal precision (3 by default).
52+
* `vector:add(vector2: table): table` — the same as `vector + vector2`.
53+
* `vector:sub(vector2: table): table` — the same as `vector - vector2`.
54+
* `vector:mul(vector2: table): table` — the same as `vector * vector2`.
55+
* `vector:div(number: number): table` — the same as `vector / number`.
56+
* `vector:len(): number` — the same as `#vector`.
57+
* `vector:dot(vector2: table): number` — the dot product.
58+
* `vector:cross(vector2: table): table` — the cross product.
59+
* `vector:normalize(): table` — returns the normalized vector.
60+
* `vector:angle(vector2: table): number` — returns the angle between vectors (in radians).
61+
* `vector:round(): table` — rounds the vector.
62+
* `vector:eq(vector2: table): boolean` — the same as `vector == vector2`.
63+
64+
## Links
65+
* [**Pastebin**](http://pastebin.com/mdfDvmps)
66+
* [The topic on the Russian forums](http://computercraft.ru/topic/1106-)

libvector/vector.lua

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
local math = require "math"
2+
local concat = require "table".concat
3+
local format = require "string".format
4+
local setmetatable = setmetatable
5+
local type, error = type, error
6+
local rawset, rawget = rawset, rawget
7+
8+
-- One of those cases where you really miss the "using" keyword.
9+
local pow, sqrt, max, floor, acos, sin, cos, modf, pi = math.pow, math.sqrt, math.max, math.floor, math.acos, math.sin, math.cos, math.modf, math.pi
10+
math = nil
11+
12+
local vector
13+
14+
local function check(o) -- Vector type check
15+
local t = type(o)
16+
if not (t == "table" and o.object == "vector") then
17+
error("attempt to perform arithmetic on a "..t.." value", 3)
18+
end
19+
end
20+
21+
local __index = {
22+
tostring = function(self, f)
23+
f = type(f) == "number" and f >= 0 and f or 3
24+
f = "%."..f.."f"
25+
local r = { }
26+
for i = 1, self.n do
27+
local n = self[i]
28+
r[i] = format(modf(n) == n and "%1d" or f, n)
29+
end
30+
return "{"..concat(r, "; ").."}"
31+
end;
32+
33+
add = function(a, b)
34+
check(a)
35+
check(b)
36+
local v = { }
37+
for i = 1, max(a.n, b.n) do
38+
v[i] = (a[i] or 0) + (b[i] or 0)
39+
end
40+
return vector(v)
41+
end;
42+
43+
sub = function(a, b)
44+
check(a)
45+
check(b)
46+
local v = { }
47+
for i = 1, max(a.n, b.n) do
48+
v[i] = (a[i] or 0) - (b[i] or 0)
49+
end
50+
return vector(v)
51+
end;
52+
53+
mul = function(a, b)
54+
local t1 = type(a)
55+
local t2 = type(b)
56+
local v = { }
57+
if t1 == "number" then
58+
check(b)
59+
for i = 1, b.n do
60+
v[i] = b[i] * a
61+
end
62+
elseif t2 == "number" then
63+
check(a)
64+
for i = 1, a.n do
65+
v[i] = a[i] * b
66+
end
67+
else
68+
check(a)
69+
check(b)
70+
v = a:cross(b)
71+
end
72+
return vector(v)
73+
end;
74+
75+
div = function(a, b)
76+
check(a)
77+
local t = type(b)
78+
if t ~= "number" then
79+
error("attempt to perform arithmetic on a "..t.." value", 3)
80+
end
81+
local v = { }
82+
for i = 1, a.n do
83+
v[i] = a[i] / b
84+
end
85+
return vector(v)
86+
end;
87+
88+
len = function(self)
89+
local r = 0
90+
for i = 1, self.n do
91+
r = r + pow(self[i], 2)
92+
end
93+
return sqrt(r)
94+
end;
95+
96+
dot = function(a, b)
97+
check(a)
98+
check(b)
99+
local r = 0
100+
for i = 1, max(a.n, b.n) do
101+
r = r + (a[i] or 0) * (b[i] or 0)
102+
end
103+
return r
104+
end;
105+
106+
cross = function(a, b)
107+
check(a)
108+
check(b)
109+
local v = {
110+
(a[2] or 0) * (b[3] or 0) - (a[3] or 0) * (b[2] or 0);
111+
(a[3] or 0) * (b[1] or 0) - (a[1] or 0) * (b[3] or 0);
112+
(a[1] or 0) * (b[2] or 0) - (a[2] or 0) * (b[1] or 0);
113+
}
114+
return vector(v)
115+
end;
116+
117+
normalize = function(self)
118+
return self / #self
119+
end;
120+
121+
angle = function(a, b)
122+
check(a)
123+
check(b)
124+
a, b = a:normalize(), b:normalize()
125+
return acos(a:dot(b))
126+
end;
127+
128+
rotate = function(v, g, a, b)
129+
local r = { }
130+
local c, s = cos(g), sin(g)
131+
for i = 1, v.n do
132+
r[i] = i == a and v[a] * c - v[b] * s or b == i and v[a] * s + v[b] * c or v[i]
133+
end
134+
return vector(r)
135+
end;
136+
137+
round = function(self, d)
138+
local v = { }
139+
d = type(d) == "number" and d or 0.5
140+
for i = 1, self.n do
141+
local a, b = modf(self[i])
142+
v[i] = b < d and a or a + 1
143+
end
144+
return vector(v)
145+
end;
146+
147+
eq = function(a, b)
148+
if not (type(a) == "table" and a.object == "vector") or not (type(a) == "table" and a.object == "vector") then
149+
return false
150+
end
151+
local r = true
152+
for i = 1, max(a.n, b.n) do
153+
if a[i] ~= b[i] then
154+
r = false
155+
break
156+
end
157+
end
158+
return r
159+
end;
160+
161+
object = "vector"; -- Object type
162+
}
163+
164+
local meta = {
165+
__index = __index;
166+
__tostring = __index.tostring;
167+
__add = __index.add;
168+
__sub = __index.sub;
169+
__mul = __index.mul;
170+
__div = __index.div;
171+
__len = __index.len;
172+
__eq = __index.eq;
173+
__newindex = function(self, d, n)
174+
local a = type(d)
175+
local b = type(n)
176+
if not (a == "number" and d == floor(d) and d > 0) then
177+
error("invalid dimension type (signed integer expected, got "..(a == "number" and d ~= floor(d) and "float" or a)..")", 2)
178+
end
179+
if b ~= "number" then
180+
error("invalid coordinate type (number expected, got "..b..")")
181+
end
182+
d = floor(d)
183+
for i = 1, d-1 do
184+
if not rawget(self, i) then
185+
rawset(self, i, 0)
186+
end
187+
end
188+
rawset(self, d, n)
189+
rawset(self, "n", d)
190+
end;
191+
}
192+
193+
vector = function(v) -- Creates a new vector
194+
v.n = #v
195+
return setmetatable(v, meta)
196+
end
197+
198+
return function(...) -- The same as above, but with additional checks
199+
local v = { ... }
200+
for i=1, #v do
201+
local t = type(v[i])
202+
if t ~= "number" then
203+
error("bad argument #"..i.." (number expected, got "..t..")")
204+
end
205+
end
206+
return vector(v)
207+
end

programs.cfg

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
["mc"] = {
33
files = {
44
["master/mc/mc.lua"] = "/bin",
5-
["master/mc/README.md"] = "/share/doc"
5+
["master/mc/README.md"] = "/share/doc/mc"
66
},
77
name = "Midday Commander",
88
description = "A file commander, similar to Midnight Commander and Norton Commander.",
@@ -13,7 +13,7 @@
1313
files = {
1414
["master/holo-editor/holo-editor.lua"] = "/bin",
1515
["master/holo-editor/holo-viewer.lua"] = "/bin",
16-
["master/holo-editor/README.md"] = "/share/doc"
16+
["master/holo-editor/README.md"] = "/share/doc/holo-editor"
1717
},
1818
name = "Hologram Editor and Viewer",
1919
description = "Allows to easily create, edit, and show holograms.",
@@ -23,7 +23,7 @@
2323
["obj"] = {
2424
files = {
2525
["master/obj/obj.lua"] = "/lib",
26-
["master/obj/README.md"] = "/share/doc"
26+
["master/obj/README.md"] = "/share/doc/obj"
2727
},
2828
name = "OBJ",
2929
description = "3D models drawing library for OpenGlasses.",
@@ -33,7 +33,7 @@
3333
["libforms"] = {
3434
files = {
3535
["master/libforms/forms.lua"] = "/lib",
36-
["master/libforms/README.md"] = "/share/doc"
36+
["master/libforms/README.md"] = "/share/doc/libforms"
3737
},
3838
name = "Forms",
3939
description = "A lightweight and easy-to-use GUI library.",
@@ -43,7 +43,7 @@
4343
["lava-runner"] = {
4444
files = {
4545
["master/lava-runner/lava-runner.lua"] = "/bin",
46-
["master/lava-runner/README.md"] = "/share/doc"
46+
["master/lava-runner/README.md"] = "/share/doc/lava-runner"
4747
},
4848
name = "Lava Runner",
4949
description = "A game for OpenComputers, where one needs to find an exit and not to boil in lava.",
@@ -53,7 +53,7 @@
5353
["geomine"] = {
5454
files = {
5555
["master/geomine/geomine.lua"] = "/bin",
56-
["master/geomine/README.md"] = "/share/doc"
56+
["master/geomine/README.md"] = "/share/doc/geomine"
5757
},
5858
name = "GeoMine",
5959
description = "A miner program that uses the Geolyzer to effectively mine the ores.",
@@ -63,7 +63,7 @@
6363
["geoglasses"] = {
6464
files = {
6565
["master/geoglasses/geoglasses.lua"] = "/bin",
66-
["master/geoglasses/README.md"] = "/share/doc"
66+
["master/geoglasses/README.md"] = "/share/doc/geoglasses"
6767
},
6868
name = "GeoGlasses",
6969
description = "A program that searches ores, and other high-density blocks, and highlights them on the OpenGlasses' glasses.",
@@ -73,7 +73,7 @@
7373
["camera"] = {
7474
files = {
7575
["master/camera/camera.lua"] = "/bin",
76-
["master/camera/README.md"] = "/share/doc"
76+
["master/camera/README.md"] = "/share/doc/camera"
7777
},
7878
name = "Camera",
7979
description = "Draws a image that can be seen by the Computronics' camera",
@@ -83,7 +83,7 @@
8383
["libthread"] = {
8484
files = {
8585
["master/libthread/thread.lua"] = "/lib",
86-
["master/libthread/README.md"] = "/share/doc"
86+
["master/libthread/README.md"] = "/share/doc/libthread"
8787
},
8888
name = "A threading library",
8989
description = "Makes it simple to create a program that needs multithreading.",
@@ -93,11 +93,21 @@
9393
["libqr"] = {
9494
files = {
9595
["master/libqr/qr.lua"] = "/lib",
96-
["master/libqr/README.md"] = "/share/doc"
96+
["master/libqr/README.md"] = "/share/doc/libqr"
9797
},
9898
name = "QR code generator",
9999
description = "A QR generator library for OpenComputers.",
100100
authors = "1Ridav",
101101
repo = "tree/master/libqr"
102-
}
102+
},
103+
["libvector"] = {
104+
files = {
105+
["master/libvector/vector.lua"] = "/lib",
106+
["master/libvector/README.md"] = "/share/doc/libvector"
107+
}
108+
},
109+
name = "Vector library",
110+
description = "Provides mathematical vectors.",
111+
authors = "Ktlo",
112+
repo = "tree/master/libvector"
103113
}

0 commit comments

Comments
 (0)