0

consider this code:

Point findIntersection(Line l1, Line l2) 
{
  int T1, T2;
  T2 = (l2.d.x*(l1.p.y-l2.p.y) + l2.d.y*(l2.p.x-l1.p.x))/(l1.d.x*l2.d.y - l1.d.y*l2.d.x);
  T1 = (l1.p.x+l1.d.x*T2-l2.p.x)/l2.d.x;
  if (T1>0 && 0<T2<1) {
    return {l2.p.x+l2.d.x*T1, l2.p.y+l2.d.y*T1};
  }
}

(full code http://pastebin.com/M6G40F4M)

this code causes a floating point exception on lines 3&4 (and 13&14 in the larger code snippet). My question is why does this happen, and what would be the correct way to find where two lines intersect. I know these errors usually occur when dividing by zero but I am not sure where I am doing that and how it could be prevented.

Ace shinigami
  • 1,374
  • 2
  • 12
  • 25
  • It's possible for `(l1.d.x*l2.d.y - l1.d.y*l2.d.x)` to be `0`. Isn't it? It's also possible for `l2.d.x` to be zero. Before dividing, you'll need to make sure that the denominator is not zero. – R Sahu May 10 '16 at 03:23
  • The first thing you have to do is always return a value. It causes undefined behaviour when the `T1>0 && 0 – M.M May 10 '16 at 05:07

1 Answers1

2

You are dividing by zero.
Let's prove it.

I'll compile with warnings on, as well as an undefined behaviour sanitizer.

clang++-3.9 -std=c++1z -g -Weverything -fsanitize=undefined  -o main t.cpp

warns:

main.cpp:16:12: warning: generalized initializer lists are incompatible with C++98 [-Wc++98-compat]
    return {l2.p.x+l2.d.x*T1, l2.p.y+l2.d.y*T1};
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:10:7: warning: no previous prototype for function 'findIntersection' [-Wmissing-prototypes]
Point findIntersection(Line l1, Line l2)
      ^
main.cpp:18:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
main.cpp:22:20: warning: generalized initializer lists are incompatible with C++98 [-Wc++98-compat]
    case 0: return {r.p.x, r.d.y};
                   ^~~~~~~~~~~~~~
main.cpp:25:20: warning: generalized initializer lists are incompatible with C++98 [-Wc++98-compat]
    case 3: return {r.d.x, r.p.y};
                   ^~~~~~~~~~~~~~
main.cpp:19:7: warning: no previous prototype for function 'getRectPoint' [-Wmissing-prototypes]
Point getRectPoint(Rect r, int n)
      ^
main.cpp:27:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^

when we run it:

main.cpp:13:57: runtime error: division by zero
[1]    26614 floating point exception (core dumped)  ./main

line 13:

T2 = (l2.d.x*(l1.p.y-l2.p.y) + l2.d.y*(l2.p.x-l1.p.x))/(l1.d.x*l2.d.y - l1.d.y*l2.d.x);
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • not sure how useful the C++98 initializer warning is, when you are in C++1z mode – M.M May 10 '16 at 05:06