From a8a5e80f416a09fa60279eea521351a54451bb40 Mon Sep 17 00:00:00 2001 From: Linklancien <123779978+Linklancien@users.noreply.github.com> Date: Sun, 30 Nov 2025 11:55:41 +0100 Subject: [PATCH] math.vec: add tests for vec2,3,4 perpendicular (#25840) --- vlib/math/vec/vec2.v | 2 +- vlib/math/vec/vec2_test.v | 21 +++++++++++++++++++++ vlib/math/vec/vec3.v | 2 +- vlib/math/vec/vec3_test.v | 25 ++++++++++++++++++++++++- vlib/math/vec/vec4.v | 2 +- vlib/math/vec/vec4_test.v | 26 ++++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/vlib/math/vec/vec2.v b/vlib/math/vec/vec2.v index 786fecbcb..09983a0a5 100644 --- a/vlib/math/vec/vec2.v +++ b/vlib/math/vec/vec2.v @@ -258,7 +258,7 @@ pub fn (v Vec2[T]) perp_ccw() Vec2[T] { return Vec2[T]{-v.y, v.x} } -// perpendicular returns the `u` projected perpendicular vector to this vector. +// perpendicular returns the `v` projected perpendicular vector to the 'u' vector. pub fn (v Vec2[T]) perpendicular(u Vec2[T]) Vec2[T] { return v - v.project(u) } diff --git a/vlib/math/vec/vec2_test.v b/vlib/math/vec/vec2_test.v index d8da8cdd4..9e8135544 100644 --- a/vlib/math/vec/vec2_test.v +++ b/vlib/math/vec/vec2_test.v @@ -299,3 +299,24 @@ fn test_vec2_project_negative_components() { assert tolerance(proj.x, 4.68, vec.vec_epsilon) assert tolerance(proj.y, -6.24, vec.vec_epsilon) } + +// Test for perpendicularity +// 'u' and 'v' are already perpendicular so it must return v +fn test_vec2_perpendicularity_angle() { + u := vec.vec2(1.0, 0.0) + v := vec.vec2(0.0, 3.0) + + per := v.perpendicular(u) + assert tolerance(per.x, v.x, vec.vec_epsilon) + assert tolerance(per.y, v.y, vec.vec_epsilon) +} + +// 'u' and 'v' are collinear so it must return the null vector +fn test_vec2_collinear() { + u := vec.vec2(1.0, 0.0) + v := vec.vec2(3.0, 0.0) + + per := v.perpendicular(u) + assert tolerance(per.x, 0.0, vec.vec_epsilon) + assert tolerance(per.y, 0.0, vec.vec_epsilon) +} diff --git a/vlib/math/vec/vec3.v b/vlib/math/vec/vec3.v index ce21d22a6..5fac7a0e2 100644 --- a/vlib/math/vec/vec3.v +++ b/vlib/math/vec/vec3.v @@ -253,7 +253,7 @@ pub fn (v Vec3[T]) unit() Vec3[T] { return Vec3[T]{v.x * invm, v.y * invm, v.z * invm} } -// perpendicular returns the `u` projected perpendicular vector to this vector. +// perpendicular returns the `v` projected perpendicular vector to the 'u' vector. @[inline] pub fn (v Vec3[T]) perpendicular(u Vec3[T]) Vec3[T] { return v - v.project(u) diff --git a/vlib/math/vec/vec3_test.v b/vlib/math/vec/vec3_test.v index 42c3b3216..e41ba0f3c 100644 --- a/vlib/math/vec/vec3_test.v +++ b/vlib/math/vec/vec3_test.v @@ -1,4 +1,4 @@ -import math { veryclose } +import math { tolerance, veryclose } import math.vec fn test_vec3_int() { @@ -131,3 +131,26 @@ fn test_vec3_project_onto_angle() { assert veryclose(proj.y, 0.0) assert veryclose(proj.z, 0.0) } + +// Test for perpendicularity +// 'u' and 'v' are already perpendicular so it must return v +fn test_vec3_perpendicularity_angle() { + u := vec.vec3(1.0, 0.0, 0.0) + v := vec.vec3(0.0, 3.0, 2.0) + + per := v.perpendicular(u) + assert tolerance(per.x, v.x, vec.vec_epsilon) + assert tolerance(per.y, v.y, vec.vec_epsilon) + assert tolerance(per.z, v.z, vec.vec_epsilon) +} + +// 'u' and 'v' are collinear so the result must be the null vector +fn test_vec3_collinear() { + u := vec.vec3(1.0, 0.0, 0.0) + v := vec.vec3(3.0, 0.0, 0.0) + + per := v.perpendicular(u) + assert tolerance(per.x, 0.0, vec.vec_epsilon) + assert tolerance(per.y, 0.0, vec.vec_epsilon) + assert tolerance(per.z, 0.0, vec.vec_epsilon) +} diff --git a/vlib/math/vec/vec4.v b/vlib/math/vec/vec4.v index 0638e74a2..523dbf5be 100644 --- a/vlib/math/vec/vec4.v +++ b/vlib/math/vec/vec4.v @@ -270,7 +270,7 @@ pub fn (v Vec4[T]) unit() Vec4[T] { } } -// perpendicular returns the `u` projected perpendicular vector to this vector. +// perpendicular returns the `v` projected perpendicular vector to the 'u' vector. pub fn (v Vec4[T]) perpendicular(u Vec4[T]) Vec4[T] { return v - v.project(u) } diff --git a/vlib/math/vec/vec4_test.v b/vlib/math/vec/vec4_test.v index 0335a4bb8..b0ff59c8c 100644 --- a/vlib/math/vec/vec4_test.v +++ b/vlib/math/vec/vec4_test.v @@ -1,3 +1,4 @@ +import math { tolerance } import math.vec fn test_vec4_int() { @@ -123,3 +124,28 @@ fn test_vec4_project_onto_zero() { assert proj.z == 0.0 assert proj.w == 0.0 } + +// Test for perpendicularity +// 'u' and 'v' are already perpendicular so it must return v +fn test_vec4_perpendicularity_angle() { + u := vec.vec4(1.0, 0.0, 0.0, 0.0) + v := vec.vec4(0.0, 3.0, 2.0, 0.0) + + per := v.perpendicular(u) + assert tolerance(per.x, v.x, vec.vec_epsilon) + assert tolerance(per.y, v.y, vec.vec_epsilon) + assert tolerance(per.z, v.z, vec.vec_epsilon) + assert tolerance(per.w, v.w, vec.vec_epsilon) +} + +// 'u' and 'v' are collinear so it must return the null vector +fn test_vec4_collinear() { + u := vec.vec4(1.0, 0.0, 0.0, 0.0) + v := vec.vec4(3.0, 0.0, 0.0, 0.0) + + per := v.perpendicular(u) + assert tolerance(per.x, 0.0, vec.vec_epsilon) + assert tolerance(per.y, 0.0, vec.vec_epsilon) + assert tolerance(per.z, 0.0, vec.vec_epsilon) + assert tolerance(per.w, 0.0, vec.vec_epsilon) +} -- 2.39.5