C# 如何在DirectX中旋转后获得网格的一个向量?

C# 如何在DirectX中旋转后获得网格的一个向量?,c#,3d,directx,direct3d,coordinate-systems,C#,3d,Directx,Direct3d,Coordinate Systems,在我的项目中,我在三维坐标系中显示一些球体。见下图 每个球体显示一个lab-colorvalue。要创建球体,我使用DirectX中的Mesh函数: // Radius der Kugel private const float radius = 4f; // Die Anzahl der Ebenen einer Kugel private const int slices = 8; // Die Anzalh der Flächen einer Ebene private const in

在我的项目中,我在三维坐标系中显示一些球体。见下图

每个球体显示一个lab-colorvalue。要创建球体,我使用DirectX中的Mesh函数:

// Radius der Kugel
private const float radius = 4f;
// Die Anzahl der Ebenen einer Kugel
private const int slices = 8;
// Die Anzalh der Flächen einer Ebene
private const int stacks = 8;

// Das Mesh zum Darstellen der Kugel
private Mesh mesh = null;
private Vector3 vec;
public Vector3 min;
public Vector3 max;

public void createMesh(Device device, Color color, params float[] labValues)
{
    // Erstellt die Kugel mit der Anbindung an das Device
    mesh = Mesh.Sphere(device, radius, slices, stacks);
    // Kopiert das Mesh zum Erstellen des VertexArrays
    Mesh tempMesh = mesh.Clone(mesh.Options.Value, Vertex.FVF_Flags, device);
    // Erstellt den VertexArray
    Vertex[] vertData = (Vertex[])tempMesh.VertexBuffer.Lock(0, typeof(Vertex), LockFlags.None, tempMesh.NumberVertices);

    // Weist jedem Vertex die Farbe und die Position zu
    for (int i = 0; i < vertData.Length; ++i)
    {
        vertData[i].color = color.ToArgb();
        vertData[i].x += labValues[1];
        vertData[i].y += labValues[0] - 50f;
        vertData[i].z += labValues[2];
    }
    min = new Vector3(labValues[1], labValues[0] + 100f, labValues[2]);
    max = new Vector3(labValues[1], labValues[0] - 100f, labValues[2]);

    // Gibt den VertexBuffer in der Kopie frei
    tempMesh.VertexBuffer.Unlock();
    // Löscht den Mesh aus dem Speicher
    mesh.Dispose();
    // Legt die Kopie in der Meshinstanz ab
    mesh = tempMesh;

    Vector3 vTemp = new Vector3(labValues[1], labValues[0], labValues[2]);
    vec = vTemp;
}

struct Vertex
{
    public float x, y, z; // Position of vertex in 3D space
    public int color;     // Diffuse color of vertex

    /// <summary>
    /// Konstruktor der Vertex
    /// </summary>
    /// <param name="_x">X(A) - Position</param>
    /// <param name="_y">Y(L) - Position</param>
    /// <param name="_z">Z(B) - Position</param>
    /// <param name="_color">Die Farbe</param>
    public Vertex(float _x, float _y, float _z, int _color)
    {
        x = _x; y = _y; z = _z;
        color = _color;
    }

    // Das Format des Vertex
    public static readonly VertexFormats FVF_Flags = VertexFormats.Position | VertexFormats.Diffuse;
}
现在,我添加了一个函数来单击球体()以显示实验室值:

public Sphere getSphereByCoordinates(Device device, List<Sphere> meshList, Vector3 cameraVec, float x, float y)
{
    // Temporäre Liste für die Kugeln
    List<Sphere> tempSphereList = new List<Sphere>();
    Sphere closestSphere = null;

    // Instanz des dichten und fernen Vektors
    Vector3 v3Near = new Vector3(x, y, 0);
    Vector3 v3Far = new Vector3(x, y, 1);

    // Wandelt den 2D Vektor in einen 3D Vektor um
    v3Near.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World);
    v3Far.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World);
    // Subtrahiert die beiden Vektoren
    v3Far.Subtract(v3Near);

    // Geht jede einzelne Kugel durch
    foreach(Sphere tempSphere in meshList)
    {
        // Prüft ob sich die Punkte schneiden und fügt es ggf. einer Liste hinzu
        if(tempSphere.labMesh.Intersect(v3Near, v3Far))
            tempSphereList.Add(tempSphere);
        }

        // Die nächste Distanz
        double closestDistance = -1.0;
        // Geht alle zutreffenden Kugeln durch und sucht sich die nahste Kugel zur Kamera aus
        foreach(Sphere tempSphere in tempSphereList)
        {
            //VertexBuffer haha = tempSphere.labMesh.
            double theDistance = Distance(cameraVec, tempSphere.labVector);

            if (theDistance < closestDistance || closestDistance == -1d)
            {
                closestDistance = theDistance;
                closestSphere = tempSphere;
            }
        }

        return closestSphere;
    }

private double Distance(Vector3 v1, Vector3 v2)
{
    // Erstellt einen Differenzvektor
    Vector3 difference = new Vector3(   v1.X - v2.X, 
                                        v1.Y - v2.Y, 
                                        v1.Z - v2.Z);
    // Gibt die berechnete Distanz zurück
    `return Math.Sqrt(Math.Pow(difference.X, 2f) + Math.Pow(difference.Y, 2f) + Math.Pow(difference.Z, 2f));
}
公共球体getSphereByCoordinates(设备设备、列表网格列表、Vector3 cameraVec、浮点x、浮点y)
{
//库格伦临时名单
List tempsherelist=新列表();
Sphere closestSphere=null;
//dichten和fernen Vektors实例
vector3v3near=新的Vector3(x,y,0);
Vector3 v3Far=新的Vector3(x,y,1);
//Wandelt den 3D Vektor um中的2D Vektor
v3Near.Unproject(device.Viewport、device.Transform.Projection、device.Transform.View、device.Transform.World);
v3Far.Unproject(device.Viewport、device.Transform.Projection、device.Transform.View、device.Transform.World);
//贝登维克托伦酒店
v3Far.减法(v3Near);
//格特·杰德·埃恩泽尔·库格尔·杜奇
foreach(球体tempSphere在网格列表中)
{
//这是一本关于施耐登和ggf的书
if(tempSphere.labMesh.Intersect(v3Near,v3Far))
tempSphereList.Add(tempSphere);
}
//第nächste区
双近距离=-1.0;
//这一切都是因为我们的努力
foreach(tempSphereList中的球体tempSphere)
{
//VertexBuffer haha=tempSphere.labMesh。
距离加倍=距离(cameraVec、tempSphere.labVector);
如果(距离<最近距离| |最近距离==-1d)
{
最近距离=距离;
closestSphere=tempSphere;
}
}
返回封闭球;
}
专用双距离(Vector3 v1,Vector3 v2)
{
//Erstellet-einen微分器
Vector3差异=新Vector3(v1.X-v2.X,
v1.Y-v2.Y,
v1.Z-v2.Z);
//祖鲁克地区
`返回Math.Sqrt(Math.Pow(difference.X,2f)+Math.Pow(difference.Y,2f)+Math.Pow(difference.Z,2f));
}

如何查看我将所有与鼠标坐标相交的网格设置为临时列表。该算法工作正常。我的问题是现在获得正确的距离。因为我计算了距离摄影机向量和静态lab值向量的距离。在单击球体之前旋转设备时,如何将静态实验室值转换为设备世界?你知道解决办法吗?谢谢你的帮助

我怀疑您的交叉点代码是否有效,因为它没有考虑设备转换。无论如何,您都应该执行交叉点的分析计算<代码>网格.相交会变得非常慢,因为它必须检查每个三角形。您有球体的位置和半径。应根据这些值检查交点(请参见光线/点的距离)

如果要使用
Mesh.Intersect
,则必须变换光线,因为该方法仅考虑未变换的网格。因此,您需要一个转换来还原设备的旋转,这正是世界矩阵的倒数。看,还有。然后可以与变换后的光线执行相交


至于距离计算,你有两个选择。您可以使用逆世界矩阵变换相机位置,也可以使用(非逆)世界矩阵变换球体位置。

与您的问题无关,但请使用您的公共函数。。。()
public Sphere getSphereByCoordinates(Device device, List<Sphere> meshList, Vector3 cameraVec, float x, float y)
{
    // Temporäre Liste für die Kugeln
    List<Sphere> tempSphereList = new List<Sphere>();
    Sphere closestSphere = null;

    // Instanz des dichten und fernen Vektors
    Vector3 v3Near = new Vector3(x, y, 0);
    Vector3 v3Far = new Vector3(x, y, 1);

    // Wandelt den 2D Vektor in einen 3D Vektor um
    v3Near.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World);
    v3Far.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, device.Transform.World);
    // Subtrahiert die beiden Vektoren
    v3Far.Subtract(v3Near);

    // Geht jede einzelne Kugel durch
    foreach(Sphere tempSphere in meshList)
    {
        // Prüft ob sich die Punkte schneiden und fügt es ggf. einer Liste hinzu
        if(tempSphere.labMesh.Intersect(v3Near, v3Far))
            tempSphereList.Add(tempSphere);
        }

        // Die nächste Distanz
        double closestDistance = -1.0;
        // Geht alle zutreffenden Kugeln durch und sucht sich die nahste Kugel zur Kamera aus
        foreach(Sphere tempSphere in tempSphereList)
        {
            //VertexBuffer haha = tempSphere.labMesh.
            double theDistance = Distance(cameraVec, tempSphere.labVector);

            if (theDistance < closestDistance || closestDistance == -1d)
            {
                closestDistance = theDistance;
                closestSphere = tempSphere;
            }
        }

        return closestSphere;
    }

private double Distance(Vector3 v1, Vector3 v2)
{
    // Erstellt einen Differenzvektor
    Vector3 difference = new Vector3(   v1.X - v2.X, 
                                        v1.Y - v2.Y, 
                                        v1.Z - v2.Z);
    // Gibt die berechnete Distanz zurück
    `return Math.Sqrt(Math.Pow(difference.X, 2f) + Math.Pow(difference.Y, 2f) + Math.Pow(difference.Z, 2f));
}