728x90
반응형
728x170
▶ 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>
728x90
▶ 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
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] MeshGeometry3D 클래스 : 수레바퀴 만들기 (0) | 2019.09.02 |
---|---|
[C#/WPF] ModelVisual3D 클래스 상속하기 (0) | 2019.09.01 |
[C#/WPF] object 객체에서 XAML 구하기 (0) | 2019.09.01 |
[C#/WPF] MeshGeometry3D 클래스 : 리소스 사용하기 (0) | 2019.09.01 |
[C#/WPF] MeshGeometry3D 클래스 : 리소스 사용하기 (0) | 2019.08.28 |
[C#/WPF] SpecularMaterial 엘리먼트 사용하기 (0) | 2019.08.26 |
[C#/WPF] SpecularMaterial 엘리먼트 사용하기 (0) | 2019.08.26 |
[C#/WPF] DrawingBrush 엘리먼트 사용하기 (0) | 2019.08.26 |
[C#/WPF] VisualBrush 엘리먼트 사용하기 (0) | 2019.08.25 |
[C#/WPF] VisualBrush 엘리먼트 사용하기 (0) | 2019.08.25 |
댓글을 달아 주세요