■ MeshGeometry3D 클래스 : 삼각측량법을 사용해 비치볼 만들기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


MainWindow.xaml

 

 

<Window x:Class="TestProject.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="800"

    Height="600"

    Title="MeshGeometry3D 클래스 : 삼각측량법을 사용해 비치볼 만들기"

    FontFamily="나눔고딕코딩"

    FontSize="16">

</Window>

 

 

MainWindow.xaml.cs

 

 

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Media.Media3D;

 

namespace TestProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public partial class MainWindow : Window

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            InitializeComponent();

 

            Viewport3D viewport3D = new Viewport3D();

 

            Content = viewport3D;

 

            MeshGeometry3D meshGeometry3D = GetSphereMeshGeometry3D(new Point3D(0, 0, 0), 1.5, 144, 72);

 

            meshGeometry3D.Freeze();

 

            Brush[] brushArray = new Brush[6]

            {

                Brushes.Red,

                Brushes.Blue,

                Brushes.Yellow,

                Brushes.Orange,

                Brushes.Green,

                Brushes.White

            };

 

            DrawingGroup drawingGroup = new DrawingGroup();

 

            for(int i = 0; i < brushArray.Length ; i++)

            {

                RectangleGeometry rectangleGeometry = new RectangleGeometry(new Rect(10 * i, 0, 10, 60));

 

                GeometryDrawing geometryDrawing = new GeometryDrawing(brushArray[i], null, rectangleGeometry);

 

                drawingGroup.Children.Add(geometryDrawing);

            }

 

            DrawingBrush drawingBrush = new DrawingBrush(drawingGroup);

 

            drawingBrush.Freeze();

 

            GeometryModel3D geometryModel3D = new GeometryModel3D();

 

            geometryModel3D.Geometry = meshGeometry3D;

            geometryModel3D.Material = new DiffuseMaterial(drawingBrush);

 

            ModelVisual3D modelVisual3D = new ModelVisual3D();

 

            modelVisual3D.Content = geometryModel3D;

 

            viewport3D.Children.Add(modelVisual3D);

 

            Model3DGroup model3DGroup = new Model3DGroup();

 

            model3DGroup.Children.Add

            (

                new AmbientLight

                (

                    Color.FromRgb(128, 128, 128)

                )

            );

 

            model3DGroup.Children.Add

            (

                new DirectionalLight

                (

                    Color.FromRgb(128, 128, 128),

                    new Vector3D(2, -3, -1)

                )

            );

 

            modelVisual3D = new ModelVisual3D();

 

            modelVisual3D.Content = model3DGroup;

 

            viewport3D.Children.Add(modelVisual3D);

 

            PerspectiveCamera perspectiveCamera = new PerspectiveCamera

            (

                new Point3D(0, 0, 8),

                new Vector3D(0, 0, -1),

                new Vector3D(0, 1, 0),

                45

            );

 

            viewport3D.Camera = perspectiveCamera;

 

            AxisAngleRotation3D axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(1, 1, 0), 0);

 

            RotateTransform3D rotateTransform3D = new RotateTransform3D(axisAngleRotation3D);

 

            geometryModel3D.Transform = rotateTransform3D;

 

            DoubleAnimation doubleAnimation = new DoubleAnimation(360, new Duration(TimeSpan.FromSeconds(5)));

 

            doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;

 

            axisAngleRotation3D.BeginAnimation(AxisAngleRotation3D.AngleProperty, doubleAnimation);

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region 구 메쉬 기하학 3D 구하기 - GetSphereMeshGeometry3D(centerPoint3D, radius, sliceCount, stackCount)

 

        /// <summary>

        /// 구 메쉬 기하학 3D 구하기

        /// </summary>

        /// <param name="centerPoint3D">중앙 포인트 3D</param>

        /// <param name="radius">반경</param>

        /// <param name="sliceCount">슬라이스 수</param>

        /// <param name="stackCount">스택 수</param>

        /// <returns>구 메쉬 기하학 3D</returns>

        MeshGeometry3D GetSphereMeshGeometry3D(Point3D centerPoint3D, double radius, int sliceCount, int stackCount)

        {

            MeshGeometry3D meshGeometry3D = new MeshGeometry3D();

 

            for(int stack = 0; stack <= stackCount; stack++)

            {

                double phi   = Math.PI / 2 - stack * Math.PI / stackCount;

                double y     = radius * Math.Sin(phi);

                double scale = -radius * Math.Cos(phi);

 

                for(int slice = 0; slice <= sliceCount; slice++)

                {

                    double theta = slice * 2 * Math.PI / sliceCount;

                    double x     = scale * Math.Sin(theta);

                    double z     = scale * Math.Cos(theta);

 

                    Vector3D normal = new Vector3D(x, y, z);

 

                    meshGeometry3D.Normals.Add(normal);

 

                    meshGeometry3D.Positions.Add(normal + centerPoint3D);

 

                    meshGeometry3D.TextureCoordinates.Add

                    (

                        new Point

                        (

                            (double)slice / sliceCount,

                            (double)stack / stackCount

                        )

                    );

                }

            }

 

            for(int stack = 0; stack < stackCount; stack++)

            {

                for(int slice = 0; slice < sliceCount; slice++)

                {

                    int n = sliceCount + 1;

 

                    if(stack != 0)

                    {

                        meshGeometry3D.TriangleIndices.Add((stack + 0) * n + slice    );

                        meshGeometry3D.TriangleIndices.Add((stack + 1) * n + slice    );

                        meshGeometry3D.TriangleIndices.Add((stack + 0) * n + slice + 1);

                    }

 

                    if(stack != stackCount - 1)

                    {

                        meshGeometry3D.TriangleIndices.Add((stack + 0) * n + slice + 1);

                        meshGeometry3D.TriangleIndices.Add((stack + 1) * n + slice    );

                        meshGeometry3D.TriangleIndices.Add((stack + 1) * n + slice + 1);

                    }

                }

            }

 

            return meshGeometry3D;

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker

댓글을 달아 주세요