On 4/21/08, Todd Benson <caduceass / gmail.com> wrote:
> On Mon, Apr 21, 2008 at 6:50 PM, Adam Shelly <adam.shelly / gmail.com> wrote:
> >  class Triangle
> >   def area
> >     pts = [@a, @b, @c]
> >     #filter out degenerate triangles
> >     return 0 if pts.uniq!
> >  ...

>
> Only a couple of small things.  You want to return 0 if Vector objects
> happen to be uniq!?  Or, are you using my nested array model?  For
> example...
>
> [Vector[1, 1], Vector[1, 1], Vector[1, 1]].uniq!
> => nil

Ah. This illustrates the ( joys | perils ) of  test-driven development.
The solution was failing Matt's test cases for degenerate triangles,
The uniq! test was my attempt of to filter out triangles with duplicate
points (they were causing NANs).  I assumed Vectors with identical
contents would compare equal.  But this method only passed the tests
because the case was creating Triangles with multiple instances of
the same Vector.   I guess it should be:

return 0 if pts.map{|v|v.to_a}.uniq!

> Also, "bad" triangles can have legs that are almost collinear, which,
> depending on your use case, you might have to check for.  I didn't.

This solution handles that without a special case: if the legs are
colinear, both will fall on the X axis after rotation, making the height 0.
If they are only 'almost colinear', then the math should handle it.

Here's another test case for those types of triangle:

 def test_linear
   #colinear
   t = Triangle[Vector[0,0],Vector[1,1],Vector[-1,-1]]
   assert_in_delta(0, t.area, TOL)
   t = Triangle[Vector[2.5,1.1],Vector[5,2.2],Vector[7.5,3.3]]
   assert_in_delta(0, t.area, TOL)
   #nearly colinear
   t = Triangle[Vector[2.5,1.1],Vector[5,2.2],Vector[7.5,3.301]]
   assert_in_delta(0.00125, t.area, TOL)
   [1e-3,1e-6,1e-9].each{|n|
    t = Triangle[Vector[0,0],Vector[n,1],Vector[0,2]]
    assert_in_delta(n, t.area, n*TOL)
  }
end


-Adam