1
0

Added tuple implementation

This commit is contained in:
neviyn 2020-07-21 13:47:51 +01:00
parent 501ae30546
commit 93c5a0809d

116
src/tuple.nim Normal file
View 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))