0

質問に入る前に、少し背景が役立つと思います。私がやっていることは、楽しみのために、xna で独自の小さな 2D 物理ライブラリを作成することです。これは私にとって初めての独立した xna プロジェクトでもあり、3D ツールを使用するのも初めてなので、すべておかしなことをしている可能性があります。とにかく、私は現在、コンストラクターが の形で任意の 3 点を取る三角形クラスを作成していVector2sます。コンストラクターでは、これらのポイントを時計回りに配置し (カリングされないように)、対応するテクスチャ座標を見つける必要があります (VertexPositionTextures頂点として使用しているため)。私が持っているものは機能しますが、非常に長く複雑に思えます。コードを短縮/簡素化する方法を探しています。これは次のとおりです。

public PTriangle(Vector2 a, Vector2 b, Vector2 c)
    : base()
{
    //set up vertices
    VertexPositionTexture[] vertices = new VertexPositionTexture[3];

        //center vertices around origin
    Vector2 center = new Vector2((a.X + b.X + c.X) / 3, (a.Y + b.Y + c.Y) / 3);
    Vector2 newA = a - center;
    Vector2 newB = b - center;
    Vector2 newC = c - center;

        //get angle of each vertex (clockwise from -x axis)
    double angleA = MathHelper.Pi - Math.Atan((double)(newA.Y / newA.X));
    double angleB = MathHelper.Pi - Math.Atan((double)(newB.Y / newB.X));
    double angleC = MathHelper.Pi - Math.Atan((double)(newC.Y / newC.X));
    if (newA.X < 0)
    {
        if (newA.Y < 0)
        {
            angleA += MathHelper.Pi;
        }
        else
        {
            angleA -= MathHelper.Pi;
        }
    }
    if (newB.X < 0)
    {
        if (newB.Y < 0)
        {
            angleB += MathHelper.Pi;
        }
        else
        {
             angleB -= MathHelper.Pi;
        }
    }
    if (newC.X < 0)
    {
        if (newC.Y < 0)
        {
            angleC += MathHelper.Pi;
        }
        else
        {
            angleC -= MathHelper.Pi;
        }
    }

        //order vertices by angle
    Vector2[] newVertices = new Vector2[3];
    if (angleA < angleB && angleA < angleC)
    {
        newVertices[0] = newA;
        if (angleB < angleC)
        {
            newVertices[1] = newB;
            newVertices[2] = newC;
        }
        else
        {
            newVertices[1] = newC;
            newVertices[2] = newB;
        }
    }
    else if (angleB < angleA && angleB < angleC)
    {
        newVertices[0] = newB;
        if (angleA < angleC)
        {
            newVertices[1] = newA;
            newVertices[2] = newC;
        }
        else
        {
            newVertices[1] = newC;
            newVertices[2] = newA;
        }
    }
    else
    {
        newVertices[0] = newC;
        if (angleA < angleB)
        {
            newVertices[1] = newA;
            newVertices[2] = newB;
        }
        else
        {
            newVertices[1] = newB;
            newVertices[2] = newA;
        }
    }

        //set positions of vertices
    vertices[0].Position = new Vector3(newVertices[0] + center, 0);
    vertices[1].Position = new Vector3(newVertices[1] + center, 0);
    vertices[2].Position = new Vector3(newVertices[2] + center, 0);

        //get width and height of triangle
    float minX = 0;
    float minY = 0;
    float maxX = 0;
    float maxY = 0;
    foreach (Vector2 vertex in newVertices)
    {
        if (vertex.X < minX)
        {
            minX = vertex.X;
        }
        else if (vertex.X > maxX)
        {
            maxX = vertex.X;
        }
        if (vertex.Y < minY)
        {
            minY = vertex.Y;
        }
        else if (vertex.Y > maxY)
        {
            maxY = vertex.Y;
        }
    }
    float width = maxX - minX;
    float height = maxY - minY;

        //shift triangle so fits in quadrant IV, and set texture coordinates
    for (int index = 0; index < newVertices.Length; ++index)
    {
        newVertices[index].X -= minX;
        newVertices[index].Y -= minY;

        vertices[index].TextureCoordinate = new Vector2(
            newVertices[index].X / width,
            1 - (newVertices[index].Y / height));
    }

    this.Vertices = vertices;

    //set up indices
    this.Indices = new short[] { 0, 1, 2 };
}
4

1 に答える 1

4

3 点を時計回りに並べるには、反時計回りテスト (または左回転テスト) を使用して 3 点の方向を確認できます。

ウィキペディアの疑似コード

# Three points are a counter-clockwise turn if ccw > 0, clockwise if
# ccw < 0, and collinear if ccw = 0 because ccw is a determinant that
# gives the signed area of the triangle formed by p1, p2 and p3.
function ccw(p1, p2, p3):
    return (p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x)

3 点が反時計回りの場合は、最後の 2 点を入れ替えて 3 点を時計回りに並べることができます。

于 2012-06-25T10:09:21.133 に答える