如何在已知中心点,半径的3D中创建一个圆,并且它是在垂直于WPF中的直线的平面上?

时间:2013-01-07 11:40:49

标签: wpf 3d geometry

如何使用已知的中心点,半径在3D中创建一个圆,并且它位于与WPF中的直线(矢量)垂直的平面上?

1 个答案:

答案 0 :(得分:3)

以下是基于我之前发布的评论的示例。

首先我们定义一个函数来生成圆的模型:

    /// <summary>
    /// Generates a model of a Circle given specified parameters
    /// </summary>
    /// <param name="radius">Radius of circle</param>
    /// <param name="normal">Vector normal to circle's plane</param>
    /// <param name="center">Center position of the circle</param>
    /// <param name="resolution">Number of slices to iterate the circumference of the circle</param>
    /// <returns>A GeometryModel3D representation of the circle</returns>
    private GeometryModel3D GetCircleModel(double radius, Vector3D normal, Point3D center, int resolution)
    {
        var mod = new GeometryModel3D();
        var geo = new MeshGeometry3D();

        // Generate the circle in the XZ-plane
        // Add the center first
        geo.Positions.Add(new Point3D(0, 0, 0));

        // Iterate from angle 0 to 2*PI
        double t = 2 * Math.PI / resolution;
        for (int i = 0; i < resolution; i++)
        {
            geo.Positions.Add(new Point3D(radius * Math.Cos(t * i), 0, -radius * Math.Sin(t * i)));
        }

        // Add points to MeshGeoemtry3D
        for (int i = 0; i < resolution; i++)
        {
            var a = 0;
            var b = i + 1;
            var c = (i < (resolution - 1)) ? i + 2 : 1;

            geo.TriangleIndices.Add(a);
            geo.TriangleIndices.Add(b);
            geo.TriangleIndices.Add(c);
        }

        mod.Geometry = geo;

        // Create transforms
        var trn = new Transform3DGroup();
        // Up Vector (normal for XZ-plane)
        var up = new Vector3D(0, 1, 0);
        // Set normal length to 1
        normal.Normalize();
        var axis = Vector3D.CrossProduct(up, normal); // Cross product is rotation axis
        var angle = Vector3D.AngleBetween(up, normal); // Angle to rotate
        trn.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(axis, angle)));
        trn.Children.Add(new TranslateTransform3D(new Vector3D(center.X, center.Y, center.Z)));

        mod.Transform = trn;

        return mod;
    }

设置ViewPort3D:

    <Grid Background="Black">
        <Viewport3D Name="mainViewPort">
            <Viewport3D.Camera>
                <PerspectiveCamera NearPlaneDistance="0.1" FarPlaneDistance="100" UpDirection="0,1,0" Position="0,0,10" 
                               LookDirection="0,0,-1" FieldOfView="60" />
            </Viewport3D.Camera>
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <Model3DGroup>
                        <AmbientLight Color="#40FFFFFF" />
                        <DirectionalLight Color="#FFFFFF" Direction="1,-1,-1" />
                    </Model3DGroup>
                </ModelVisual3D.Content>
            </ModelVisual3D>
        </Viewport3D>
    </Grid>

然后测试:

    private void AddCircleModel()
    {
        var mod = GetCircleModel(1.5, new Vector3D(0, 1, 1), new Point3D(0, -1, 0), 20);
        mod.Material = new DiffuseMaterial(Brushes.Silver);
        var vis = new ModelVisual3D() { Content = mod };
        mainViewPort.Children.Add(vis);
    }

加载您的窗口,致电AddCircleModel();并享受。根据您心中的内容调整视图/参数。