첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ 측지 구 큐브 사용하기

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


TestProject.zip


Triangle.cs

 

 

using System;

using System.Collections.Generic;

using System.Windows.Media.Media3D;

 

namespace TestProject

{

    /// <summary>

    /// 삼각형

    /// </summary>

    public class Triangle

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

        #region Field

 

        /// <summary>

        /// 포인트 배열

        /// </summary>

        public Point3D[] PointArray;

 

        #endregion

 

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

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

 

        #region 생성자 - Triangle(pointArray)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="pointArray">포인트 배열</param>

        public Triangle(params Point3D[] pointArray)

        {

            PointArray = pointArray;

        }

 

        #endregion

 

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

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

 

        #region 세분화 하기 - Subdivide(triangleList, centerPoint, radius)

 

        /// <summary>

        /// 세분화 하기

        /// </summary>

        /// <param name="triangleList">삼각형 리스트</param>

        /// <param name="centerPoint">중심 포인트</param>

        /// <param name="radius">반지름</param>

        public void Subdivide(List<Triangle> triangleList, Point3D centerPoint, double radius)

        {

            Vector3D v10 = PointArray[1] - PointArray[0];

            Vector3D v20 = PointArray[2] - PointArray[0];

            Vector3D v21 = PointArray[2] - PointArray[1];

 

            Point3D point1 = PointArray[0] + v10 * 1.0 / 3.0;

            Point3D point2 = PointArray[0] + v20 * 1.0 / 3.0;

            Point3D point3 = PointArray[0] + v10 * 2.0 / 3.0;

            Point3D point4 = PointArray[0] + v10 * 2.0 / 3.0 + v21 * 1.0 / 3.0;

            Point3D point5 = PointArray[0] + v20 * 2.0 / 3.0;

            Point3D point6 = PointArray[1] + v21 * 1.0 / 3.0;

            Point3D point7 = PointArray[1] + v21 * 2.0 / 3.0;

 

            NormalizePoint(ref point1, centerPoint, radius);

            NormalizePoint(ref point2, centerPoint, radius);

            NormalizePoint(ref point3, centerPoint, radius);

            NormalizePoint(ref point4, centerPoint, radius);

            NormalizePoint(ref point5, centerPoint, radius);

            NormalizePoint(ref point6, centerPoint, radius);

            NormalizePoint(ref point7, centerPoint, radius);

 

            triangleList.Add(new Triangle(PointArray[0], point1       , point2       ));

            triangleList.Add(new Triangle(point1       , point3       , point4       ));

            triangleList.Add(new Triangle(point1       , point4       , point2       ));

            triangleList.Add(new Triangle(point2       , point4       , point5       ));

            triangleList.Add(new Triangle(point3       , PointArray[1], point6       ));

            triangleList.Add(new Triangle(point3       , point6       , point4       ));

            triangleList.Add(new Triangle(point4       , point6       , point7       ));

            triangleList.Add(new Triangle(point4       , point7       , point5       ));

            triangleList.Add(new Triangle(point5       , point7       , PointArray[2]));

        }

 

        #endregion

        #region 각도 배열 구하기 - GetAngleArray()

 

        /// <summary>

        /// 각도 배열 구하기

        /// </summary>

        /// <returns>각도 배열</returns>

        public double[] GetAngleArray()

        {

            Vector3D v10 = PointArray[1] - PointArray[0];

            Vector3D v21 = PointArray[2] - PointArray[1];

            Vector3D v02 = PointArray[0] - PointArray[2];

 

            v10.Normalize();

            v21.Normalize();

            v02.Normalize();

 

            double angle0 = Math.Acos(Vector3D.DotProduct(v10, -v02)) * 180.0 / Math.PI;

            double angle1 = Math.Acos(Vector3D.DotProduct(v21, -v10)) * 180.0 / Math.PI;

            double angle2 = Math.Acos(Vector3D.DotProduct(v02, -v21)) * 180.0 / Math.PI;

 

            double[] angleArray = new double[] { angle0, angle1, angle2 };

 

            Array.Sort(angleArray);

 

            return angleArray;

        }

 

        #endregion

        #region 별 모양 만들기 - Stellate(triangleList, centerPoint, radius)

 

        /// <summary>

        /// 별 모양 만들기

        /// </summary>

        /// <param name="triangleList">삼각형 리스트</param>

        /// <param name="centerPoint">중심 포인트</param>

        /// <param name="radius">반지름</param>

        public void Stellate(List<Triangle> triangleList, Point3D centerPoint, double radius)

        {

            Point3D peakPoint = new Point3D

            (

                (PointArray[0].X + PointArray[1].X + PointArray[2].X) / 3.0,

                (PointArray[0].Y + PointArray[1].Y + PointArray[2].Y) / 3.0,

                (PointArray[0].Z + PointArray[1].Z + PointArray[2].Z) / 3.0

            );

 

            NormalizePoint(ref peakPoint, centerPoint, radius);

 

            triangleList.Add(new Triangle(PointArray[0], PointArray[1], peakPoint));

            triangleList.Add(new Triangle(PointArray[1], PointArray[2], peakPoint));

            triangleList.Add(new Triangle(PointArray[2], PointArray[0], peakPoint));

        }

 

        #endregion

 

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

 

        #region 포인트 정규화 하기 - NormalizePoint(point, centerPoint, distance)

 

        /// <summary>

        /// 포인트 정규화 하기

        /// </summary>

        /// <param name="point">포인트</param>

        /// <param name="centerPoint">중심 포인트</param>

        /// <param name="distance">거리</param>

        private void NormalizePoint(ref Point3D point, Point3D centerPoint, double distance)

        {

            Vector3D vector = point - centerPoint;

 

            point = centerPoint + vector / vector.Length * distance;

        }

 

        #endregion

    }

}

 

 

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="측지 구 큐브 사용하기"

    FontFamily="나눔고딕코딩"

    FontSize="16"

    Loaded="Window_Loaded">

    <Grid>

        <Grid.Resources>

            <Style TargetType="CheckBox">

                <Setter Property="VerticalAlignment" Value="Center" />

                <Setter Property="Margin" Value="5 0 10 0" />

            </Style>

            <Style TargetType="Label">

                <Setter Property="VerticalAlignment" Value="Center" />

                <Setter Property="Margin" Value="5 0 0 0" />

            </Style>

        </Grid.Resources>

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto" />

            <RowDefinition />

            <RowDefinition Height="20" />

        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="80" />

            <ColumnDefinition />

            <ColumnDefinition Width="20" />

        </Grid.ColumnDefinitions>

        <Viewport3D Name="viewport3D" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" />

        <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal">

            <StackPanel Orientation="Horizontal">

                <Label Content="거리" />

                <Label Name="distanceLabel"

                    Margin="0"

                    HorizontalContentAlignment="Right"

                    ContentStringFormat="0"

                    Content="{Binding ElementName=distanceScrollBar, Path=Value}" />

            </StackPanel>

        </StackPanel>

        <ScrollBar Name="distanceScrollBar" Grid.Column="1"

            HorizontalAlignment="Stretch"

            Height="20"

            Orientation="Horizontal"

            Minimum="1"

            Maximum="100"

            Value="20"

            Scroll="distanceScrollBar_Scroll" />

        <ScrollBar Name="cameraThetaScrollBar" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"

            Orientation="Horizontal"

            Minimum="0"

            Maximum="360"

            Value="35"

            Scroll="cameraThetaScrollBar_Scroll" />

        <ScrollBar Name="cameraPhiScrollBar" Grid.Row="1" Grid.Column="2"

            Orientation="Vertical"

            Minimum="-90"

            Maximum="90"

            Value="33"

            Scroll="cameraPhiScrollBar_Scroll" />

    </Grid>

</Window>

 

 

MainWindow.xaml.cs

 

 

using System;

using System.Collections.Generic;

using System.Windows;

using System.Windows.Controls.Primitives;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Media3D;

using System.Windows.Threading;

 

namespace TestProject

{

    /// <summary>

    /// 메인 윈도우

    /// </summary>

    public partial class MainWindow : Window

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

        #region Field

 

        /// <summary>

        /// 모델 그룹

        /// </summary>

        private Model3DGroup modelGroup = new Model3DGroup();

 

        /// <summary>

        /// 조명 리스트

        /// </summary>

        private List<Light> lightList = new List<Light>();

 

        /// <summary>

        /// 카메라

        /// </summary>

        private PerspectiveCamera camera;

 

        /// <summary>

        /// 카메라 파이

        /// </summary>

        private double cameraPhi;

        

        /// <summary>

        /// 카메라 세타

        /// </summary>

        private double cameraTheta;

        

        /// <summary>

        /// 카메라 R

        /// </summary>

        private double cameraR;

 

        /// <summary>

        /// 분할 레벨

        /// </summary>

        private int divisionLevel = 1;

 

        /// <summary>

        /// 별 모양 R

        /// </summary>

        private double stellateR = 0.96;

 

        /// <summary>

        /// 전체 삼각형 카운트

        /// </summary>

        private int totalTriangleCount = 0;

 

        #endregion

 

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

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

 

        #region 생성자 - MainWindow()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainWindow()

        {

            InitializeComponent();

        }

 

        #endregion

 

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

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

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)

 

        /// <summary>

        /// 윈도우 로드시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            this.camera = new PerspectiveCamera();

 

            this.camera.FieldOfView = 60;

 

            this.viewport3D.Camera = this.camera;

 

            this.cameraTheta = this.cameraThetaScrollBar.Value * Math.PI / 180.0;

            this.cameraPhi   = this.cameraPhiScrollBar.Value * Math.PI / 180.0;

            this.cameraR     = double.Parse(this.distanceLabel.Content.ToString());

 

            SetCameraPosition();

 

            DefineLight();

 

            DefineModel();

 

            ModelVisual3D modelVisual = new ModelVisual3D();

 

            modelVisual.Content = this.modelGroup;

 

            this.viewport3D.Children.Add(modelVisual);

        }

 

        #endregion

        #region 거리 스크롤바 스크롤시 처리하기 - distanceScrollBar_Scroll(sender, e)

 

        /// <summary>

        /// 거리 스크롤바 스크롤시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void distanceScrollBar_Scroll(object sender, ScrollEventArgs e)

        {

            this.cameraR = this.distanceScrollBar.Value;

 

            SetCameraPosition();

        }

 

        #endregion

        #region 카메라 파이 스크롤바 스크롤시 처리하기 - cameraPhiScrollBar_Scroll(sender, e)

 

        /// <summary>

        /// 카메라 파이 스크롤바 스크롤시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void cameraPhiScrollBar_Scroll(object sender, ScrollEventArgs e)

        {

            this.cameraPhi = this.cameraPhiScrollBar.Value * Math.PI / 180.0;

 

            SetCameraPosition();

        }

 

        #endregion

        #region 카메라 세타 스크롤바 스크롤시 처리하기 - cameraThetaScrollBar_Scroll(sender, e)

 

        /// <summary>

        /// 카메라 세타 스크롤바 스크롤시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void cameraThetaScrollBar_Scroll(object sender, ScrollEventArgs e)

        {

            this.cameraTheta = this.cameraThetaScrollBar.Value * Math.PI / 180.0;

 

            SetCameraPosition();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 카메라 위치 설정하기 - SetCameraPosition()

 

        /// <summary>

        /// 카메라 위치 설정하기

        /// </summary>

        private void SetCameraPosition()

        {

            double y   = this.cameraR * Math.Sin(this.cameraPhi);

            double hyp = this.cameraR * Math.Cos(this.cameraPhi);

            double x   = hyp * Math.Cos(this.cameraTheta);

            double z   = hyp * Math.Sin(this.cameraTheta);

 

            this.camera.Position = new Point3D(x, y, z);

 

            this.camera.LookDirection = new Vector3D(-x, -y, -z);

 

            this.camera.UpDirection = new Vector3D(0, 1, 0);

        }

 

        #endregion

        #region 조명 정의하기 - DefineLight()

 

        /// <summary>

        /// 조명 정의하기

        /// </summary>

        private void DefineLight()

        {

            Color color64  = Color.FromArgb(255, 128, 128, 64);

            Color color128 = Color.FromArgb(255, 255, 255, 128);

 

            this.lightList.Add(new AmbientLight(color64));

 

            this.lightList.Add(new DirectionalLight(color64, new Vector3D(-1.0, -2.0, -3.0)));

            this.lightList.Add(new DirectionalLight(color64, new Vector3D( 1.0,  2.0,  3.0)));

 

            foreach(Light light in this.lightList)

            {

                this.modelGroup.Children.Add(light);

            }

        }

 

        #endregion

        #region 스케일 벡터 구하기 - GetScaleVector(vector, length)

 

        /// <summary>

        /// 스케일 벡터 구하기

        /// </summary>

        /// <param name="vector">벡터</param>

        /// <param name="length">길이</param>

        /// <returns>스케일 벡터</returns>

        private Vector3D GetScaleVector(Vector3D vector, double length)

        {

            double scale = length / vector.Length;

 

            return new Vector3D

            (

                vector.X * scale,

                vector.Y * scale,

                vector.Z * scale

            );

        }

 

        #endregion

        #region 삼각형 추가하기 - AddTriangle(mesh, point1, point2, point3)

 

        /// <summary>

        /// 삼각형 추가하기

        /// </summary>

        /// <param name="mesh">메시</param>

        /// <param name="point1">포인트 1</param>

        /// <param name="point2">포인트 2</param>

        /// <param name="point3">포인트 3</param>

        private void AddTriangle(MeshGeometry3D mesh, Point3D point1, Point3D point2, Point3D point3)

        {

            int index = mesh.Positions.Count;

 

            mesh.Positions.Add(point1);

            mesh.Positions.Add(point2);

            mesh.Positions.Add(point3);

 

            mesh.TriangleIndices.Add(index++);

            mesh.TriangleIndices.Add(index++);

            mesh.TriangleIndices.Add(index  );

        }

 

        #endregion

        #region 삼각형 추가하기 - AddTriangle(mesh, triangle)

 

        /// <summary>

        /// 삼각형 추가하기

        /// </summary>

        /// <param name="mesh">메시</param>

        /// <param name="triangle">삼각형</param>

        private void AddTriangle(MeshGeometry3D mesh, Triangle triangle)

        {

            this.totalTriangleCount++;

 

            int index = mesh.Positions.Count;

 

            mesh.Positions.Add(triangle.PointArray[0]);

            mesh.Positions.Add(triangle.PointArray[1]);

            mesh.Positions.Add(triangle.PointArray[2]);

 

            mesh.TriangleIndices.Add(index++);

            mesh.TriangleIndices.Add(index++);

            mesh.TriangleIndices.Add(index  );

        }

 

        #endregion

        #region 세그먼트 추가하기 - AddSegment(mesh, point1, point2, upVector)

 

        /// <summary>

        /// 세그먼트 추가하기

        /// </summary>

        /// <param name="mesh">메시</param>

        /// <param name="point1">포인트 1</param>

        /// <param name="point2">포인트 2</param>

        /// <param name="upVector">UP 벡터</param>

        private void AddSegment(MeshGeometry3D mesh, Point3D point1, Point3D point2, Vector3D upVector)

        {

            const double THICKNESS = 0.01;

 

            Vector3D vector1      = point2 - point1;

            Vector3D scaleVector1 = GetScaleVector(upVector, THICKNESS / 2.0);

            Vector3D scaleVector2 = Vector3D.CrossProduct(vector1, scaleVector1);

 

            scaleVector2 = GetScaleVector(scaleVector2, THICKNESS / 2.0);

 

            Point3D p1pp = point1 + scaleVector1 + scaleVector2;

            Point3D p1mp = point1 - scaleVector1 + scaleVector2;

            Point3D p1pm = point1 + scaleVector1 - scaleVector2;

            Point3D p1mm = point1 - scaleVector1 - scaleVector2;

            Point3D p2pp = point2 + scaleVector1 + scaleVector2;

            Point3D p2mp = point2 - scaleVector1 + scaleVector2;

            Point3D p2pm = point2 + scaleVector1 - scaleVector2;

            Point3D p2mm = point2 - scaleVector1 - scaleVector2;

 

            AddTriangle(mesh, p1pp, p1mp, p2mp);

            AddTriangle(mesh, p1pp, p2mp, p2pp);

 

            AddTriangle(mesh, p1pp, p2pp, p2pm);

            AddTriangle(mesh, p1pp, p2pm, p1pm);

 

            AddTriangle(mesh, p1pm, p2pm, p2mm);

            AddTriangle(mesh, p1pm, p2mm, p1mm);

 

            AddTriangle(mesh, p1mm, p2mm, p2mp);

            AddTriangle(mesh, p1mm, p2mp, p1mp);

 

            AddTriangle(mesh, p1pp, p1pm, p1mm);

            AddTriangle(mesh, p1pp, p1mm, p1mp);

 

            AddTriangle(mesh, p2pp, p2mp, p2mm);

            AddTriangle(mesh, p2pp, p2mm, p2pm);

        }

 

        #endregion

        #region 포인트 배열 구하기 - GetPointArray(sideLength)

 

        /// <summary>

        /// 포인트 배열 구하기

        /// </summary>

        /// <param name="sideLength">면 길이</param>

        /// <returns>포인트 배열</returns>

        private Point3D[] GetPointArray(double sideLength)

        {

            double s  = sideLength;

            double t2 = Math.PI / 10.0;

            double t4 = Math.PI / 5.0;

            double r  = (s / 2.0) / Math.Sin(t4);

            double h  = Math.Cos(t4) * r;

            double cx = r * Math.Sin(t2);

            double cz = r * Math.Cos(t2);

            double h1 = Math.Sqrt(s * s - r * r);

            double h2 = Math.Sqrt((h + r) * (h + r) - h * h);

            double y2 = (h2 - h1) / 2.0;

            double y1 = y2 + h1;

 

            List<Point3D> pointList = new List<Point3D>();

 

            pointList.Add(new Point3D( 0 ,  y1, 0     ));

            pointList.Add(new Point3D( r ,  y2, 0     ));

            pointList.Add(new Point3D( cx,  y2, cz    ));

            pointList.Add(new Point3D(-h ,  y2, s / 2 ));

            pointList.Add(new Point3D(-h ,  y2, -s / 2));

            pointList.Add(new Point3D( cx,  y2, -cz   ));

            pointList.Add(new Point3D(-r , -y2, 0     ));

            pointList.Add(new Point3D(-cx, -y2, -cz   ));

            pointList.Add(new Point3D( h , -y2, -s / 2));

            pointList.Add(new Point3D( h , -y2, s / 2 ));

            pointList.Add(new Point3D(-cx, -y2, cz    ));

            pointList.Add(new Point3D( 0 , -y1, 0     ));

 

            return pointList.ToArray();

        }

 

        #endregion

        #region 삼각형 리스트 구하기 - GetTriangleList(sideLength)

 

        /// <summary>

        /// 삼각형 리스트 구하기

        /// </summary>

        /// <param name="sideLength">면 길이</param>

        /// <returns>삼각형 리스트</returns>

        private Triangle[] GetTriangleList(double sideLength)

        {

            Point3D[] pointArray = GetPointArray(sideLength);

 

            List<Triangle> triangleList = new List<Triangle>();

 

            triangleList.Add(new Triangle(pointArray[0], pointArray[2], pointArray[1]));

            triangleList.Add(new Triangle(pointArray[0], pointArray[3], pointArray[2]));

            triangleList.Add(new Triangle(pointArray[0], pointArray[4], pointArray[3]));

            triangleList.Add(new Triangle(pointArray[0], pointArray[5], pointArray[4]));

            triangleList.Add(new Triangle(pointArray[0], pointArray[1], pointArray[5]));

 

            triangleList.Add(new Triangle(pointArray[1], pointArray[2], pointArray[9 ]));

            triangleList.Add(new Triangle(pointArray[2], pointArray[3], pointArray[10]));

            triangleList.Add(new Triangle(pointArray[3], pointArray[4], pointArray[6 ]));

            triangleList.Add(new Triangle(pointArray[4], pointArray[5], pointArray[7 ]));

            triangleList.Add(new Triangle(pointArray[5], pointArray[1], pointArray[8 ]));

 

            triangleList.Add(new Triangle(pointArray[6 ], pointArray[4], pointArray[7 ]));

            triangleList.Add(new Triangle(pointArray[7 ], pointArray[5], pointArray[8 ]));

            triangleList.Add(new Triangle(pointArray[8 ], pointArray[1], pointArray[9 ]));

            triangleList.Add(new Triangle(pointArray[9 ], pointArray[2], pointArray[10]));

            triangleList.Add(new Triangle(pointArray[10], pointArray[3], pointArray[6 ]));

 

            triangleList.Add(new Triangle(pointArray[11], pointArray[6 ], pointArray[7 ]));

            triangleList.Add(new Triangle(pointArray[11], pointArray[7 ], pointArray[8 ]));

            triangleList.Add(new Triangle(pointArray[11], pointArray[8 ], pointArray[9 ]));

            triangleList.Add(new Triangle(pointArray[11], pointArray[9 ], pointArray[10]));

            triangleList.Add(new Triangle(pointArray[11], pointArray[10], pointArray[6 ]));

 

            double radius = pointArray[0].Y;

 

            Point3D originPoint = new Point3D(0, 0, 0);

 

            for(int i = 0; i < this.divisionLevel; i++)

            {

                List<Triangle> newTriangleList = new List<Triangle>();

 

                foreach(Triangle triangle in triangleList)

                {

                    triangle.Subdivide(newTriangleList, originPoint, radius);

                }

 

                triangleList = newTriangleList;

            }

 

            List<Triangle> stellateTriangleList = new List<Triangle>();

 

            foreach(Triangle triangle in triangleList)

            {

                triangle.Stellate(stellateTriangleList, originPoint, this.stellateR);

            }

 

            triangleList = stellateTriangleList;

 

            return triangleList.ToArray();

        }

 

        #endregion

        #region 모델 정의하기 - DefineModel()

 

        /// <summary>

        /// 모델 정의하기

        /// </summary>

        private void DefineModel()

        {

            Cursor = Cursors.Wait;

 

            const int MAXIMUM   = 5;

            const int MINIMUM_X = -MAXIMUM;

            const int MAXIMUM_X =  MAXIMUM;

            const int MINIMUM_Y = -MAXIMUM;

            const int MAXIMUM_Y =  MAXIMUM;

            const int MINIMUM_Z = -MAXIMUM;

            const int MAXIMUM_Z =  MAXIMUM;

 

            double deltaRed   = 255 / (MAXIMUM_X - MINIMUM_X);

            double deltaGreen = 255 / (MAXIMUM_Y - MINIMUM_Y);

            double deltaBlue  = 255 / (MAXIMUM_Z - MINIMUM_Z);

 

            for(int x = MINIMUM_X; x <= MAXIMUM_X; x++)

            {

                Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));

 

                for(int y = MINIMUM_Y; y <= MAXIMUM_Y; y++)

                {

                    for(int z = MINIMUM_Z; z <= MAXIMUM_Z; z++)

                    {

                        Triangle[] triangleList = GetTriangleList(1);

 

                        MeshGeometry3D faceMesh = new MeshGeometry3D();

 

                        foreach(Triangle triangle in triangleList)

                        {

                            AddTriangle(faceMesh, triangle);

                        }

 

                        byte red   = (byte)((x - MINIMUM_X) * deltaRed  );

                        byte green = (byte)((y - MINIMUM_Y) * deltaGreen);

                        byte blue  = (byte)((z - MINIMUM_Z) * deltaBlue );

 

                        Color color = Color.FromArgb(255, red, green, blue);

 

                        SolidColorBrush faceBrush = new SolidColorBrush(color);

 

                        DiffuseMaterial faiceMaterial = new DiffuseMaterial(faceBrush);

 

                        GeometryModel3D faceModel = new GeometryModel3D(faceMesh, faiceMaterial);

 

                        const double SCALE = 0.4;

 

                        ScaleTransform3D scaleTransform = new ScaleTransform3D

                        (

                            SCALE,

                            SCALE,

                            SCALE,

                            0,

                            0,

                            0

                        );

 

                        TranslateTransform3D translateTransform = new TranslateTransform3D(x, y, z);

 

                        Transform3DGroup transformGroup = new Transform3DGroup();

 

                        transformGroup.Children.Add(scaleTransform);

 

                        transformGroup.Children.Add(translateTransform);

 

                        faceModel.Transform = transformGroup;

 

                        this.modelGroup.Children.Add(faceModel);

                    }

                }

            }

 

            Cursor = null;

        }

 

        #endregion

    }

}

 

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

Posted by 사용자 icodebroker

댓글을 달아 주세요