3

既知の中心点、半径を使用して3Dで円を作成し、それがWPFの線(ベクトル)に垂直な平面上にある方法を教えてください。

4

2 に答える 2

4

以下は、以前に投稿したコメントに基づく例です。

まず、円のモデルを生成する関数を定義します。

    /// <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();してお楽しみください。ビュー/パラメータを心ゆくまで調整してください。

于 2013-01-07T14:42:52.883 に答える