0

Given a vector (or two points) how can i get the discrete coordinates that this vector intersects in some given interval?

I am using this such that given a ray(vector) i can calculate the pixels in an image that this ray intersects and use these as indexes for my image. The ray is always in the plane of the image in the case of 3D.

Also the vector comes from another coordinate system than the one used for the image indexes, but this is just a scaling between coordinate systems.

I'm looking for a solution in 3D but 2D can be accepted.

EDIT: The interval is a 2d space, so the solution is a set of points in this 2d interval. And this will be run on a GPU with CUDAfy.NET

smok
  • 355
  • 3
  • 16
  • what framework are you using? usually there are built in functions that do exactly this job... – Florian Schmidinger Mar 09 '15 at 13:49
  • None, just C#. Want to use it together with CUDAfy so I don't think I can use it with another framework – smok Mar 09 '15 at 13:52
  • You can use whatever framework you want... put it in an extra library if you want to seperate them. – Florian Schmidinger Mar 09 '15 at 14:02
  • I need to put an attribute [cudafy] on the class/method that I want to use. How would i do that if i use another framework? – smok Mar 09 '15 at 14:08
  • Using delegation to the extra library encapsulating all functions you need from another framework... no biggy – Florian Schmidinger Mar 09 '15 at 14:13
  • This will be run on the GPU and memory has to be transferred to it. Using a framework I would have to transfer complex type I have no control over, when the only types that can transferred are more or less simple types and structs. I am a beginner with CUDAfy but can't see how this would work. – smok Mar 09 '15 at 14:22
  • I see the problem... to be honest no clue either... – Florian Schmidinger Mar 09 '15 at 14:28

3 Answers3

0

Your vector P1,P2 is all these points:

vector := P1 + a * (P2-P1)  with a in [0;1]

Yout intervall P3,P4 is all these points:

interval := P3 + b * (P4 - P3)  with b in [0,1]

They interscet in the same point:

vector == interval
P1 + a * (P2-P1) == P3 + b * (P4-P3)

In 2d these are two equations with two unknowns -> solvable

DrKoch
  • 9,556
  • 2
  • 34
  • 43
  • Cant see what this would help. The interval in my case is the width/height of the image. Or maybe i'm missing something – smok Mar 09 '15 at 14:06
0

Here are my assumptions:

  • the bottom-left corner of your image is the origin (the point with coordinates (0, 0))
  • you have an image with width w and height h
  • you can put the vector in the form of a linear equation (i.e., y=mx+b, where m is the slope and b is the y-intercept)

Given those assumptions, do the following to find the discrete coordinates where the line intersects the edges of your image:

    /// <summary>
    /// Find discreet coordinates where the line y=mx+b intersects the edges of a w-by-h image.
    /// </summary>
    /// <param name="m">slope of the line</param>
    /// <param name="b">y-intercept of the line</param>
    /// <param name="w">width of the image</param>
    /// <param name="h">height of the image</param>
    /// <returns>the points of intersection</returns>
    List<Point> GetIntersectionsForImage(double m, double b, double w, double h)
    {
        var intersections = new List<Point>();

        // Check for intersection with left side (y-axis).
        if (b >= 0 && b <= h)
        {
            intersections.Add(new Point(0.0, b));
        }

        // Check for intersection with right side (x=w).
        var yValRightSide = m * w + b;
        if (yValRightSide >= 0 && yValRightSide <= h)
        {
            intersections.Add(new Point(w, yValRightSide));
        }

        // If the slope is zero, intersections with top or bottom will be taken care of above.
        if (m != 0.0)
        {
            // Check for intersection with top (y=h).
            var xValTop = (h - b) / m;
            if (xValTop >= 0 && xValTop <= w)
            {
                intersections.Add(new Point(xValTop, h));
            }

            // Check for intersection with bottom (y=0).
            var xValBottom = (0.0 - b) / m;
            if (xValBottom >= 0 && xValBottom <= w)
            {
                intersections.Add(new Point(xValBottom, 0));
            }
        }

        return intersections;
    }

And here are the tests to make sure it works:

    [TestMethod]
    public void IntersectingPoints_AreCorrect()
    {
        // The line y=x intersects a 1x1 image at points (0, 0) and (1, 1).
        var results = GetIntersectionsForImage(1.0, 0.0, 1.0, 1.0);
        foreach (var p in new List<Point> { new Point(0.0, 0.0), new Point(1.0, 1.0) })
        {
            Assert.IsTrue(results.Contains(p));
        }

        // The line y=1 intersects a 2x2 image at points (0, 1), and (2, 1).
        results = GetIntersectionsForImage(0.0, 1.0, 2.0, 2.0);
        foreach (var p in new List<Point> { new Point(0.0, 1.0), new Point(2.0, 1.0) })
        {
            Assert.IsTrue(results.Contains(p));
        }
    }
Kaitlin Hipkin
  • 189
  • 1
  • 11
0

After a bit of searching I found Bresenham's line algorithm which was more or less just what I needed.

Please refer to this answer if you're interested in the algorithm I used.

Community
  • 1
  • 1
smok
  • 355
  • 3
  • 16