0

Suppose you are given the vertices of a triangle and asked to find the area using the Shoelace formula and Heron's formula. The two methods yield different results.

In the example describe below, there is a discrepancy i.e. difference of 896 between the two methods. What causes this discrepancy in the result?

Does this say anything about the accuracy of the methods in general i.e. is one method more accurate than the other?

My Best Guess: calculating the area using Heron's formula requires us to compute the lengths of each side. This computation introduces an additional uncertainty/error in the result. To avoid this "extra error", we can calculate the area directly from the given information i.e. the vertices. Therefore, the Shoelace method is more accurate when given the vertices.

def shoelace_formula(v):
    x1y2 = v[0][0]*v[1][1]
    x2y3 = v[1][0]*v[2][1]
    x3y1 = v[2][0]*v[0][1]
    x2y1 = v[1][0]*v[0][1]
    x3y2 = v[2][0]*v[1][1]
    x1y3 = v[0][0]*v[2][1]
    A = (0.5)*abs(x1y2+x2y3+x3y1-x2y1-x3y2-x1y3)
    return A

def magnitudes(v):
    mags = []
    sides = ((v[0],v[1]),(v[1],v[2]),(v[0],v[2]))
    for side in sides:
        mag = hypot(side[0][0]-side[1][0],side[0][1]-side[1][1])
        # mag = sqrt((side[0][0]-side[1][0])**2+(side[0][1]-side[1][1])**2)
        mags.append(mag)
    return mags

def herons_formula(a,b,c):
    s = (a+b+c)/2.0
    A = sqrt(s*(s-a)*(s-b)*(s-c))
    return A

vertices = [[9120703, 8956600230], [-88693678, -83026], [67100, 47194000]]
a,b,c = magnitudes(vertices)
Area_heron = herons_formula(a,b,c)
Area_shoelace =shoelace_formula(vertices)
print repr(Area_shoelace), repr(Area_heron), Area_shoelace - Area_heron
#returns 3.9518890053421114e+17 3.9518890053421203e+17 -896.0
jkarimi
  • 1,247
  • 2
  • 15
  • 27
  • Comparing reals on exact equality is always dangerous, how large is the difference actually? – haraldkl Sep 05 '15 at 22:11
  • A better way to deal with floats is to test that the difference between the two is less than some arbitrary error value you deem acceptable. Prefer something like `abs(Area_heron - Area_shoelace) < 0.0001` to `Area_heron == Area_shoelace` – chucksmash Sep 05 '15 at 22:15
  • in the example above, printing the values for `Area_shoelace` and `Area_heron` returns `2.0`. I see a similar result for very large numbers; it seems to be equal if we print and compare the values. But if we use an equality, python suggests they are not equal. So for what ever reason they are being represented differently internally. – jkarimi Sep 05 '15 at 22:16
  • You're not seeing all the digits. Look at `print repr(Area_shoelace), repr(Area_heron), Area_shoelace - Area_heron`. (Probably we should close this as a dup of one of the many "don't use `==` to compare floating point numbers" questions.) – DSM Sep 05 '15 at 22:30
  • @DSM that results in `2.0 1.9999999999999993 6.66133814775e-16`. What is the cause of this discrepancy? Does it say anything about the general accuracy of the two methods? – jkarimi Sep 05 '15 at 22:35
  • Meh, different operations, different truncations, different results. 2 words - floating point. – Alexandru Barbarosie Sep 05 '15 at 23:24
  • In your case, since you have integer coordinates, the area is a rational number, and you could get an exact answer with the shoelace formula by using the fractions module. You could also get the exact answer with Heron's formula (and the fractions module), but you'd have to compute the square root yourself. Both formulas are exact, and give the same answer theoretically. The difference (which is completely inconsequential -- take another look at it) arises just because of artifacts of the calculation and the representation of floating point numbers. – saulspatz Sep 05 '15 at 23:25

0 Answers0