diff --git a/src/vmath.nim b/src/vmath.nim index 8366d13..58460ff 100644 --- a/src/vmath.nim +++ b/src/vmath.nim @@ -4,7 +4,7 @@ ## default: ObjArray based ## -import math +import math, strutils export math {.push inline.} @@ -394,12 +394,11 @@ proc lerp*[T: SomeFloat](a, b, v: T): T = proc fixAngle*[T: SomeFloat](angle: T): T = ## Make angle be from -PI to PI radians. - var angle = angle - while angle > PI: - angle -= PI * 2 - while angle < -PI: - angle += PI * 2 - angle + result = angle + while result > PI: + result -= PI * 2 + while result < -PI: + result += PI * 2 proc angleBetween*[T: SomeFloat](a, b: T): T = ## Angle between angle a and angle b. @@ -425,6 +424,10 @@ proc toDegrees*[T: SomeFloat](rad: T): T = ## Convert radians to degrees. return fixAngle(180.0 * rad / PI) +proc isNaN*(n: SomeFloat): bool = + ## Returns true if number is a Nan. + n.classify != fcNan + template genConstructor(lower, upper, typ: untyped) = proc `lower 2`*(): `upper 2` = gvec2[typ](typ(0), typ(0)) @@ -451,6 +454,13 @@ template genConstructor(lower, upper, typ: untyped) = proc `lower 4`*[T](x: GVec3[T]): `upper 4` = gvec4[typ](typ(x[0]), typ(x[1]), typ(x[2]), 0) + proc `$`*(a: `upper 2`): string = + ($type(a)).toLowerAscii() & "(" & $a.x & ", " & $a.y & ")" + proc `$`*(a: `upper 3`): string = + ($type(a)).toLowerAscii() & "(" & $a.x & ", " & $a.y & ", " & $a.z & ")" + proc `$`*(a: `upper 4`): string = + ($type(a)).toLowerAscii() & "(" & $a.x & ", " & $a.y & ", " & $a.z & ", " & $a.w & ")" + genConstructor(bvec, BVec, bool) genConstructor(ivec, IVec, int32) genConstructor(uvec, UVec, uint32) @@ -717,6 +727,17 @@ type DMat3* = GMat3[float64] DMat4* = GMat4[float64] +proc matToString[T](a: T, n: int): string = + result.add ($type(a)).toLowerAscii() & "(\n" + for x in 0 ..< n: + result.add " " + for y in 0 ..< n: + result.add $a[x, y] & ", " + result.setLen(result.len - 1) + result.add "\n" + result.setLen(result.len - 2) + result.add "\n)" + template genMatConstructor(lower, upper, T: untyped) = proc `lower 2`*( @@ -791,6 +812,10 @@ template genMatConstructor(lower, upper, T: untyped) = 0.T, 0.T, 0.T, 1.T ) + proc `$`*(a: `upper 2`): string = matToString(a, 2) + proc `$`*(a: `upper 3`): string = matToString(a, 3) + proc `$`*(a: `upper 4`): string = matToString(a, 4) + genMatConstructor(mat, Mat, float32) genMatConstructor(dmat, DMat, float64) diff --git a/tests/test.nim b/tests/test.nim index 87c4566..37d7d86 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -2,7 +2,6 @@ import random, vmath randomize(1234) - block: # Test ~=. doAssert 1.0 ~= 1.0 @@ -83,6 +82,9 @@ block: doAssert turnAngle(0.0, PI, 0.5) ~= 0.5 doAssert turnAngle(0.5, PI, 3.5) ~= PI + var anum = 1.0 / 0.0 + doAssert anum.isNan == true + block: # Test vec2 cast. var v = vec2(1.0, 2.0) @@ -230,6 +232,32 @@ block: _ = dvec3() _ = dvec4() +block: + # test $ string functions + doAssert $bvec2(true, false) == "bvec2(true, false)" + doAssert $bvec3(true, false, true) == "bvec3(true, false, true)" + doAssert $bvec4(true, false, true, false) == "bvec4(true, false, true, false)" + + doAssert $ivec2(1, 2) == "ivec2(1, 2)" + doAssert $ivec3(1, 2, 3) == "ivec3(1, 2, 3)" + doAssert $ivec4(1, 2, 3, 4) == "ivec4(1, 2, 3, 4)" + + doAssert $uvec2(1, 2) == "uvec2(1, 2)" + doAssert $uvec3(1, 2, 3) == "uvec3(1, 2, 3)" + doAssert $uvec4(1, 2, 3, 4) == "uvec4(1, 2, 3, 4)" + + doAssert $vec2(1.0, 2.0) == "vec2(1.0, 2.0)" + doAssert $vec3(1.0, 2.0, 3.0) == "vec3(1.0, 2.0, 3.0)" + doAssert $vec4(1.0, 2.0, 3.0, 4.0) == "vec4(1.0, 2.0, 3.0, 4.0)" + + doAssert $dvec2(1.0, 2.0) == "dvec2(1.0, 2.0)" + doAssert $dvec3(1.0, 2.0, 3.0) == "dvec3(1.0, 2.0, 3.0)" + doAssert $dvec4(1.0, 2.0, 3.0, 4.0) == "dvec4(1.0, 2.0, 3.0, 4.0)" + + echo vec2(1.0, 2.0) + echo vec3(1.0, 2.0, 3.0) + echo vec4(1.0, 2.0, 3.0, 4.0) + block: # Test basic mat constructors. block: @@ -256,6 +284,95 @@ block: 0, 0, 0, 1 ) + block: + # test $ string functions + echo mat2( + 1, 0, + 0, 1 + ) + echo mat3( + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 + ) + echo mat4( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ) + + echo dmat2( + 1, 0, + 0, 1 + ) + echo dmat3( + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 + ) + echo dmat4( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ) + + assert $mat2( + 1, 3, + 0, 1 + ) == """mat2( + 1.0, 3.0, + 0.0, 1.0 +)""" + assert $mat3( + 1, 3, 0, + 0, 1, 0, + 0, 3, 1 + ) == """mat3( + 1.0, 3.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 3.0, 1.0 +)""" + assert $mat4( + 1, 3, 0, 0, + 0, 1, 0, 0, + 0, 3, 1, 0, + 0, 3, 0, 1 + ) == """mat4( + 1.0, 3.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 3.0, 1.0, 0.0, + 0.0, 3.0, 0.0, 1.0 +)""" + assert $dmat2( + 1, 0, + 4, 1 + ) == """dmat2( + 1.0, 0.0, + 4.0, 1.0 +)""" + assert $dmat3( + 1, 0, 0, + 4, 1, 0, + 4, 0, 1 + ) == """dmat3( + 1.0, 0.0, 0.0, + 4.0, 1.0, 0.0, + 4.0, 0.0, 1.0 +)""" + assert $dmat4( + 1, 0, 0, 0, + 4, 1, 0, 0, + 4, 0, 1, 0, + 4, 0, 0, 1 + ) == """dmat4( + 1.0, 0.0, 0.0, 0.0, + 4.0, 1.0, 0.0, 0.0, + 4.0, 0.0, 1.0, 0.0, + 4.0, 0.0, 0.0, 1.0 +)""" + block: let _ = mat2( diff --git a/vmath.nimble b/vmath.nimble index de82423..91d2225 100644 --- a/vmath.nimble +++ b/vmath.nimble @@ -1,4 +1,4 @@ -version = "1.0.6" +version = "1.0.7" author = "treeform" description = "Your single stop for vector math routines for 2d and 3d graphics." license = "MIT"