Module:CineMol/geometry/testcases
Jump to navigation
Jump to search
| File:Gnome-applications-science.svg | This is the test cases page for the module Module:CineMol/geometry. Results of the test cases. |
-- This is a port of CineMol to lua
-- CineMol https://github.com/moltools/CineMol was written by David Meijer, Marnix H. Medema & Justin J. J. van der Hooft and is MIT licensed
-- Please consider any edits I make to this page also dual licensed MIT & CC-BY-SA 4.0
local p = require('Module:UnitTests')
local g = require('Module:CineMol/geometry')
for k,v in pairs(g) do
_G[k] = v
end
require( 'strict' )
function p:assertAlmostEquals(actual, expected, name)
name = name == nil and "AlmostEquals " .. expected or name
self:equals( name, math.abs( actual - expected ) < 0.001, true )
end
-- ============
-- Vector3D
-- ============
function p:test_vector3d_creation()
local vector = Vector3D(1, 2, 3)
self:equals("vector x", vector.x, 1 )
self:equals("vector y", vector.y, 2 )
self:equals("vector z", vector.z, 3 )
end
function p:test_random_vector3d()
local vector = Vector3D_create_random()
-- All values should be between 0 and -1.
self:equals("vector x", 0 <= vector.x and vector.x <= 1, true)
self:equals("vector y", 0 <= vector.y and vector.y <= 1, true)
self:equals("vector z", 0 <= vector.z and vector.z <= 1, true)
end
function p:test_vector3d_length()
local vector = Vector3D(1, 2, 3)
self:equals("length", math.abs(vector:length() - 3.742) <0.001, true)
end
-- END Vector3D
function p:test_GramSchmidt()
local vector_n = Vector3D(1,2,3)
local v, w = gram_schmidt(vector_n)
self:equals( "n not null", type(vector_n), "table")
self:equals( "v not null", type(v), "table")
self:equals( "w not null", type(w), "table")
self:equals( "w is Vector3D", w._TYPE, "Vector3D")
self:assertAlmostEquals( vector_n:dot(w), 0 )
self:assertAlmostEquals( v:dot(w), 0 )
end
function p:test_same_side_of_plane_same_side()
local plane_point = Point3D(0, 0, 0)
local plane_normal = Vector3D(0, 0, 1)
local plane = Plane3D(plane_point, plane_normal)
local point1 = Point3D(1, 1, 1)
local point2 = Point3D(-1, -1, 1)
local result = same_side_of_plane(plane, point1, point2)
self:equals("same_side", result, true )
end
function p:test_same_side_of_plane_opposite_side()
local plane_point = Point3D(0, 0, 0)
local plane_normal = Vector3D(0, 0, 1)
local plane = Plane3D(plane_point, plane_normal)
local point1 = Point3D(1, 1, 1)
local point2 = Point3D(-1, -1, -1)
local result = same_side_of_plane(plane, point1, point2)
self:equals("same_side", result, false )
end
function p:test_distance_to_line()
local point = Point3D(1, 1, 1)
local line = Line3D(Point3D(0, 0, 0), Point3D(2, 2, 2))
local result = distance_to_line(line, point)
self:assertAlmostEquals(result, 0.0, "is zero")
point = Point3D(1, 0, 0)
line = Line3D(Point3D(-1, -1, 0), Point3D(2, 2, 0))
result = distance_to_line(line, point)
self:assertAlmostEquals(result, 0.707, "not zero")
end
function p:test_three_perpendicular_lines()
local line = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0))
local width = 1
local result = get_perpendicular_lines(line, width, 3)
-- Distances between the starts and the ends of the three new lines should
-- all be equal to the given width.
self:assertAlmostEquals(result[1].start:calculate_distance(result[2].start), width, "1.start 2.start")
self:assertAlmostEquals(result[1].endp:calculate_distance(result[2].endp), width, "1.end 2.end")
self:assertAlmostEquals(result[2].start:calculate_distance(result[3].start), width, "2.start 3.start")
self:assertAlmostEquals(result[2].endp:calculate_distance(result[3].endp), width, "2.end 3.end")
self:assertAlmostEquals(
result[1].start:calculate_distance(result[3].start), width * 2, "start1 start3"
)
self:assertAlmostEquals(result[1].endp:calculate_distance(result[3].endp), width * 2, "end.1 end.3")
-- Distances between the starts and the ends of the three new lines and the
-- original line should be equal to the given width for the first and third line ...
self:assertAlmostEquals(result[1].start:calculate_distance(line.start), width, "1.start line.start")
self:assertAlmostEquals(result[1].endp:calculate_distance(line.endp), width, "1.end line.end")
self:assertAlmostEquals(result[3].start:calculate_distance(line.start), width, "3.start line.start")
self:assertAlmostEquals(result[3].endp:calculate_distance(line.endp), width, "3.end line.end")
-- ... and zero for the second line.
self:assertAlmostEquals(result[2].start:calculate_distance(line.start), 0, "2.start line.start")
self:assertAlmostEquals(result[2].endp:calculate_distance(line.endp), 0, "2.end line.end")
end
function p:test_GetPointsOnLine3D()
local line = Line3D(Point3D(0, 0, 0), Point3D(1, 1, 1))
local result = get_points_on_line_3d(line, 10)
self:equals( "number of lines returned", #result, 11)
self:assertAlmostEquals(result[1]:calculate_distance(line.start), 0, "distance start")
self:assertAlmostEquals(result[11]:calculate_distance(line.endp), 0, "distance end")
for i = 1, #result do
self:assertAlmostEquals(distance_to_line(line, result[i]), 0, "distance to line " .. i )
end
end
function p:test_GetPointsOnCircumferenceCircle3D()
local circle = Circle3D(Point3D(0, 0, 0), 1, Vector3D(0, 0, 1))
local result = get_points_on_circumference_circle_3d(circle, 10)
self:equals("number of points", #result, 10)
for i, point in ipairs( result ) do
self:assertAlmostEquals( point:calculate_distance(circle.center), circle.radius, "dist to radius " .. i )
end
end
function p:test_GetPointsOnSurfaceCircle3D()
local circle = Circle3D(Point3D(0, 0, 0), 1, Vector3D(0, 0, 1))
local num_radii = 3
local num_points = 10
local result = get_points_on_surface_circle_3d(circle, num_radii, num_points)
self:equals("number of pts", #result, num_radii * num_points)
for i, point in ipairs(result) do
self:equals( "point is inside circle " .. i, point:calculate_distance(circle.center) <= circle.radius, true )
self:assertAlmostEquals(point.z, 0, "z is 0 - " .. i )
end
end
-- TestGetPointsOnSurfaceCap
function p:test_GetPointsOnSurfaceCap()
local circle = Circle3D(Point3D(0, 0, 0), 1, Vector3D(0, 0, 1))
local cap_type = CylinderCapType.FLAT
local result = get_points_on_surface_cap(
cap_type, circle.center, circle.radius, circle.normal, Point3D(0, 0, -1), 10
)
for i,point in ipairs(result) do
self:equals( "point inside circle FLAT_CAP " .. i, math.floor(point:calculate_distance(circle.center)*1e5)/1e5 <= circle.radius, true)
self:assertAlmostEquals(point.z, 0, "FLAT CAP z=0 " .. i)
end
result = get_points_on_surface_cap(
CylinderCapType.ROUND, circle.center, circle.radius, circle.normal, Point3D(0, 0, -1), 10
)
for i,point in ipairs(result) do
self:equals( "point inside circle FLAT_CAP " .. i, math.floor(point:calculate_distance(circle.center)*1e5)/1e5 <= circle.radius, true)
self:equals("ROUND CAP z=0 " .. i, point.z >= 0, true)
end
result = get_points_on_surface_cap(
CylinderCapType.NO_CAP, circle.center, circle.radius, circle.normal, Point3D(0, 0, -1), 10
)
self:equals( 'NO_CAP numb points', #result, 0 )
end
function p:test_points_on_surface_cylinder_returns_points_on_surface()
local start = Point3D(0, 0, 0)
local endp = Point3D(0, 0, 1)
local line = Line3D(start, endp)
local radius = 1
local cylinder = Cylinder(start, endp, radius, CylinderCapType.NO_CAP)
local result = get_points_on_surface_cylinder(cylinder, 10)
for i,point in ipairs(result) do
self:assertAlmostEquals(distance_to_line(line, point), radius, 'point in radius ' .. i)
end
end
function p:test_point_is_inside_sphere_inside()
local sphere = Sphere(Point3D(0, 0, 0), 1)
local point = Point3D(0, 0, 0.5)
local result = point_is_inside_sphere(sphere, point)
self:equals( "inside sphere", result, true)
point = Point3D(0, 0, 1.5)
result = point_is_inside_sphere(sphere, point)
self:equals( "outside sphere", result, false)
end
function p:test_point_is_inside_cylinder()
local cylinder = Cylinder(Point3D(0, 0, 0), Point3D(0, 0, 1), 1, CylinderCapType.NO_CAP)
local point = Point3D(0, 0, 0.5)
local result = point_is_inside_cylinder(cylinder, point)
self:equals( "inside", result, true)
point = Point3D(0, 0, 1.5)
result = point_is_inside_cylinder(cylinder, point)
self:equals( "outside", result, false)
end
function p:test_sphere_intersects_with_sphere()
local sphere1 = Sphere(Point3D(0, 0, 0), 1)
local sphere2 = Sphere(Point3D(1, 0, 0), 1)
local result = sphere_intersects_with_sphere(sphere1, sphere2)
self:equals( "intersects", result, true )
sphere2 = Sphere(Point3D(3, 0, 0), 1)
result = sphere_intersects_with_sphere(sphere1, sphere2)
self:equals( "not intersects", result, false )
end
function p:test_sphere_intersects_with_cylinder()
local sphere = Sphere(Point3D(0, 0, 0), 1)
local cylinder = Cylinder(Point3D(0, 0, 0), Point3D(0, 0, 1), 1, CylinderCapType.NO_CAP)
local result = sphere_intersects_with_cylinder(sphere, cylinder)
self:equals( "intersects", result, true )
cylinder = Cylinder(Point3D(0, 0, 3), Point3D(0, 0, 4), 1, CylinderCapType.NO_CAP)
result = sphere_intersects_with_cylinder(sphere, cylinder)
self:equals( "not intersects", result, false )
end
function p:test_cylinder_intersects_with_cylinder()
local cylinder1 = Cylinder(Point3D(0, 0, 0), Point3D(0, 0, 1), 1, CylinderCapType.NO_CAP)
local cylinder2 = Cylinder(Point3D(1, 0, 0), Point3D(1, 0, 1), 1, CylinderCapType.NO_CAP)
local result = cylinder_intersects_with_cylinder(cylinder1, cylinder2)
self:equals( "intersects", result, true )
cylinder2 = Cylinder(Point3D(3, 0, 0), Point3D(3, 0, 1), 1, CylinderCapType.NO_CAP)
result = cylinder_intersects_with_cylinder(cylinder1, cylinder2)
self:equals( "not intersects", result, false )
end
function p:test_points_on_surface_sphere_returns_points_on_surface()
local sphere = Sphere(Point3D(0,0,0), 1)
local result = get_points_on_surface_sphere(sphere, 10, 10)
for i,point in ipairs( result ) do
self:assertAlmostEquals( point:calculate_distance(sphere.center), sphere.radius, "point " .. i )
end
end
return p