Added tuple implementation
This commit is contained in:
parent
501ae30546
commit
93c5a0809d
116
src/tuple.nim
Normal file
116
src/tuple.nim
Normal file
@ -0,0 +1,116 @@
|
||||
from math import sqrt
|
||||
|
||||
type
|
||||
Tuple4* = object
|
||||
x*, y*, z*, w*: float
|
||||
|
||||
proc point*(x: float, y: float, z: float): Tuple4 = Tuple4(x: x, y: y, z: z, w: 1)
|
||||
|
||||
proc vector*(x: float, y: float, z: float): Tuple4 = Tuple4(x: x, y: y, z: z, w: 0)
|
||||
|
||||
proc isPoint*(target: Tuple4): bool = target.w == 1
|
||||
proc isVector*(target: Tuple4): bool = target.w == 0
|
||||
|
||||
proc `+`*(lhs: Tuple4, rhs: Tuple4): Tuple4 = Tuple4(x: lhs.x + rhs.x, y: lhs.y + rhs.y, z: lhs.z + rhs.z, w: lhs.w + rhs.w)
|
||||
proc `-`*(lhs: Tuple4, rhs: Tuple4): Tuple4 = Tuple4(x: lhs.x - rhs.x, y: lhs.y - rhs.y, z: lhs.z - rhs.z, w: lhs.w - rhs.w)
|
||||
proc `-`*(tup: Tuple4): Tuple4 = Tuple4(x: -tup.x, y: -tup.y, z: -tup.z, w: -tup.w)
|
||||
proc `*`*(tup: Tuple4, mag: float): Tuple4 = Tuple4(x: tup.x * mag, y: tup.y * mag, z: tup.z * mag, w: tup.w * mag)
|
||||
proc `/`*(tup: Tuple4, mag: float): Tuple4 = Tuple4(x: tup.x / mag, y: tup.y / mag, z: tup.z / mag, w: tup.w / mag)
|
||||
|
||||
proc magnitude*(tup: Tuple4): float = sqrt(tup.x * tup.x + tup.y * tup.y + tup.z * tup.z + tup.w * tup.w)
|
||||
proc normalize*(tup: Tuple4): Tuple4 =
|
||||
let mag = tup.magnitude()
|
||||
Tuple4(x: tup.x / mag, y: tup.y / mag, z: tup.z / mag, w: tup.w / mag)
|
||||
proc dot*(lhs: Tuple4, rhs: Tuple4): float = lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w
|
||||
proc cross*(lhs: Tuple4, rhs: Tuple4): Tuple4 = vector(lhs.y * rhs.z - lhs.z * rhs. y,
|
||||
lhs.z * rhs.x - lhs.x * rhs.z,
|
||||
lhs.x * rhs.y - lhs.y * rhs.x)
|
||||
|
||||
when isMainModule:
|
||||
import unittest
|
||||
suite "tuple":
|
||||
test "Manual Tuple4 is point":
|
||||
let target = Tuple4(x: 2, y: 3, z: 4, w: 1)
|
||||
check(target.isPoint())
|
||||
|
||||
test "Manual Tuple4 is vector":
|
||||
let target = Tuple4(x: 2, y: 3, z: 4, w: 0)
|
||||
check(target.isVector())
|
||||
|
||||
test "Point creation":
|
||||
let target = point(2, 3, 4)
|
||||
check(target == Tuple4(x: 2, y: 3, z: 4, w: 1))
|
||||
|
||||
test "Vector creation":
|
||||
let target = vector(2, 3, 4)
|
||||
check(target == Tuple4(x: 2, y: 3, z: 4, w: 0))
|
||||
|
||||
test "Tuple addition":
|
||||
let t1 = Tuple4(x: 3, y: -2, z: 5, w: 1)
|
||||
let t2 = Tuple4(x: -2, y: 3, z: 1, w: 0)
|
||||
let result = Tuple4(x: 1, y: 1, z: 6, w: 1)
|
||||
check(t1 + t2 == result)
|
||||
|
||||
test "Point subtraction":
|
||||
let t1 = point(3, 2, 1)
|
||||
let t2 = point(5, 6, 7)
|
||||
check(t1 - t2 == vector(-2, -4, -6))
|
||||
|
||||
test "Subtract vector from point":
|
||||
let t1 = point(3, 2, 1)
|
||||
let t2 = vector(5, 6, 7)
|
||||
check(t1 - t2 == point(-2, -4, -6))
|
||||
|
||||
test "Vector subtraction":
|
||||
let t1 = vector(3, 2, 1)
|
||||
let t2 = vector(5, 6, 7)
|
||||
check(t1 - t2 == vector(-2, -4, -6))
|
||||
|
||||
test "Negation":
|
||||
let t1 = Tuple4(x: 1, y: -2, z: 3, w: -4)
|
||||
check(-t1 == Tuple4(x: -1, y: 2, z: -3, w: 4))
|
||||
|
||||
test "Multiply tuple by scalar":
|
||||
let t1 = Tuple4(x: 1, y: -2, z: 3, w: -4)
|
||||
check(t1 * 3.5 == Tuple4(x: 3.5, y: -7, z: 10.5, w: -14))
|
||||
|
||||
test "Multiple tuple by fraction":
|
||||
let t1 = Tuple4(x: 1, y: -2, z: 3, w: -4)
|
||||
check(t1 * 0.5 == Tuple4(x: 0.5, y: -1, z: 1.5, w: -2))
|
||||
|
||||
test "Divide tuple by scalar":
|
||||
let t1 = Tuple4(x: 1, y: -2, z: 3, w: -4)
|
||||
check(t1 / 2 == Tuple4(x: 0.5, y: -1, z: 1.5, w: -2))
|
||||
|
||||
test "Magnitude of vector(1, 0, 0)":
|
||||
check(vector(1, 0, 0).magnitude() == 1)
|
||||
|
||||
test "Magnitude of vector(0, 1, 0)":
|
||||
check(vector(0, 1, 0).magnitude() == 1)
|
||||
|
||||
test "Magnitude of vector(0, 0, 1)":
|
||||
check(vector(0, 0, 1).magnitude() == 1)
|
||||
|
||||
test "Magnitude of vector(1, 2, 3)":
|
||||
check(vector(1, 2, 3).magnitude() == sqrt(14.0))
|
||||
|
||||
test "Magnitude of vector(-1, -2, -3)":
|
||||
check(vector(-1, -2, -3).magnitude() == sqrt(14.0))
|
||||
|
||||
test "Normalize vector(4, 0, 0)":
|
||||
check(vector(4, 0, 0).normalize() == vector(1, 0, 0))
|
||||
|
||||
test "Normalize vector(1, 2, 3)":
|
||||
check(vector(1, 2, 3).normalize() == vector(1/sqrt(14.0), 2/sqrt(14.0), 3/sqrt(14.0)))
|
||||
|
||||
test "Magnitude of normalized vector":
|
||||
check(vector(1, 2, 3).normalize().magnitude() == 1)
|
||||
|
||||
test "Dot product":
|
||||
check(vector(1, 2, 3).dot(vector(2, 3, 4)) == 20)
|
||||
|
||||
test "Vector cross product":
|
||||
let t1 = vector(1, 2, 3)
|
||||
let t2 = vector(2, 3, 4)
|
||||
check(t1.cross(t2) == vector(-1, 2, -1))
|
||||
check(t2.cross(t1) == vector(1, -2, 1))
|
Loading…
Reference in New Issue
Block a user