Computational Geometry - How to check if two lines intersect only at the anchor?

-3

Well, I need to make a program in C ++ that gets a A (x, 0) point a point B (x, 0) this point A and B they are on the x-axis, always with y = 0.

After receiving the A point and the B point, I have to receive a C (x, y) D (x, y) and check if they intercept only on the anchor ... Follow the image to get clearer.

As the above image shows, the points A and B form a straight line .. Then I will receive points C (x, y) and D (x, y) and I need to do a program to calculate If the points intercept only in points A and B , but I do not know how to do this.

I'm not asking for ready code, just a light on how to check if two points intercept only on points A and B ...

    
asked by anonymous 06.08.2018 / 17:33

1 answer

8

There are four concepts to consider:

  • Point
  • Vector
  • Reta
  • Triangle

All of these concepts are in two dimensions. The point and the vector have a x coordinate and a y coordinate. A triangle is represented by 3 points.

The line can be represented as a point and a vector or as a colon. To find the% vector of% of a line given by the points v and a , you can do this:

v.x = a.x - b.x;
v.y = a.y - b.y;

The opposite case, to find the point b from a line with a point b and a vector a is this:

b.x = a.x - v.x;
b.y = a.y - v.y;

Notice that in both cases it is the same equation. In fact, in this second pair of equations, you could use v instead of + if you prefer or multiply - and v.x by any number other than zero before adding or subtracting with the coordinates of v.y , since the only thing that matters here to define the a point is that it is any point on the line since it is not itself b .

To simplify some calculations, you may prefer to work with normalized vectors. To create a normalized% color from a a vector, you do this:

double mag = sqrt(v.x * v.x + v.y * v.y);
u.x = v.x / mag;
u.y = v.y / mag;

And note that this works only if at least one of u and v is non-zero. In this your problem, null vectors are not usable.

That said, what you have to do is see if the D point is inside the triangle ABC or if the point C is inside the triangle ABD. For this, you will already have a function something like this:

bool dentro(Triangulo t, Ponto p);

Or, if you are using classes:

bool Triangulo::dentro(Ponto p);

Now we have to see how to know if a point is inside the triangle. To do this, we can see that a line always divides the plane into two parts. Therefore, point D is within the triangle ABC if all these conditions are true:

  • Using A and B to divide the plane, points C and D are on the same side.
  • Using A and C to divide the plane, points B and D are on the same side.
  • Using B and C to divide the plane, points A and D are on the same side.

If all of the above conditions are true, then D is inside the triangle. If at least one of them is false, it's out. A point on top of the line can be considered as being on both sides simultaneously (ie, above the line it is inside the triangle).

With this, you will have a function something like this:

bool mesmo_lado(Reta r, Ponto p1, Ponto p2);

Or so:

bool Reta::mesmo_lado(Ponto p1, Ponto p2);

To know which side of the line a point is on, you can do something like the figure below:

In this figure, points A and B form a line and there is a point C. Then there is a line CK perpendicular to line AB (ie, they form an angle of 90 °), where point K is the point where the two straight lines meet.

The idea is to use a vector to measure this CK segment. You then do the same with D producing a straight DJ (where J is another point on the line AB, but not necessarily equal to K). As a result, CK and DJ will be vectors of the same direction, but not necessarily with the same directions. If CK and DJ have the same meaning, then C and D are on the same side. If CK and DJ have opposite directions, then C and D are on different sides of the AB line.

Thus, to find the vector perpendicular to another vector:

Vetor *Vetor::perpendicular() {
    return new Vetor(this.y, -this.x);
}

Or else it could be this too (the vector would point to the opposite side, but in the same direction):

Vetor Vetor::perpendicular() {
    return new Vetor(-this.y, this.x);
}

When you do this, you already have the AB line and when you use the C point and the perpendicular vector of the AB line, you get the CK line.

However, you still do not know where the K point is. To find it, we use a system of equations where the points are v.x , v.y and a , line vector AB is% the length of segment AK and% of which is the length of segment CK:

k.x = a.x + r * vab.x;
k.x = c.x + s * vck.x;
k.y = a.y + r * vab.y;
k.y = c.y + s * vck.y;

Let's isolate b and c :

r = (k.x - a.x) / vab.x;
r = (k.y - a.y) / vab.y;
s = (k.x - c.x) / vck.x;
s = (k.y - c.y) / vck.y;

Note that there are two formulas for vab and two formulas for vab . Use the one that suits you best. The one that best suit is the one that best avoids division by zero. That way, you can compare vck and r and opt for the formula that divides by the greater. The same occurs with s and r .

Finding the K point, you can create the CK line. You do the same for D and get a DJ point where J is some other point. Note that in this case, the CK and DJ vector will have the same direction. Then you can check the meaning by comparing the signals of the s and r components of the vector. Equal signs are same side and different signs are opposite sides.

With this, you can finally set up your function / method s and with it the function / method vab.x and finally solve your problem.

    
07.08.2018 / 00:31