/test/test_triangle.rb
Ruby | 318 lines | 245 code | 49 blank | 24 comment | 16 complexity | c1791eb23aa2bcd243a27dfd2f086f68 MD5 | raw file
- $LOAD_PATH.unshift(File.dirname(__FILE__))
- require 'helper'
- include GMath3D
- MiniTest::Unit.autorun
- class TriangleTestCase < MiniTest::Unit::TestCase
- def setup
- @triangle = Triangle.new( Vector3.new(1,2,2), Vector3.new(1,4,2), Vector3.new(-1,3,0))
- @triangle_default = Triangle.new()
- end
- def test_initialize
- assert_equal(Vector3.new(1,2,2), @triangle.vertices[0])
- assert_equal(Vector3.new(1,4,2), @triangle.vertices[1])
- assert_equal(Vector3.new(-1,3,0), @triangle.vertices[2])
- assert_equal(Vector3.new(0,0,0), @triangle_default.vertices[0])
- assert_equal(Vector3.new(1,0,0), @triangle_default.vertices[1])
- assert_equal(Vector3.new(0,1,0), @triangle_default.vertices[2])
- end
- def test_equals
- assert(@triangle != nil)
- assert(@triangle != "string")
- shallow_copied = @triangle
- assert(@triangle.equal?(shallow_copied))
- assert(@triangle == shallow_copied)
- assert_equal(@triangle, Triangle.new( Vector3.new(1.0,2.0,2.0), Vector3.new(1.0,4.0,2.0), Vector3.new(-1.0,3.0,0.0)))
- assert(@triangle == Triangle.new( Vector3.new(1.0,2.0,2.0), Vector3.new(1.0,4.0,2.0), Vector3.new(-1.0,3.0,0.0)))
- assert(@triangle != Triangle.new( Vector3.new(1.0,2.0,2.0), Vector3.new(1.0,4.0,2.0), Vector3.new(-1.0,3.0,0.5)))
- end
- def test_clone
- shallow_copied = @triangle
- shallow_copied.vertices[2].x = 1
- assert(@triangle == shallow_copied)
- assert(@triangle.equal?(shallow_copied))
- assert_equal(1, @triangle.vertices[2].x)
- assert_equal(1, shallow_copied.vertices[2].x)
- cloned =@triangle.clone
- assert(@triangle == cloned)
- assert(!@triangle.equal?(cloned))
- cloned.vertices[2].x = -10
- assert_equal(-10, cloned.vertices[2].x)
- assert_equal(1, @triangle.vertices[2].x) # original never changed in editing cloned one.
- end
- def test_to_s
- assert_equal("Triangle[[1, 2, 2], [1, 4, 2], [-1, 3, 0]]", @triangle.to_s)
- end
- def test_box
- box1 = @triangle.box
- box2 = @triangle_default.box
- assert_equal(Vector3.new(-1,2,0), box1.min_point)
- assert_equal(Vector3.new(1,4,2), box1.max_point)
- assert_equal(Vector3.new(0,0,0) , box2.min_point)
- assert_equal(Vector3.new(1,1,0) , box2.max_point)
- end
- def test_point
- assert_equal(@triangle.vertices[0], @triangle.point( Array.new([1,0,0])))
- assert_equal(@triangle.vertices[1], @triangle.point( Array.new([0,1,0])))
- assert_equal(@triangle.vertices[2], @triangle.point( Array.new([0,0,1])))
- #on edge
- assert_equal(Vector3.new(1,3,2), @triangle.point( Array.new([0.5,0.5,0])))
- assert_equal(Vector3.new(0,3.5,1), @triangle.point( Array.new([0,0.5,0.5])))
- assert_equal(Vector3.new(0,2.5,1), @triangle.point( Array.new([0.5,0,0.5])))
- #inside
- assert_equal(Vector3.new(0, 3, 1), @triangle.point( Array.new([0.25,0.25,0.5])))
- assert_equal(@triangle.center, @triangle.point( Array.new([1.0/3.0,1.0/3.0,1.0/3.0])))
- end
- def test_edges
- edges = @triangle.edges
- assert_equal(@triangle.vertices[0], edges[0].start_point)
- assert_equal(@triangle.vertices[1], edges[0].end_point)
- assert_equal(@triangle.vertices[1], edges[1].start_point)
- assert_equal(@triangle.vertices[2], edges[1].end_point)
- assert_equal(@triangle.vertices[2], edges[2].start_point)
- assert_equal(@triangle.vertices[0], edges[2].end_point)
- end
- def test_area
- assert_in_delta(Math::sqrt(8), @triangle.area, @triangle.tolerance)
- assert_in_delta(0.5, @triangle_default.area, @triangle_default.tolerance)
- end
- def test_normal
- assert_equal( Vector3.new(-1,0,1).normalize(), @triangle.normal )
- assert_equal( Vector3.new(0,0,1) ,@triangle_default.normal )
- end
- def test_reverse
- current_normal = @triangle.normal()
- reversed_normal = @triangle.reverse().normal()
- assert( current_normal.parallel?(reversed_normal) )
- assert( !current_normal.same_direction?(reversed_normal) )
- end
- def test_center
- center = @triangle.center
- assert_in_delta( 0.333333333333333, center.x, @triangle.tolerance)
- assert_in_delta( 3.0, center.y, @triangle.tolerance)
- assert_in_delta( 1.333333333333333, center.z, @triangle.tolerance)
- barycentric_coordinate = @triangle.barycentric_coordinate(center)
- assert_in_delta( 1.0/3.0, barycentric_coordinate[0], @triangle.tolerance)
- assert_in_delta( 1.0/3.0, barycentric_coordinate[1], @triangle.tolerance)
- assert_in_delta( 1.0/3.0, barycentric_coordinate[2], @triangle.tolerance)
- end
- def test_barycentric_coordinate
- # on vertex
- coord = @triangle.barycentric_coordinate( @triangle.vertices[1])
- assert_equal( 3, coord.size )
- assert_in_delta( 0, coord[0], @triangle.tolerance)
- assert_in_delta( 1, coord[1], @triangle.tolerance)
- assert_in_delta( 0, coord[2], @triangle.tolerance)
- # on edge
- coord = @triangle.barycentric_coordinate( Vector3.new(1,3,2) )
- assert_in_delta( 0.5, coord[0], @triangle.tolerance)
- assert_in_delta( 0.5, coord[1], @triangle.tolerance)
- assert_in_delta( 0, coord[2], @triangle.tolerance)
- # inside case
- coord = @triangle.barycentric_coordinate( Vector3.new(0,3,1) )
- assert_in_delta( 1.0, coord[0] + coord[1] + coord[2], @triangle.tolerance)
- assert_in_delta( 0.25, coord[0], @triangle.tolerance)
- assert_in_delta( 0.25, coord[1], @triangle.tolerance)
- assert_in_delta( 0.5, coord[2], @triangle.tolerance)
- # outside case
- coord = @triangle_default.barycentric_coordinate( Vector3.new(2,0,0) )
- assert_in_delta( -1.0, coord[0], @triangle.tolerance)
- assert_in_delta( 2.0, coord[1], @triangle.tolerance)
- assert_in_delta( 0.0, coord[2], @triangle.tolerance)
- # outside case
- coord = @triangle.barycentric_coordinate( Vector3.new(3,3,4) )
- assert_in_delta( 1.0, coord[0], @triangle.tolerance)
- assert_in_delta( 1.0, coord[1], @triangle.tolerance)
- assert_in_delta( -1.0, coord[2], @triangle.tolerance)
- #invalid argument
- assert_raises ArgumentError do
- coord = @triangle.barycentric_coordinate( 3 )
- end
- assert_raises ArgumentError do
- coord = @triangle.barycentric_coordinate( nil )
- end
- end
- def test_contains
- check_point = @triangle.center + @triangle.normal*3.0
- assert( !@triangle.contains?( check_point) )
- assert( @triangle.contains?( @triangle.center) )
- assert( @triangle.contains?( Vector3.new( 1,3,2)))
- assert( @triangle.contains?( Vector3.new(-1,3,0)))
- assert( @triangle_default.contains?( Vector3.new( 0.5, 0.5, 0.0 ) ))
- assert( !@triangle_default.contains?( Vector3.new( -1.0, 2.0, 0.0 )))
- assert( !@triangle_default.contains?( Vector3.new( 1.0, 1.0, 0.0 )))
- end
- def test_distance_to_point
- # on inside
- check_point = @triangle.center + @triangle.normal*3.0
- distance, point_on_triangle = @triangle.distance(check_point)
- assert_in_delta(3.0, distance, @triangle.tolerance)
- assert_equal(@triangle.center, point_on_triangle)
- # on vertex
- distance, point_on_triangle = @triangle_default.distance(Vector3.new(-1,-1,0.5))
- assert_in_delta(Math::sqrt(2.25), distance, @triangle_default.tolerance)
- assert_equal(@triangle_default.vertices[0], point_on_triangle)
- # on edge
- distance, point_on_triangle = @triangle.distance( Vector3.new(2,3,2))
- assert_in_delta(1, distance, @triangle_default.tolerance)
- assert_equal(Vector3.new(1,3,2), point_on_triangle)
- # contains to inside
- distance, point_on_triangle = @triangle_default.distance(@triangle_default.center)
- assert_in_delta(0, distance, @triangle_default.tolerance)
- assert_equal(@triangle_default.center, point_on_triangle)
- end
- def test_distance_to_line
- # on inside
- line = Line.new(Vector3.new(0,3,-1), Vector3.new(0,0,4))
- distance, point_on_triangle, point_on_line, param_on_line = @triangle.distance(line)
- assert_equal(0, distance)
- assert_equal(Vector3.new(0,3,1), point_on_triangle)
- assert_equal(Vector3.new(0,3,1), point_on_line)
- assert_in_delta(0.5, param_on_line, line.tolerance)
- # on edge
- line = Line.new(Vector3.new(1,3,-1), Vector3.new(0,0,4))
- distance, point_on_triangle, point_on_line, param_on_line = @triangle.distance(line)
- assert_equal(0, distance)
- assert_equal(Vector3.new(1,3,2), point_on_triangle)
- assert_equal(Vector3.new(1,3,2), point_on_line)
- assert_in_delta(0.75, param_on_line, line.tolerance)
- # on vertex
- line = Line.new(Vector3.new(-1,3,0), Vector3.new(1,1,2))
- distance, point_on_triangle, point_on_line, param_on_line = @triangle.distance(line)
- assert_equal(0, distance)
- assert_equal(Vector3.new(-1,3,0), point_on_triangle)
- assert_equal(Vector3.new(-1,3,0), point_on_line)
- assert_in_delta(0.0, param_on_line, line.tolerance)
- # closest point is out of triangle1
- line = Line.new(Vector3.new(2,3,0), Vector3.new(0,0,4))
- distance, point_on_triangle, point_on_line, param_on_line = @triangle.distance(line)
- assert_equal(1, distance)
- assert_equal(Vector3.new(1,3,2), point_on_triangle)
- assert_equal(Vector3.new(2,3,2), point_on_line)
- assert_in_delta(0.5, param_on_line, line.tolerance)
- # closest point is out of triangle2
- line = Line.new(Vector3.new(-2,3,-1), Vector3.new(0,0,1))
- distance, point_on_triangle, point_on_line, param_on_line = @triangle.distance(line)
- assert_equal(1, distance)
- assert_equal(Vector3.new(-1,3,0), point_on_triangle)
- assert_equal(Vector3.new(-2,3,0), point_on_line)
- assert_in_delta(1, param_on_line, line.tolerance)
- # parallel case
- line = Line.new(Vector3.new(1,0,4), Vector3.new(0,6,0))
- distance, point_on_triangle, point_on_line, param_on_line = @triangle.distance(line)
- assert_equal(2, distance)
- assert_equal(nil, point_on_triangle)
- assert_equal(nil, point_on_line)
- assert_equal(nil, param_on_line)
- end
- def test_distance_to_plane
- # intersect case
- plane = Plane.new(Vector3.new(0,0,1), Vector3.new(1,0,0))
- distance, intersect_line, point_on_triangle, point_on_plane = @triangle.distance(plane)
- assert_equal( 0, distance )
- point1 = Vector3.new(0,2.5,1)
- point2 = Vector3.new(0,3.5,1)
- assert( FiniteLine.new(point1, point2) == intersect_line || FiniteLine.new(point2, point1) == intersect_line)
- assert_equal( nil, point_on_triangle )
- assert_equal( nil, point_on_plane )
- # contains edge
- plane = Plane.new(Vector3.new(1,0,1), Vector3.new(-1,0,0))
- distance, intersect_line, point_on_triangle, point_on_plane = @triangle.distance(plane)
- assert_equal( 0, distance )
- point1 = Vector3.new(1,2,2)
- point2 = Vector3.new(1,4,2)
- assert( FiniteLine.new(point1, point2) == intersect_line || FiniteLine.new(point2, point1) == intersect_line)
- assert_equal( nil, point_on_triangle )
- assert_equal( nil, point_on_plane )
- # contains vertex
- plane = Plane.new(Vector3.new(-1,0,1), Vector3.new(1,0,0))
- distance, intersect_line, point_on_triangle, point_on_plane = @triangle.distance(plane)
- assert_equal( 0, distance )
- assert_equal( nil, intersect_line)
- assert_equal( Vector3.new(-1,3,0), point_on_triangle )
- assert_equal( Vector3.new(-1,3,0), point_on_plane )
- # closeing point is outside of triangle
- plane = Plane.new(Vector3.new(-2,0,0), Vector3.new(-1,0,0))
- distance, intersect_line, point_on_triangle, point_on_plane = @triangle.distance(plane)
- assert_equal( 1, distance )
- assert_equal( nil, intersect_line)
- assert_equal( Vector3.new(-1,3,0), point_on_triangle )
- assert_equal( Vector3.new(-2,3,0), point_on_plane )
- # parallel to plane
- plane = Plane.new(Vector3.new(0,0,4), Vector3.new(0,0,1))
- distance, intersect_line, point_on_triangle, point_on_plane = @triangle_default.distance(plane)
- assert_equal( 4, distance )
- assert_equal( nil, intersect_line)
- assert_equal( nil, point_on_triangle )
- assert_equal( nil, point_on_plane )
- # parallel to edge
- plane = Plane.new(Vector3.new(3.5,0,3), Vector3.new(-1,0,0))
- distance, closest_line, point_on_triangle, point_on_plane = @triangle.distance(plane)
- assert_equal( 2.5, distance )
- point1 = Vector3.new(1,2,2)
- point2 = Vector3.new(1,4,2)
- assert( FiniteLine.new(point1, point2) == closest_line || FiniteLine.new(point2, point1) == closest_line)
- assert_equal( nil, point_on_triangle )
- assert_equal( nil, point_on_plane )
- end
- def test_angle
- triangle1 = Triangle.new( Vector3.new(0,0,1), Vector3.new(Math.sqrt(3.0),0,1), Vector3.new(0,1,1))
- triangle2 = Triangle.new( Vector3.new(1,0,0), Vector3.new(0,0,1), Vector3.new(1,1,1))
- assert_equal(nil, triangle1.angle(-1))
- assert_equal(nil, triangle1.angle(3))
- assert_in_delta(90.0*Math::PI/180.0, triangle1.angle(0), triangle1.tolerance)
- assert_in_delta(30.0*Math::PI/180.0, triangle1.angle(1), triangle1.tolerance)
- assert_in_delta(60.0*Math::PI/180.0, triangle1.angle(2), triangle1.tolerance)
- assert_in_delta(60.0*Math::PI/180.0, triangle2.angle(0), triangle1.tolerance)
- assert_in_delta(60.0*Math::PI/180.0, triangle2.angle(1), triangle1.tolerance)
- assert_in_delta(60.0*Math::PI/180.0, triangle2.angle(2), triangle1.tolerance)
- end
- end