剪辑线到屏幕坐标

时间:2012-06-25 18:12:33

标签: c++ math graphics vector 2d

我的行被定义为两点。 start =(xs,ys) 结束=(xe,ye)

我正在使用的绘图功能仅接受完全在屏幕坐标中的线条。 屏幕尺寸为(xSize,ySize)。

左上角是(0,0)。右下角是(xSize,ySize)。

其他一些函数给我的行定义为例如start(-50,-15)end(5000,200)。所以它的结束是在屏幕尺寸之外。

在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

如何计算屏幕边缘的新起点和终点,而不是屏幕外部。 我知道怎么在纸上做。但我无法将其转移到c ++。 在纸面上,我正在为属于边缘和线条的点进行搜索。但这是对c ++的大量计算。

你能帮忙吗?

1 个答案:

答案 0 :(得分:5)

有许多线裁剪算法,如:

<强> [EDIT1] 见下图: enter image description here

有三种起点:

  1. sx&gt; 0和sy&lt; 0(红线)
  2. sx&lt; 0和sy&gt; 0(黄线)
  3. sx&lt; 0和sy&lt; 0(绿线和紫线)
  4. 在情境1和2中,分别只能找到Xintersect和Yintersect,并选择它们作为新的起点。 如您所见,情况3中有两种线。在这种情况下,找到Xintersect和Yintersect并选择终点附近的交点,这是与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
    }