0

2点として定義されている線があります。start =(xs、ys)end =(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++の多くの計算になります。

手伝ってくれますか?

4

1 に答える 1

5

次のような多くのラインクリッピングアルゴリズムがあります。

[編集1] 下の図を参照してください。 ここに画像の説明を入力してください

開始点には次の3種類があります。

  1. sx>0およびsy<0(赤い線)
  2. sx<0およびsy>0(黄色の線)
  3. sx<0およびsy<0(緑と紫の線)

状況1と2では、それぞれXintersectとYintersectを見つけて、それらを新しい開始点として選択します。ご覧のとおり、シチュエーション3には2種類の線があります。このシチュエーションでは、XintersectとYintersectを見つけて、endPointまでの距離が最小のポイントであるエンドポイントの近くの交点を選択します。

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

[編集2]

// 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
}
于 2012-06-25T18:47:20.287 に答える