clankill3r
clankill3r

Reputation: 9543

Distance calculation with square root on end result gives different result

I can't wrap my head around this. Why is the part where I square such significant smaller? I know if I use l += l then I get the correct amount but it should not be that way I believe.

If we look at processings dist method:

  static public final float dist(float x1, float y1, float x2, float y2) {
    return sqrt(sq(x2-x1) + sq(y2-y1));
  }

Then square root is used on the inner product. In my code I do this with the final result.

void setup() {
  
  // normal way, which gives correct result:
  float l = 0;

  l += dist(96.5, 89.0, 420.0, 97.5);
  l += dist(420.0, 97.5, 412.5, 409.5);
  l += dist(412.5, 409.5, 89.0, 420.0);
  l += dist(89.0, 420.0, 96.5, 89.0);

  println(l); // ok
  println(sqrt(sq(l))); // ok
  
  l = 0;
 
  l += distSQ(96.5, 89.0, 420.0, 97.5);
  l += distSQ(420.0, 97.5, 412.5, 409.5);
  l += distSQ(412.5, 409.5, 89.0, 420.0);
  l += distSQ(89.0, 420.0, 96.5, 89.0);
      
  l = sqrt(l);
  
  println("why is this one smaller? "+l); // should be twice as big
  
}

static protected final float distSQ(float x1, float y1, float x2, float y2) {
  return sq(x2-x1) + sq(y2-y1);
}

edit:

output is:

1290.457

1290.457

why is this one smaller? 645.3716

Upvotes: 0

Views: 230

Answers (4)

Cimbali
Cimbali

Reputation: 11395

It might be worth stating that what you expect from the square root function sqrt only happens for linear functions*.

A function f, that takes a real and returns a real, verifies f(a+b) = f(a)+f(b) for all a and b (thus what you expect) is necessarily defined by a constant c such that f(x)=c*x.

You can see that the reciprocal is true as well and easy to see : c*a+c*b = c*(a+b)

In that case, plotting f would result in a straight line that goes through the origin (the point (0,0)), which you know is not the case for the square root : http://fooplot.com/plot/rojyepxjog


* This is true on the rationals, you have to add a few pathological cases on the real numbers, but nothing that would affect your daily life.

Upvotes: 0

Simon
Simon

Reputation: 6363

l += dist(96.5, 89.0, 420.0, 97.5);
l += dist(420.0, 97.5, 412.5, 409.5);
...

Is like

l = sqrt(a^2+b^2) + sqrt(c^2+d^2)...

But

l += distSQ(96.5, 89.0, 420.0, 97.5);
l += distSQ(420.0, 97.5, 412.5, 409.5);
l = sqrt(l);

Is like

l = sqrt(a^2+b^2+c^2+d^2...)

They are not equivalent. Here's an example sqrt(9)+sqrt(4)=5 but sqrt(9+4)=3.6

Upvotes: 2

Bathsheba
Bathsheba

Reputation: 234715

If you think that (a + b + c + d) * (a + b + c + d) is equal to aa + bb + cc + dd then we should publish jointly!

So,

 l += distSQ(96.5, 89.0, 420.0, 97.5);
 l += distSQ(420.0, 97.5, 412.5, 409.5);
 l += distSQ(412.5, 409.5, 89.0, 420.0);
 l += distSQ(89.0, 420.0, 96.5, 89.0);
 l = sqrt(l);

is a very different value to

  l += dist(96.5, 89.0, 420.0, 97.5);
  l += dist(420.0, 97.5, 412.5, 409.5);
  l += dist(412.5, 409.5, 89.0, 420.0);
  l += dist(89.0, 420.0, 96.5, 89.0);

Upvotes: 1

Aditya Kiran
Aditya Kiran

Reputation: 251

Just put the brackets over the return statement at distSQ

Upvotes: 0

Related Questions