How many integer points within the three points forming a triangle?

后端 未结 13 1272
一个人的身影
一个人的身影 2020-12-12 21:04

Actually this is a classic problem as SO user Victor put it (in another SO question regarding which tasks to ask during an interview).

I couldn\'t do it in an hour

相关标签:
13条回答
  • 2020-12-12 21:28

    Here's another method, not necessarily the best, but sure to impress any interviewer.

    First, call the point with the lowest X co-ord 'L', the point with the highest X co-ord 'R', and the remaining point 'M' (Left, Right, and Middle).

    Then, set up two instances of Bresenham's line algorithm. Parameterize one instance to draw from L to R, and the second to draw from L to M. Run the algorithms simultaneously for X = X[L] to X[M]. But instead of drawing any lines or turning on any pixels, count the pixels between the lines.

    After stepping from X[L] to X[M], change the parameters of the second Bresenham to draw from M to R, then continue to run the algorithms simultaneously for X = X[M] to X[R].

    This is very similar to the solution proposed by Erwin Smout 7 hours ago, but using Bresenham instead of a line-slope formula.

    I think that in order to count the columns of pixels, you will need to determine whether M lies above or below the line LR, and of course special cases will arise when two points have the same X or Y co-ordinate. But by the time this comes up, your interviewer will be suitably awed and you can move on to the next question.

    0 讨论(0)
  • 2020-12-12 21:29

    I'd go like this :

    Take the uppermost point of the triangle (the one with the highest Y coordinate). There are two "slopes" starting at that point. It's not the general solution, but for easy visualisation, think of one of both "going to the left" (decreasing x coordinates) and the other one "going to the right".

    From those two slopes and any given Y coordinate less than the highest point, you should be able to compute the number of integer points that appear within the bounds set by the slopes. Iterating over decreasing Y coordinates, add all those number of points together.

    Stop when your decreasing Y coordinates reach the second-highest point of the triangle.

    You have now counted all points "above the second-highest point", and you are now left with the problem of "counting all the points within some (much smaller !!!) triangle, of which you know that its upper side parallels the X-axis.

    Repeat the same procedure, but now with taking the "leftmost point" instead of the "uppermost", and with proceedding "by increasing x", instead of by "decreasing y".

    After that, you are left with the problem of counting all the integer points within a, once again much smaller, triangle, of which you know that its upper side parallels the X-axis, and its left side parallels the Y-axis.

    Keep repeating (recurring), until you count no points in the triangle you're left with.

    (Have I now made your homework for you ?)

    0 讨论(0)
  • 2020-12-12 21:31

    Pick's theorem (http://en.wikipedia.org/wiki/Pick%27s_theorem) states that the surface of a simple polygon placed on integer points is given by:

    A = i + b/2 - 1
    

    Here A is the surface of the triangle, i is the number of interior points and b is the number of boundary points. The number of boundary points b can be calculated easily by summing the greatest common divisor of the slopes of each line:

    b =   gcd(abs(p0x - p1x), abs(p0y - p1y)) 
        + gcd(abs(p1x - p2x), abs(p1y - p2y)) 
        + gcd(abs(p2x - p0x), abs(p2y - p0y))
    

    The surface can also be calculated. For a formula which calculates the surface see https://stackoverflow.com/a/14382692/2491535 . Combining these known values i can be calculated by:

    i = A + 1 - b/2
    
    0 讨论(0)
  • 2020-12-12 21:31

    My knee-jerk reaction would be to brute-force it:

    • Find the maximum and minimum extent of the triangle in the x and y directions.
    • Loop over all combinations of integer points within those extents.
    • For each set of points, use one of the standard tests (Same side or Barycentric techniques, for example) to see if the point lies within the triangle. Since this sort of computation is a component of algorithms for detecting intersections between rays/line segments and triangles, you can also check this link for more info.
    0 讨论(0)
  • 2020-12-12 21:33

    (wierd) pseudo-code for a bit-better-than-brute-force (it should have O(n))
    i hope you understand what i mean

    n=0
    p1,p2,p3 = order points by xcoordinate(p1,p2,p3)
    for int i between p1.x and p2.x do
      a = (intersection point of the line p1-p2 and the line with x==i).y 
      b = (intersection point of the line p1-p3 and the line with x==i).y
      n += number of integers between floats (a, b)
    end
    for i between p2.x+1 and p3.x do
      a = (intersection point of the line p2-p3 and the line with x==i).y 
      b = (intersection point of the line p1-p3 and the line with x==i).y
      n += number of integers between floats (a, b)
    end
    

    this algorithm is rather easy to extend for vertices of type float (only needs some round at the "for i.." part, with a special case for p2.x being integer (there, rounded down=rounded up))
    and there are some opportunities for optimization in a real implementation

    0 讨论(0)
  • 2020-12-12 21:43

    This is called the "Point in the Triangle" test.

    Here is an article with several solutions to this problem: Point in the Triangle Test.

    alt text

    A common way to check if a point is in a triangle is to find the vectors connecting the point to each of the triangle's three vertices and sum the angles between those vectors. If the sum of the angles is 2*pi (360-degrees) then the point is inside the triangle, otherwise it is not.

    0 讨论(0)
提交回复
热议问题