Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:CineMol/geometry/testcases

From Wikipedia, the free encyclopedia
-- 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