9

glLineWidth を使用せずに可変幅の線を描画する最良の方法は何ですか? 長方形を描くだけですか?平行線いろいろ?上記のどれでもない?

4

7 に答える 7

14

次の 2 つの三角形を描くことができます。

// Draws a line between (x1,y1) - (x2,y2) with a start thickness of t1 and
// end thickness t2.
void DrawLine(float x1, float y1, float x2, float y2, float t1, float t2)
{
    float angle = atan2(y2 - y1, x2 - x1);
    float t2sina1 = t1 / 2 * sin(angle);
    float t2cosa1 = t1 / 2 * cos(angle);
    float t2sina2 = t2 / 2 * sin(angle);
    float t2cosa2 = t2 / 2 * cos(angle);

    glBegin(GL_TRIANGLES);
    glVertex2f(x1 + t2sina1, y1 - t2cosa1);
    glVertex2f(x2 + t2sina2, y2 - t2cosa2);
    glVertex2f(x2 - t2sina2, y2 + t2cosa2);
    glVertex2f(x2 - t2sina2, y2 + t2cosa2);
    glVertex2f(x1 - t2sina1, y1 + t2cosa1);
    glVertex2f(x1 + t2sina1, y1 - t2cosa1);
    glEnd();
}
于 2008-09-19T14:16:09.740 に答える
9

わかりました、これはどうですか: (オズガー)

       あ
      / \
     / \
    . p1 \
   / \
  / 日
 B - .p2
      - - - C

つまり、AB はwidth1で、CD はwidth2です。

それで、

// find line between p1 and p2
Vector p1p2 = p2 - p1 ;

// find a perpendicular
Vector perp = p1p2.perpendicular().normalize()

// Walk from p1 to A
Vector A = p1 + perp*(width1/2)
Vector B = p1 - perp*(width1/2)

Vector C = p2 - perp*(width2/2)
Vector D = p2 - perp*(width2/2)

// wind triangles
Triangle( A, B, D )
Triangle( B, D, C )

このアルゴリズムには CW/CCW 巻きの問題がある可能性があることに注意してください。上図で perp が (-y, x) として計算される場合は CCW 巻きになり、(y, -x) の場合は CW 巻きになります。 .

于 2010-07-22T23:42:31.450 に答える
2

これに対する優れたソリューションを探している人のために、このコードはLWJGLを使用して記述されていますが、OpenGLの任意の実装に簡単に適合させることができます。

import java.awt.Color;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
public static void DrawThickLine(int startScreenX, int startScreenY, int endScreenX, int endScreenY, Color color, float alpha, float width) {

    Vector2f start = new Vector2f(startScreenX, startScreenY);
    Vector2f end = new Vector2f(endScreenX, endScreenY);

    float dx = startScreenX - endScreenX;
    float dy = startScreenY - endScreenY;

    Vector2f rightSide = new Vector2f(dy, -dx);
    if (rightSide.length() > 0) {
        rightSide.normalise();
        rightSide.scale(width / 2);
    }
    Vector2f leftSide = new Vector2f(-dy, dx);
    if (leftSide.length() > 0) {
        leftSide.normalise();
        leftSide.scale(width / 2);
    }

    Vector2f one = new Vector2f();
    Vector2f.add(leftSide, start, one);

    Vector2f two = new Vector2f();
    Vector2f.add(rightSide, start, two);

    Vector2f three = new Vector2f();
    Vector2f.add(rightSide, end, three);

    Vector2f four = new Vector2f();
    Vector2f.add(leftSide, end, four);

    GL11.glBegin(GL11.GL_QUADS);
    GL11.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), alpha);
    GL11.glVertex3f(one.x, one.y, 0);
    GL11.glVertex3f(two.x, two.y, 0);
    GL11.glVertex3f(three.x, three.y, 0);
    GL11.glVertex3f(four.x, four.y, 0);
    GL11.glColor4f(1, 1, 1, 1);
    GL11.glEnd();
}
于 2011-05-04T01:12:08.177 に答える
2

今日も同じことをしなければなりませんでした。

(x1,y1) -> (x2,y2)特定のにまたがる線を作成するための非常に簡単な方法は、以下を使用しwidthて単純な単位サイズの正方形を変換することです。(0., -0.5) -> (1., 0.5)

  1. glTranslatef(...)(x1,y1)目的の場所に移動します。
  2. glScalef(...)length必要に応じて右にスケーリングするにはwidthlength = sqrt( (x2-x1)^2 + (y2-y1)^2 )またはその他の複雑さの低い近似を使用します。
  3. glRotatef(...)angle正しい向きに: を使用しますangle = atan2(y2-y1, x2-x1)

単位正方形はGL_TRIANGLE_STRIP、上記の変換後に実線に変わる 2 つの三角形のストリップから非常に単純に作成されます。

ここでの負担は、アプリケーション コードではなく、主に OpenGL (およびグラフィック ハードウェア) にかかります。上記の手順は、glPushMatrix()andglPopMatrix()呼び出しを囲むことにより、非常に簡単に一般的な関数に変換されます。

于 2010-11-08T04:36:32.810 に答える
1

これを行う別の方法として、たまたまソフトウェア ラスタライザーを作成している場合は、ピクセルの配色ステージで重心座標を使用し、重心座標の 1 つが 0 に近いときにピクセルに色を付ける方法があります。許容量が多いほど、線は太くなります。

于 2010-07-22T23:49:36.190 に答える
1

四角形 (つまり、GL_QUAD または 2 つの GL_TRIANGLES) は、その音からすると最善の策のように聞こえますが、他の方法を考えられるかどうかはわかりません。

于 2008-09-19T14:16:14.047 に答える
1

元のポイントが (x1,y1) -> (x2,y2) であると仮定します。次のポイント (x1-width/2, y1)、(x1+width/2,y1)、(x2-width/2, y2)、(x2+width/2,y2) を使用して長方形を作成し、次に使用します。 quads/tris で描画します。これは単純な単純な方法です。線幅が大きいと、エンドポイントの動作がおかしくなることに注意してください。次に本当にやりたいことは、ベクトル演算を使用したスマートな平行線計算 (それほど悪くはないはずです) です。何らかの理由で、ドット/クロス積とベクトル射影が思い浮かびます。

于 2008-09-19T19:49:04.980 に答える