Search code examples
javalinegraphics2djava-2d

Draw an infinite line through 2 points?


I'm looking for a way to draw an infinite line (a line with no end, also known as a ray) through 2 points. I can draw a line between 2 points with Line2D, no problem here.

Next the infinite part needed a look. With my simple mind I thought, lets multiply the x and y coordinates from the second point with 100 and redraw the line. This works, but only in simple cases.

For example here is a case in which it produces lines with different angles:

    g.setColor(Color.red);
    g2.setStroke(new BasicStroke(4.0f));
    g2.draw(new Line2D.Double(0, 61.632653061218946, 944, 217.25510204080692));
    g.setColor(Color.blue);
    g2.setStroke(new BasicStroke(1.0f));
    g2.draw(new Line2D.Double(0, 61.632653061218946, 944*10, 217.25510204080692*10));

This will first draw a fat red line, next it will draw a blue thin line.

The blue line has a different angle compared the the red line. Here's a screenshot to illustrate this effect:

enter image description here

Does somebody know a way to fix this, or maybe a better way to draw a infinite line through 2 points?


Solution

  • Let's do the math for a second.

    • The first line is (0, 61.632653061218946)-(944, 217.25510204080692). Slope is rise/run, therefore m = 0.16485428917329234533898305084746.
    • The second line is (0, 61.632653061218946)-(9440, 2172.5510204080692); m = 0.22361423382911549300847457627119.

    The slopes are different, which is just another way of saying the angles are different.

    What you need to do is extend the line. You cannot just multiply both coordinates of one of the points by 10. First determine either an x or a y beyond the bounds of your canvas, then solve for the other value.

    How do you do this?

    1. First, get the equation for the line. A line is defined by y=m*x+b, where m is the slope, and b is the y-intercept.

      1. We already know how to calculate the slope (rise/run = y2 - y1 / x2 - x1). We get 0.16485428917329234533898305084746
      2. Plug in the slope and solve for b (y - m*x), you get 61.632653061218946. In your case you already have this value as the y-intercept is the y-coordinate when x=0.
      3. You then get the equation y = 0.16485428917329234533898305084746 * x + 61.632653061218946
    2. Now, pick a sufficiently large x, say 10000. Plug this value in and solve for y. You get 1710.1755447941423993898305084746.

    3. Finally, draw your line to this new point, (0, 61.632653061218946)-(10000,1710.1755447941423993898305084746)

    Great, now let's generalize this.

    • We have two points (x1, y1) and (x2, y2). We want to solve for (10000, y3).
    • Therefore, y3 = m*x3 + b, or y3 = m * 10000 + b.
    • We also know that b = y - m * x, so plugging this in and arbitrarily choosing point 1, y3 = m * 10000 + y1 - m * x1.
    • Ok, let's factor out the m: y3 = m * (10000 + x1) - y1.
    • We know m = (y2 - y1) / (x2 - x1), so plugging this in: y3 = ((y2 - y1) / (x2 - x1)) * (10000 + x1) - y1.

    If your line doesn't start at x = 0, you will need to repeat this process for x = 0, meaning you should plot a line (0, ((y2 - y1) / (x2 - x1)) * x1 - y1)-(10000,((y2 - y1) / (x2 - x1)) * (10000 + x1) - y1).

    Note: If x2 - x1 is 0, you have an infinite slope. This is a vertical line, and you'll have to handle this case separately.