Project Euler 102: For how many triangles in the text file does the interior contain the origin?

Project Euler 102: For how many triangles in the text file does the interior contain the origin?

Written by on 23 June 2012

Topics: Project Euler

Problem 102 of Project Euler asks us the following question

Three distinct points are plotted at random on a Cartesian plane, for which -1000 ≤ xy ≤ 1000, such that a triangle is formed.

Consider the following two triangles:

A(-340,495), B(-153,-910), C(835,-947)

X(-175,41), Y(-421,-714), Z(574,-645)

It can be verified that triangle ABC contains the origin, whereas triangle XYZ does not.

Using triangles.txt  a 27K text file containing the co-ordinates of one thousand “random” triangles, find the number of triangles for which the interior contains the origin.

NOTE: The first two examples in the file represent the triangles in the example given above.

This problem can be solved in a plethora of ways as far as I have seen. I like one particular solution though, which involves calculating the area of triangle and compare it to triangles containing the point P which we are testing if it is in the interior of the triangle.

Area = Area

We want to test if the triangle ABC contains the point P. The main concept of the solution is that the area of the triangle ABC is equal to the area of the triangles ABP + APC + PBC. I wont prove that it is true, but I have found Geogebra again and made a small applet you can play around with and convince yourself that it is indeed true.

You get the feeling for it now I assume?

Area of a triangle

The next thing we need is to calculate the area of the different triangles. Again there is a plethora of methods to do this. But since we have the coordinates of the corners we might as well utilize that.

Wikipedia is happy to inform us that such a formula exists. It is based on the determinant of the vertices.  Which in the general case will give us the following formula

where is the x coordinate of the A vertex of the triangle.

From here on it should be pretty simple.

Coding the solution

The majority of the code for this is made for parsing the input file, and the main file looks like

string[] lines = File.ReadAllLines(filename);
int result = 0;

foreach (string line in lines) {
    //Parse the line
    string[] segments = line.Split(',');
    int[,] coordinates = new int[2, segments.Length/2];

    int[] A = {Convert.ToInt32(segments[0]) ,
               Convert.ToInt32(segments[1])};
    int[] B = {Convert.ToInt32(segments[2]) ,
               Convert.ToInt32(segments[3])};
    int[] C = {Convert.ToInt32(segments[4]) ,
               Convert.ToInt32(segments[5])};
    int[] P = {0,0};

    if (area(A, B, C) ==
        area(A, B, P) +
        area(A, P, C) +
        area(P, B, C))
        result++;
}

The area function I have implemented as

private int area(int[] a, int[] b, int[] c) {
    return Math.Abs((a[0] - c[0])*(b[1] -a[1]) -
                    (a[0]-b[0])*(c[1]-a[1]));
}

As you can see I have removed the 1/2 factor in the front. Since we are not interested in the actual area, but only if they are equal the factor doesn’t have any function. By removing it I can avoid using floating point operations and therefor make the comparison more accurate.

Wrapping up

I have chosen a simple method to figure out if a point is inside a triangle. Besides being simple it is also rather fast. The execution of the problem gives us

 The number of Triangles containing (0,0): 228
 Solution took 2,5883 ms
 

You can find the complete source code here.

I think this method is pretty neat. However, there are many more methods. Blackpawn covers two of these methods. Another method is to measure the angles in the triangles made and so on. The big question is; How did you solve it?

7 Comments For This Post I'd Love to Hear Yours!

  1. Eman says:

    Nice, I have read in your post that there is a formula for this problem.
    My code was really inaccurate. Can you give me some hints how to search for information???

  2. Kristian says:

    Hi Eman

    I am uncertain what you refer to here. I think I cover the whole solution approach including the needed formulas.

    If you want alternative solution strategies google is really your friend for this specific problem. Searching for something like “point in the interior of a triangle”. Will return several hits with good information.

    If you mean something different with your question, please elaborate a bit more.

    /Kristian

  3. Eman says:

    And also I can’t understand why the Area is calculated like this:

    Math.Abs((a[0] – c[0])*(b[1] -c[1]) – (a[1]-c[1])*(b[0]-c[0]));

    instead of this (like in the formula form wiki)

    Math.Abs((a[0] – c[0])*(b[1] -c[1]) – (a[1]-c[1])*(b[0]-c[0]));

  4. Eman says:

    aaa sorry I posted it wrong it should be:

    instead of this (like in the formula form wiki)

    Math.Abs((a[0] – c[0])*(b[1] -a[1]) – (a[0]-b[0])*(c[1]-a[1]));

  5. Kristian says:

    That looks more like a mistake than anything else. You can see that the formula I write is different from the code implementation. It is possible that you can write it both ways, but I think I should be consistent.

    I will change that, and thanks for noticing.

  6. Kal says:

    It might be faster to use Barycentric Coordinates. Essentially, given triangle ABC, you get two vectors AB and AC and, for any point P, you write P = u(AB) + v(AC). If u and v are both in (0, 1) then P is in the interior of ABC.

  7. Kristian says:

    I touched on Barycentric coordinates. However, I dismissed the idea for this one, I just don’t remember why. But you are certainly right that it is a valid way to go.

Leave a Comment Here's Your Chance to Be Heard!

You can use these html tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

You can use short tags like: [code language="language"][/code]

The code tag supports the following languages: as3, bash, coldfusion, c, cpp, csharp, css, delphi, diff,erlang, groovy, javascript, java, javafx, perl, php, plain, powershell, python, ruby, scala, sql, tex, vb, xml

You can use [latex]your formula[/latex] if you want to format something using latex

Notify me of comments via e-mail. You can also subscribe without commenting.