0
votes

I have line that is defined as two points. start = (xs,ys) end = (xe, ye)

Drawing function that I'm using Only accepts lines that are fully in screen coordinates. Screen size is (xSize, ySize).

Top left corner is (0,0). Bottom right corner is (xSize, ySize).

Some other funcions gives me line that that is defined for example as start(-50, -15) end(5000, 200). So it's ends are outside of screen size.

In C++

struct Vec2
{
 int x, y
};

Vec2 start, end //This is all little bit pseudo code
Vec2 screenSize;//You can access coordinates like start.x end.y

How can I calculate new start and endt that is at the screen edge, not outside screen. I know how to do it on paper. But I can't transfer it to c++. On paper I'm sershing for point that belongs to edge and line. But it is to much calculations for c++.

Can you help?

1
The Cohen–Sutherland algorithm is generally considered to be a fast solution to this very common problem.acraig5075

1 Answers

5
votes

There are many line clipping algorithms like:

[EDIT1] See below figure: enter image description here

there are 3 kinds of start point:

  1. sx > 0 and sy < 0 (red line)
  2. sx < 0 and sy > 0 (yellow line)
  3. sx < 0 and sy < 0 (green and violet lines)

In situations 1 and 2 simply find Xintersect and Yintersect respectively and choose them as new start point. As you can see, there are 2 kinds of lines in situation 3. In this situation find Xintersect and Yintersect and choose the intersect point near the end point which is the point that has minimum distance to endPoint.

min(distance(Xintersect, endPoint), distance(Yintersect, endPoint))

[EDIT2]

// Liang-Barsky function by Daniel White @ http://www.skytopia.com/project/articles/compsci/clipping.html
// This function inputs 8 numbers, and outputs 4 new numbers (plus a boolean value to say whether the clipped line is drawn at all).
//
bool LiangBarsky (double edgeLeft, double edgeRight, double edgeBottom, double edgeTop,   // Define the x/y clipping values for the border.
                  double x0src, double y0src, double x1src, double y1src,                 // Define the start and end points of the line.
                  double &x0clip, double &y0clip, double &x1clip, double &y1clip)         // The output values, so declare these outside.
{

    double t0 = 0.0;    double t1 = 1.0;
    double xdelta = x1src-x0src;
    double ydelta = y1src-y0src;
    double p,q,r;

    for(int edge=0; edge<4; edge++) {   // Traverse through left, right, bottom, top edges.
        if (edge==0) {  p = -xdelta;    q = -(edgeLeft-x0src);  }
        if (edge==1) {  p = xdelta;     q =  (edgeRight-x0src); }
        if (edge==2) {  p = -ydelta;    q = -(edgeBottom-y0src);}
        if (edge==3) {  p = ydelta;     q =  (edgeTop-y0src);   }   
        r = q/p;
        if(p==0 && q<0) return false;   // Don't draw line at all. (parallel line outside)

        if(p<0) {
            if(r>t1) return false;         // Don't draw line at all.
            else if(r>t0) t0=r;            // Line is clipped!
        } else if(p>0) {
            if(r<t0) return false;      // Don't draw line at all.
            else if(r<t1) t1=r;         // Line is clipped!
        }
    }

    x0clip = x0src + t0*xdelta;
    y0clip = y0src + t0*ydelta;
    x1clip = x0src + t1*xdelta;
    y1clip = y0src + t1*ydelta;

    return true;        // (clipped) line is drawn
}