C# wpf 3D 面向 Origo

发布于 2024-12-05 02:39:46 字数 1104 浏览 0 评论 0原文

如果我有三个点并且总是希望可见面应该是从原点“面向”的一侧,是否有计算平面法线的快捷方式?

像这样

        mesh.Positions.Add(p0);
        mesh.Positions.Add(p1);
        mesh.Positions.Add(p2);

        mesh.TriangleIndices.Add(0);
        mesh.TriangleIndices.Add(1);
        mesh.TriangleIndices.Add(2);


        normal = Vector3D(1,1,1);

        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);

        model = new GeometryModel3D(mesh, material);

还是我每次都必须计算正常?

如果我必须计算法线,那么算法是什么,我在互联网上查找并尝试了几种方法,但它们让我怀疑,就像这个。

        normal = CalculateNormal(p0, p1, p2);

其中CalculateNormal

    public static Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2)
    {
        Vector3D v0 = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
        Vector3D v1 = new Vector3D(p1.X - p2.X, p1.Y - p2.Y, p2.Z - p1.Z);

        return Vector3D.CrossProduct(v0, v1);
    }

不应该是

Vector3D v1 = new Vector3D(p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z);

反而 ?

/斯特凡

If I have three points and always want the visible face should be the side that is "facing" from origo, is there a shortcut to calculate the normal of the plane ?

Like this

        mesh.Positions.Add(p0);
        mesh.Positions.Add(p1);
        mesh.Positions.Add(p2);

        mesh.TriangleIndices.Add(0);
        mesh.TriangleIndices.Add(1);
        mesh.TriangleIndices.Add(2);


        normal = Vector3D(1,1,1);

        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);

        model = new GeometryModel3D(mesh, material);

Or do I have to calculate the normal every time ?

If I have to calculate the normal, what is the algorithm for that, I have looked on the internet and tried a couple methods but they make me suspicious, like this one.

        normal = CalculateNormal(p0, p1, p2);

Where CalculateNormal is

    public static Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2)
    {
        Vector3D v0 = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
        Vector3D v1 = new Vector3D(p1.X - p2.X, p1.Y - p2.Y, p2.Z - p1.Z);

        return Vector3D.CrossProduct(v0, v1);
    }

should it not be

Vector3D v1 = new Vector3D(p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z);

instead ?

/Stefan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我的黑色迷你裙 2024-12-12 02:39:46

下面的效果很好

    private Model3DGroup CreateTriangleSide(Point3D p0, Point3D p1, Point3D p2, Material material)
    {
        MeshGeometry3D mesh = null;
        GeometryModel3D model = null;
        Model3DGroup group = new Model3DGroup();
        Vector3D normal;

        //
        // Front side of jagged part
        //
        mesh = new MeshGeometry3D();

        mesh.Positions.Add(p0);
        mesh.Positions.Add(p1);
        mesh.Positions.Add(p2);

        mesh.TriangleIndices.Add(0);
        mesh.TriangleIndices.Add(1);
        mesh.TriangleIndices.Add(2);

        normal = CalculateNormal(p0, p1, p2);
        normal = Normalize(normal);

        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);

        model = new GeometryModel3D(mesh, material);
        group.Children.Add(model);
        //
        // Front side of the surface below the jagged edge
        //
        Point3D p3 = new Point3D(p1.X, p1.Y, bh);
        Point3D p4 = new Point3D(p2.X, p2.Y, bh);

        return group;
    }



    public const double RADDEGC = (Math.PI / 180.0);

    public enum ANGLETYPE { RAD, DEG };

    /*
     * Takes the angle and the Z value to create a 3D point in space
     * 
     * @param angle The angle 
     * @param radius The radius of the circle 
     * @param z The z value
     * @param t The angle type, for example RAD (radians) or DEG (degress
     * 
     */
    public static Point3D CP(double radius, double angle, double z = 0, ANGLETYPE angtype = ANGLETYPE.RAD)
    {
        Point3D p = new Point3D();

        p.Z = z;
        //
        if (angtype ==  ANGLETYPE.RAD)
        {
            p.X = radius * Math.Cos(angle);
            p.Y = radius * Math.Sin(angle);
        }
        else
        {
            p.X = radius * Math.Cos(angle * RADDEGC);
            p.Y = radius * Math.Sin(angle * RADDEGC);
        }

        return p;
    }

    public static Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2)
    {
        Vector3D a1 = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
        Vector3D b1 = new Vector3D(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);

        Vector3D dir = Vector3D.CrossProduct(a1, b1);

        return dir;
    }


    public static Vector3D Normalize(Vector3D norm)
    {
        double fac1 = Math.Sqrt((norm.X * norm.X) + (norm.Y * norm.Y) + (norm.Z * norm.Z));

        if (fac1 == 0)
        {
            return norm;
        }
        norm = new Vector3D(norm.X / fac1, norm.Y / fac1, norm.Z / fac1);

        return norm;
    }

The following works well

    private Model3DGroup CreateTriangleSide(Point3D p0, Point3D p1, Point3D p2, Material material)
    {
        MeshGeometry3D mesh = null;
        GeometryModel3D model = null;
        Model3DGroup group = new Model3DGroup();
        Vector3D normal;

        //
        // Front side of jagged part
        //
        mesh = new MeshGeometry3D();

        mesh.Positions.Add(p0);
        mesh.Positions.Add(p1);
        mesh.Positions.Add(p2);

        mesh.TriangleIndices.Add(0);
        mesh.TriangleIndices.Add(1);
        mesh.TriangleIndices.Add(2);

        normal = CalculateNormal(p0, p1, p2);
        normal = Normalize(normal);

        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);
        mesh.Normals.Add(normal);

        model = new GeometryModel3D(mesh, material);
        group.Children.Add(model);
        //
        // Front side of the surface below the jagged edge
        //
        Point3D p3 = new Point3D(p1.X, p1.Y, bh);
        Point3D p4 = new Point3D(p2.X, p2.Y, bh);

        return group;
    }



    public const double RADDEGC = (Math.PI / 180.0);

    public enum ANGLETYPE { RAD, DEG };

    /*
     * Takes the angle and the Z value to create a 3D point in space
     * 
     * @param angle The angle 
     * @param radius The radius of the circle 
     * @param z The z value
     * @param t The angle type, for example RAD (radians) or DEG (degress
     * 
     */
    public static Point3D CP(double radius, double angle, double z = 0, ANGLETYPE angtype = ANGLETYPE.RAD)
    {
        Point3D p = new Point3D();

        p.Z = z;
        //
        if (angtype ==  ANGLETYPE.RAD)
        {
            p.X = radius * Math.Cos(angle);
            p.Y = radius * Math.Sin(angle);
        }
        else
        {
            p.X = radius * Math.Cos(angle * RADDEGC);
            p.Y = radius * Math.Sin(angle * RADDEGC);
        }

        return p;
    }

    public static Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2)
    {
        Vector3D a1 = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
        Vector3D b1 = new Vector3D(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);

        Vector3D dir = Vector3D.CrossProduct(a1, b1);

        return dir;
    }


    public static Vector3D Normalize(Vector3D norm)
    {
        double fac1 = Math.Sqrt((norm.X * norm.X) + (norm.Y * norm.Y) + (norm.Z * norm.Z));

        if (fac1 == 0)
        {
            return norm;
        }
        norm = new Vector3D(norm.X / fac1, norm.Y / fac1, norm.Z / fac1);

        return norm;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文