{"id":360,"date":"2007-05-24T16:18:00","date_gmt":"2007-05-24T16:18:00","guid":{"rendered":"http:\/\/www.gisdeveloper.co.kr\/?p=360"},"modified":"2017-01-29T13:10:57","modified_gmt":"2017-01-29T04:10:57","slug":"%ea%b5%acsphere-%ec%9b%90%ed%86%b5cylinder-%ec%9b%90%eb%bf%94cone-%eb%a0%8c%eb%8d%94%eb%a7%81","status":"publish","type":"post","link":"http:\/\/www.gisdeveloper.co.kr\/?p=360","title":{"rendered":"\uad6c(Sphere), \uc6d0\ud1b5(Cylinder), \uc6d0\ubfd4(Cone) \ub80c\ub354\ub9c1"},"content":{"rendered":"<p>\uce5c\uc808\ud55c \uae08\uc790\uc528\ub791 \uc0c1\uad00\uc5c6\ub294 WPF\ub294 \ub9e4\uc6b0 \ubd88\uce5c\uc808\ud558\uac8c\ub3c4 3D\uc5d0\uc11c \uad6c, \uc6d0\ud1b5, \uc6d0\ubfd4 \ub4f1\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 Geometry\ub97c \uc27d\uac8c \ub098\ud0c0\ub0bc \uc218\uac00 \uc5c6\ub2e4. \uc624\uc9c1 WPF\ub294 \uc138\uac1c\uc758 Point\ub85c \uad6c\uc131\ub41c \uc0bc\uac01\ud615(Triangle) Geometry\ub9cc\uc744 \ub098\ud0c0\ub0bc \uc218 \uc788\ub2e4. \uadf8\ub7f0\uc989, \uad6c, \uc6d0, \uc6d0\ubfd4\uc744 \ub098\ud0c0\ub0b4\uae30 \uc704\ud574\uc11c\ub294 \uac1c\ubc1c\uc790 \uc9c1\uc811 \uc0bc\uac01\ud615 \uc694\uc18c\ub97c \uc870\ud569\ud558\ub294 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec\uc57c\ub9cc \ud55c\ub2e4. \ubc14\ub85c \uc774 \uae00\uc774 \uc774\ub7ec\ud55c \ucf54\ub4dc\ub97c \uc704\ud55c \uac83\uc774\ub2e4. \ud2b9\ud788 XAML\uc744 \uc774\uc6a9\ud558\uc5ec \uad6c, \uc6d0\ud1b5 \ub4f1\uc758 \uc704\uce58\ub098 \uc7ac\uc9c8 \uc9c0\uc815 \ub4f1\uacfc \uac19\uc740 \uc18d\uc131\uc744 \uc9c0\uc815\ud558\uace0 \uc2e4\uc81c \uad6c, \uc6d0\ud1b5 \ub4f1\uc5d0 \ub300\ud55c Geometry\uc758 \ub17c\ub9ac\uc801\uc778 \uad6c\uc131 \uc815\ubcf4\ub294 Code-Behind\uc5d0\uc11c, (\uc6b0\ub9ac\ub294 C# \ucf54\ub4dc\ub85c..) \ucc98\ub9ac\ud574\uc8fc\ub294 WPF\uc758 \ub9e4\ub825\uc801\uc778 \ucf54\ub4dc \uad6c\uc870\ub85c \uc791\uc131\ub418\uc5c8\ub2e4. <\/p>\n<p>\uba3c\uc800 \uac04\ub2e8\uc774 \uad6c \ub4f1\uacfc \uac19\uc740 Geometry\uc5d0 \ub300\ud55c \ub17c\ub9ac\uc801\uc778 \uad6c\uc131\uc5d0 \ub300\ud55c Code-Behind \ucf54\ub4dc\uac00 \uc791\uc131\ub418\uc5b4\uc84c\ub2e4\ub294 \uac00\uc815\ud558\uc5d0 XAML\uc744 \uc774\uc6a9\ud558\uc5ec \ud654\uba74\uc0c1\uc5d0 \ub80c\ub354\ub9c1 \uc2dc\ud0a4\ub294 XAML\uc744 \uc0b4\ud3b4\ubcf4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4.  <\/p>\n<pre><Window x:Class=\"Visual3DSample.Window1\" \r\n    xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\" \r\n    xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\" \r\n    xmlns:my=\"clr-namespace:Primitive3DSurfaces;assembly=Primitive3DSurfaces\"  \r\n    Title=\"tst WPF3D\"> \r\n \r\n  <Grid> \r\n    <Grid.Background> \r\n      <LinearGradientBrush StartPoint=\"1,1\" EndPoint=\"0,0\"> \r\n        <LinearGradientBrush.GradientStops> \r\n          <GradientStop Color=\"Black\" Offset=\"0\"\/> \r\n          <GradientStop Color=\"DarkBlue\" Offset=\"1\"\/> \r\n        <\/LinearGradientBrush.GradientStops> \r\n      <\/LinearGradientBrush> \r\n    <\/Grid.Background> \r\n     \r\n    <Viewport3D Grid.Column=\"0\" Grid.Row=\"0\"> \r\n      <Viewport3D.Camera> \r\n        <PerspectiveCamera Position=\"0,0,-8\"  \r\n                           UpDirection=\"0,1,0\" LookDirection=\"0,0,1\"  \r\n                           FieldOfView=\"30\" NearPlaneDistance=\"0.125\"\/> \r\n      <\/Viewport3D.Camera> \r\n \r\n      <Viewport3D.Children> \r\n        <ModelVisual3D> \r\n          <ModelVisual3D.Content> \r\n            <DirectionalLight Color=\"White\" Direction=\"0,0,1\" \/> \r\n          <\/ModelVisual3D.Content> \r\n        <\/ModelVisual3D> \r\n        <ModelVisual3D> \r\n           \r\n        <my:Sphere3D> \r\n          <ModelVisual3D.Transform> \r\n            <TranslateTransform3D OffsetX=\"0\" OffsetY=\"0\" OffsetZ=\"0\"  \/> \r\n          <\/ModelVisual3D.Transform> \r\n          <my:Sphere3D.Material> \r\n            <DiffuseMaterial> \r\n              <DiffuseMaterial.Brush> \r\n                <ImageBrush ImageSource=\"Azul.jpg\" \/> \r\n              <\/DiffuseMaterial.Brush> \r\n            <\/DiffuseMaterial> \r\n          <\/my:Sphere3D.Material> \r\n        <\/my:Sphere3D> \r\n\r\n      <\/ModelVisual3D> \r\n    <\/Viewport3D.Children> \r\n  <\/Viewport3D> \r\n  <\/Grid> \r\n<\/Window><\/pre>\n<p>\uc774\ubbf8 \uc774 \ube14\ub85c\uadf8\ub97c \ud1b5\ud574 WPF\uc5d0\uc11c \uae30\ubcf8\uc801\uc778 3D \uc7a5\uba74\uc744 \ub80c\ub354\ub9c1\ud558\uae30 \uc704\ud55c \ucf54\ub4dc\ub294 \uc0b4\ud3b4\ubcf4\uc558\uc73c\ubbc0\ub85c, \uc5ec\uae30\uc11c\ub294 \uc0c8\ub85c\uc6b4 \uac83(\uc624\ub80c\uc9c0\uc0c9\uc0c1\uc758 \ucf54\ub4dc)\ub9cc\uc744 \uc9da\uace0 \ub118\uc5b4\uac00\uaca0\ub2e4.  <\/p>\n<p>\uba3c\uc800 Window \uc694\uc18c\uc758 xmlns:my \uc18d\uc131\uc740 Code-Behind\uc5d0\uc11c \uc6b0\ub9ac\uac00 \ub098\uc911\uc5d0 \uc791\uc131\ud560 \uad6c, \uc6d0\ud1b5 \ub4f1\uacfc \uac19\uc740 Geometry\uc758 \uc2e4\uc81c \uad6c\uc131 \ucf54\ub4dc\uac00 \ub2f4\uaca8 \uc788\ub294 Namespace\uc640 Assembly(DLL)\uc5d0 \ub300\ud55c \ucc38\uc870\uc774\ub2e4. \uc989, \uc6b0\ub9ac\ub294 \ub610 \ud558\ub098\uc758 \ud504\ub85c\uc81d\ud2b8\uc5d0 \uad6c, \uc6d0\ud1b5 \ub4f1\uc758 \uad6c\uc131 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \uc5b4\uc148\ube14\ub9ac\ub97c \ub9cc\ub4e4\uace0 \uc774\ub97c \uc0ac\uc6a9\ud558\ub294 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774\ub2e4. \uc774\ub807\uac8c \ucc38\uc870\ub97c \ud55c\ud6c4\uc5d0 \uc6b0\ub9ac\ub294 my:Sphere3D \uc694\uc18c\uc758 \ud615\ud0dc\ub85c \uc6d0\ud558\ub294 \uc704\uce58\uc640 \uc7ac\uc9c8 \ub4f1\uc744 \uc9c0\uc815\ud574\uc11c \ud654\uba74\uc0c1\uc5d0 \uc27d\uac8c \ub80c\ub354\ub9c1 \ud560 \uc218 \uc788\ub294 \uac83\uc774\ub2e4. my:Sphere3D\uc758 Sphere3D\ub294 \uc55e\uc11c \ucc38\uc870\ud55c Assembly DLL \uc548\uc5d0 \ub9cc\ub4e0 Public Class \uc774\ub984\uc774\ub2e4.  <\/p>\n<p>\uc774\uc81c \uacb0\uacfc\ub97c \uc0b4\ud3b4\ubcf8 \ud6c4\uc5d0 Sphere3D\uac00 \uc5b4\ub5bb\uac8c \uad6c\ud604\ub418\uc5c8\ub294\uc9c0 \ucf54\ub4dc\ub97c \uc0b4\ud3b4\ubcf4\uae30\ub85c \ud558\uc790. <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.gisdeveloper.co.kr\/wp-content\/uploads\/1\/1105475365.png\" class=\"aligncenter\" width=\"495\" height=\"311\" alt=\"\" \/>Sphere3D\uc5d0 \ub300\ud55c \ucf54\ub4dc\ub97c \uc0b4\ud3b4\ubcf4\uae30\uc5d0 \uc55e\uc11c \uba3c\uc800 WPF 3D\uc5d0\uc11c Geometry\uc640 \uc5f0\uad00\ub41c \ud074\ub798\uc2a4\uc758 \uad6c\uc870\ub97c \uc0b4\ud3b4\ubcf4\uc790. <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.gisdeveloper.co.kr\/wp-content\/uploads\/1\/1168047260.png\" class=\"aligncenter\" width=\"529\" height=\"220\" alt=\"\" \/><br \/>\n\uc5ec\uae30\uc11c Primitive3D\uc640 Sphere3D, Cylinder3D, Cone3D\ub294 \uc0c8\ub86d\uac8c \uc815\uc758\ud55c \ud074\ub798\uc2a4\uc774\uace0 \ub098\uba38\uc9c0\ub294 \ubaa8\ub450 .NET\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ud074\ub798\uc2a4\uc774\ub2e4. ModelVisual3D\ub294 WPF\uc5d0\uc11c \ucd5c\uc885\uc801\uc73c\ub85c \ud654\uba74\uc0c1\uc5d0 \ub80c\ub354\ub9c1\ub420 \ub300\uc0c1\uc774 \ub418\ub294 \ud074\ub798\uc2a4\ub85c\uc368 \ub80c\ub354\ub9c1\ud560 Geometry \uc815\ubcf4 \uc800\uc7a5\uc744 \uc704\ud574 Model3D Type\uc758 GeometryModel3D \uc778\uc2a4\ud134\uc2a4\ub97c \ub9f4\ubc84\ub85c \uac16\ub294\ub2e4. \ubc14\ub85c \uc774 ModelVisual3D\ub85c\ubd80\ud130 \ud30c\uc0dd\ub41c \uc0c8\ub85c\uc6b4 Primitive3D\ub97c \ud1b5\ud574 \uc6b0\ub9ac\uac00 \uc6d0\ud558\ub294 \uad6c, \uc6d0\ud1b5 \ub4f1\uacfc \uac19\uc740 3D \uc694\uc18c\ub97c \ub80c\ub354\ub9c1\ud560 \uc218 \uc788\ub294 Geometry\ub97c \uad6c\uc131\ud558\ub294 \uac83\uc774\ub2e4. \uc774\uc81c Primitive3D \ud074\ub798\uc2a4\ub97c \uc0b4\ud3b4\ubcf4\uae30\ub85c \ud558\uc790. <\/p>\n<pre>using System; \r\nusing System.Windows; \r\nusing System.Windows.Media; \r\nusing System.Windows.Media.Media3D; \r\n \r\nnamespace Primitive3DSurfaces \r\n{ \r\n    public abstract class Primitive3D : ModelVisual3D \r\n    { \r\n        \/\/<1> \r\n        internal abstract Geometry3D Tessellate(); \r\n        \/\/<2> \r\n        internal readonly GeometryModel3D _content  \r\n            = new GeometryModel3D(); \r\n \r\n        \/\/<3>\r\n        public Primitive3D() \r\n        { \r\n            Content = _content; \r\n            _content.Geometry = Tessellate(); \r\n        } \r\n \r\n        \/\/<4-1> \r\n        public static DependencyProperty MaterialProperty = \r\n            DependencyProperty.Register( \r\n                \"Material\", \r\n                typeof(Material), \r\n                typeof(Primitive3D),  \r\n                new PropertyMetadata( null,  \r\n                    new PropertyChangedCallback(OnMaterialChanged))); \r\n        \/\/<4-2> \r\n        public Material Material \r\n        { \r\n            get { return (Material)GetValue(MaterialProperty); } \r\n            set { SetValue(MaterialProperty, value); } \r\n        } \r\n \r\n        \/\/<5> \r\n        internal static void OnMaterialChanged(Object sender,  \r\n            DependencyPropertyChangedEventArgs e) \r\n        { \r\n            Primitive3D p = ((Primitive3D)sender); \r\n            p._content.Material = p.Material; \r\n        } \r\n \r\n        \/\/<6> \r\n        internal static void OnGeometryChanged(DependencyObject d) \r\n        { \r\n            Primitive3D p = ((Primitive3D)d); \r\n            p._content.Geometry = p.Tessellate(); \r\n        } \r\n \r\n        \/\/<7> \r\n        internal double DegToRad(double degrees) \r\n        { \r\n            return (degrees \/ 180.0) * Math.PI; \r\n        } \r\n    } \r\n}<\/pre>\n<p>\uba3c\uc800, <1>\ubc88 \ucf54\ub4dc\uc758 \ubaa9\uc801\uc740 \uad6c, \uc6d0\ud1b5 \ub4f1\uc744 \uad6c\uc131\ud558\ub294 Vertex Point\uc640 Point Index, Texture \uc88c\ud45c\ub97c \uacc4\uc0b0\ud558\uc5ec \uc774 \uacc4\uc0b0\ub41c \uc815\ubcf4\ub97c \ub2f4\uc744 \uc218 \uc788\ub294 Geometry3D\ub97c \ubc18\ud658\ud574\uc8fc\ub294 \ucd94\uc0c1\ud568\uc218\ub85c\uc368 Primitive3D\uc758 \uac00\uc7a5 \ud575\uc2ec\uc774 \ub418\ub294 \ub9e4\uc11c\ub4dc\uc774\ub2e4. \uc989, \uad6c, \uc6d0\ud1b5 \ub4f1\uc740 \uac01\uac01 \uc774 Tessellate \ud568\uc218\ub97c \uc790\uc2e0\uc5d0 \ub9de\uac8c \uad6c\ud604\ud558\uc5ec \uc790\uc2e0\uc758 \ubaa8\uc591\uc744 \uad6c\uc131\ud558\ub294 \uac83\uc774\ub2e4. <\/p>\n<p><2>\ubc88 \ucf54\ub4dc\ub294 <1>\uc5d0\uc11c \uc18c\uac1c\ud55c Tessellate \ud568\uc218\uc5d0\uc11c \ubc18\ud658\ub41c \uc88c\ud45c \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\uae30 \uc704\ud55c GeometryModel3D\ub97c \uc0dd\uc131\ud558\ub294 \uac83\uc774\ub2e4. \ubcf4\ub2e4 \uc801\ud655\ud788 \ub9d0\ud55c\ub2e4\uba74 GeometryModel3D\uc758 Geometry \uba64\ubc84 \ubcc0\uc218\uc5d0 Tessellate\uc758 \ubc18\ud658 \uc815\ubcf4\uac00 \ub2f4\uae30\uac8c \ub41c\ub2e4. <\/p>\n<p><3>\ubc88 \ucf54\ub4dc\ub294 \uc0dd\uc131\uc790\ub85c\uc368 Primitive3D\uac00 \uc0c1\uc18d\ubc1b\uc740 ModelVisual3D\uc758 \uba64\ubc84\ubcc0\uc218\uc778 Content\ub97c \uc124\uc815\ud558\uace0 \uacc4\uc0b0\ub418\uc5b4\uc9c8 \uc88c\ud45c\ub97c \uad6c\ud55c\ud6c4 \uc124\uc815\ud558\uace0 \uc788\ub2e4. <\/p>\n<p><4-1>\uacfc <4-2>\ub294 \ubcf4\ub2e4 \ub9ce\uc740 \uc124\uba85\uc774 \ud544\uc694\ud55c\ub370, \uc5ec\uae30\uc11c\ub294 3D\uc5d0 \ub300\ud55c \uc124\uba85\uc774\ubbc0\ub85c \uac04\ub2e8\ud788 \uc124\uba85\ud558\ub3c4\ub85d \ud558\uaca0\ub2e4. \uc774 \ubd80\ubd84\uc744 \uc774\ud574\ud558\uae30 \uc704\ud574\uc11c\ub294 Dependency Property\uc774\ub77c\ub294 WPF\uc758 \uac1c\ub150\uc744 \uc54c\uc544\uc57c \ud558\ub294\ub370, Dependency Property\uc740 \ub370\uc774\ud130\ubc14\uc778\ub529\uc774\ub098 \ud2b8\ub9ac\uac70 \ucc98\ub9ac\ub4f1\uc5d0\uc11c \ud574\ub2f9 \uc18d\uc131\uc774 \uadf8 \ub300\uc0c1\uc774 \ub420 \uc218 \uc788\ub3c4\ub85d \ud558\ub294 \uac1c\ub150\uc774\ub2e4. \uc880\ub354 \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 \ucd94\ud6c4\uc5d0 Dependency Property\uc5d0 \ub300\ud574 \uc911\uc810\uc801\uc73c\ub85c \uc0b4\ud3b4\ubcfc \uae30\ud68c\ub97c \uac16\uaca0\ub2e4. <\/p>\n<p><5>\ub294 XAML\uc774\ub098 Code-Behind\uc758 \ucf54\ub4dc\ub97c \ud1b5\ud574\uc11c \uc7ac\uc9c8\uc5d0 \ub300\ud55c \uc18d\uc131\uc774 \ubcc0\uacbd\ub418\uc5c8\uc744\ub54c \ubc1c\uc0dd\ud558\ub294 \uc774\ubca4\ud2b8 \ucf54\ub4dc\uc774\ub2e4. <\/p>\n<p><6>\uc740 <5>\uc640 \ub9c8\ucc2c\uac00\uc9c0\ub85c Geometry \uad6c\uc131\uc815\ubcf4(\uc88c\ud45c, TextureMapping \uc88c\ud45c, \uc88c\ud45c Index)\uac00 \ubcc0\uacbd\ub418\uc5c8\uc744\ub54c \ubc1c\uc0dd\ub418\ub294 \ucf54\ub4dc\uc774\ub2e4. <\/p>\n<p>\ub9c8\uc9c0\ub9c9\uc73c\ub85c <7>\uc740 \uac04\ub2e8\ud55c \ubcf4\uc870 Utility \ud568\uc218\uc774\ub2e4. <\/p>\n<p>\uc774\uc81c \uc774 Primitive3D\uc5d0\uc11c \uc0c1\uc18d\ubc1b\uc740 Sphere3D \ud074\ub798\uc2a4\uc5d0 \ub300\ud574\uc11c \uc0b4\ud3b4\ubcf4\ub3c4\ub85d \ud558\uc790. \uadf8 \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. <\/p>\n<pre>using System; \r\nusing System.Windows; \r\nusing System.Windows.Media; \r\nusing System.Windows.Media.Media3D; \r\n \r\nnamespace Primitive3DSurfaces \r\n{ \r\n    public sealed class Sphere3D : Primitive3D \r\n    { \r\n        internal Point3D GetPosition(double t, double y) \r\n        { \r\n            double r = Math.Sqrt(1 - y * y); \r\n            double x = r * Math.Cos(t); \r\n            double z = r * Math.Sin(t); \r\n \r\n            return new Point3D(x, y, z); \r\n        } \r\n \r\n        private Vector3D GetNormal(double t, double y) \r\n        { \r\n            return (Vector3D) GetPosition(t, y); \r\n        } \r\n \r\n        private Point GetTextureCoordinate(double t, double y) \r\n        { \r\n            Matrix TYtoUV = new Matrix(); \r\n            TYtoUV.Scale(1 \/ (2 * Math.PI), -0.5); \r\n \r\n            Point p = new Point(t, y); \r\n            p = p * TYtoUV; \r\n \r\n            return p; \r\n        } \r\n \r\n        internal override Geometry3D Tessellate() \r\n        { \r\n            int tDiv = 32; \r\n            int yDiv = 32; \r\n            double maxTheta = DegToRad(360.0); \r\n            double minY = -1.0; \r\n            double maxY = 1.0; \r\n \r\n            double dt = maxTheta \/ tDiv; \r\n            double dy = (maxY - minY) \/ yDiv; \r\n \r\n            MeshGeometry3D mesh = new MeshGeometry3D(); \r\n \r\n            for (int yi = 0; yi <= yDiv; yi++) \r\n            { \r\n                double y = minY + yi * dy; \r\n \r\n                for (int ti = 0; ti <= tDiv; ti++) \r\n                { \r\n                    double t = ti * dt; \r\n \r\n                    mesh.Positions.Add(GetPosition(t, y)); \r\n                    mesh.Normals.Add(GetNormal(t, y)); \r\n                    mesh.TextureCoordinates.Add(GetTextureCoordinate(t, y)); \r\n                } \r\n            } \r\n \r\n            for (int yi = 0; yi < yDiv; yi++) \r\n            { \r\n                for (int ti = 0; ti < tDiv; ti++) \r\n                { \r\n                    int x0 = ti; \r\n                    int x1 = (ti + 1); \r\n                    int y0 = yi * (tDiv + 1); \r\n                    int y1 = (yi + 1) * (tDiv + 1); \r\n \r\n                    mesh.TriangleIndices.Add(x0 + y0); \r\n                    mesh.TriangleIndices.Add(x0 + y1); \r\n                    mesh.TriangleIndices.Add(x1 + y0); \r\n \r\n                    mesh.TriangleIndices.Add(x1 + y0); \r\n                    mesh.TriangleIndices.Add(x0 + y1); \r\n                    mesh.TriangleIndices.Add(x1 + y1); \r\n                } \r\n            } \r\n \r\n            mesh.Freeze(); \r\n            return mesh; \r\n        } \r\n    } \r\n}<\/pre>\n<p>\uac00\uc7a5 \ud575\uc2ec\uc801\uc774\uace0 \uc720\uc77c\ud558\uac8c \uc9d1\uc911\ud574\uc57c\ud558\ub294 \ucf54\ub4dc\ub294 \uc5ed\uc2dc Override\ub41c Tessellate \ub9e4\uc11c\ub4dc\uc774\ub2e4. \ucf54\ub4dc\ub97c \ubcf4\uba74 \ubc18\ud658\ud560 Geometry3D\uc5d0\uc11c \uc0c1\uc18d\ub41c MeshGeometry3D\ub97c \uc0dd\uc131\ud55c \ud6c4, \uc774 \uc0dd\uc131\ub41c \uc778\uc2a4\ud134\uc2a4\uc5d0 \uc704\uce58 \uc88c\ud45c, \uc0bc\uac01\ud615 Index, TextureMapping \uc88c\ud45c\ub97c \uacc4\uc0b0\ud558\uc5ec \uadf8 \uac12\ub4e4\uc744 \ucd94\uac00\ud558\uace0 \uc788\uc74c\uc744 \uc54c \uc218 \uc788\ub2e4. <\/p>\n<p>\ub05d\uc73c\ub85c \uc6d0\ud1b5\uacfc \uc6d0\ubfd4\uc5d0 \ub300\ud55c \ucf54\ub4dc\ub97c \uc81c\uc2dc\ud55c\ub2e4. \uc11c\ub85c \ube44\uad50\ud558\uba70 \ubd84\uc11d\ud574 \ubcf4\uae38\ubc14\ub780\ub2e4. <\/p>\n<pre>using System; \r\nusing System.Windows; \r\nusing System.Windows.Media; \r\nusing System.Windows.Media.Media3D; \r\n \r\nnamespace Primitive3DSurfaces \r\n{ \r\n    public sealed class Cylinder3D : Primitive3D \r\n    { \r\n        internal Point3D GetPosition(double t, double y) \r\n        { \r\n            double x = Math.Cos(t); \r\n            double z = Math.Sin(t); \r\n \r\n            return new Point3D(x, y, z); \r\n        } \r\n \r\n        private Vector3D GetNormal(double t, double y) \r\n        { \r\n            double x = Math.Cos(t); \r\n            double z = Math.Sin(t); \r\n \r\n            return new Vector3D(x, 0, z); \r\n        } \r\n \r\n        private Point GetTextureCoordinate(double t, double y) \r\n        { \r\n            Matrix m = new Matrix(); \r\n            m.Scale(1 \/ (2 * Math.PI), -0.5); \r\n \r\n            Point p = new Point(t, y); \r\n            p = p * m; \r\n \r\n            return p; \r\n        } \r\n \r\n        internal override Geometry3D Tessellate() \r\n        { \r\n            int tDiv = 32; \r\n            int yDiv = 32; \r\n            double maxTheta = DegToRad(360.0); \r\n            double minY = -1.0; \r\n            double maxY = 1.0; \r\n \r\n            double dt = maxTheta \/ tDiv; \r\n            double dy = (maxY - minY) \/ yDiv; \r\n \r\n            MeshGeometry3D mesh = new MeshGeometry3D(); \r\n \r\n            for (int yi = 0; yi <= yDiv; yi++) \r\n            { \r\n                double y = minY + yi * dy; \r\n \r\n                for (int ti = 0; ti <= tDiv; ti++) \r\n                { \r\n                    double t = ti * dt; \r\n \r\n                    mesh.Positions.Add(GetPosition(t, y)); \r\n                    mesh.Normals.Add(GetNormal(t, y)); \r\n                    mesh.TextureCoordinates.Add(GetTextureCoordinate(t, y)); \r\n                } \r\n            } \r\n \r\n            for (int yi = 0; yi < yDiv; yi++) \r\n            { \r\n                for (int ti = 0; ti < tDiv; ti++) \r\n                { \r\n                    int x0 = ti; \r\n                    int x1 = (ti + 1); \r\n                    int y0 = yi * (tDiv + 1); \r\n                    int y1 = (yi + 1) * (tDiv + 1); \r\n \r\n                    mesh.TriangleIndices.Add(x0 + y0); \r\n                    mesh.TriangleIndices.Add(x0 + y1); \r\n                    mesh.TriangleIndices.Add(x1 + y0); \r\n \r\n                    mesh.TriangleIndices.Add(x1 + y0); \r\n                    mesh.TriangleIndices.Add(x0 + y1); \r\n                    mesh.TriangleIndices.Add(x1 + y1); \r\n                } \r\n            } \r\n \r\n            mesh.Freeze(); \r\n            return mesh; \r\n        } \r\n    } \r\n}<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.gisdeveloper.co.kr\/wp-content\/uploads\/1\/1036954679.png\" class=\"aligncenter\" width=\"497\" height=\"336\" alt=\"\" \/><\/p>\n<pre>using System; \r\nusing System.Windows; \r\nusing System.Windows.Media; \r\nusing System.Windows.Media.Media3D; \r\n \r\nnamespace Primitive3DSurfaces \r\n{ \r\n    public sealed class Cone3D : Primitive3D \r\n    { \r\n        internal Point3D GetPosition(double t, double y) \r\n        { \r\n            double r = (1 - y) \/ 2; \r\n            double x = r * Math.Cos(t); \r\n            double z = r * Math.Sin(t); \r\n \r\n            return new Point3D(x, y, z); \r\n        } \r\n \r\n        private Vector3D GetNormal(double t, double y) \r\n        { \r\n            double x = 2 * Math.Cos(t); \r\n            double z = 2 * Math.Sin(t); \r\n \r\n            return new Vector3D(x, 1, z); \r\n        } \r\n \r\n        private Point GetTextureCoordinate(double t, double y) \r\n        { \r\n            Matrix m = new Matrix(); \r\n            m.Scale(1 \/ (2 * Math.PI), -0.5); \r\n \r\n            Point p = new Point(t, y); \r\n            p = p * m; \r\n \r\n            return p; \r\n        } \r\n \r\n        internal override Geometry3D Tessellate() \r\n        { \r\n            int tDiv = 32; \r\n            int yDiv = 32; \r\n            double maxTheta = DegToRad(360.0); \r\n            double minY = -1.0; \r\n            double maxY = 1.0; \r\n \r\n            double dt = maxTheta \/ tDiv; \r\n            double dy = (maxY - minY) \/ yDiv; \r\n \r\n            MeshGeometry3D mesh = new MeshGeometry3D(); \r\n \r\n            for (int yi = 0; yi <= yDiv; yi++) \r\n            { \r\n                double y = minY + yi * dy; \r\n \r\n                for (int ti = 0; ti <= tDiv; ti++) \r\n                { \r\n                    double t = ti * dt; \r\n \r\n                    mesh.Positions.Add(GetPosition(t, y)); \r\n                    mesh.Normals.Add(GetNormal(t, y)); \r\n                    mesh.TextureCoordinates.Add(GetTextureCoordinate(t, y)); \r\n                } \r\n            } \r\n \r\n            for (int yi = 0; yi < yDiv; yi++) \r\n            { \r\n                for (int ti = 0; ti < tDiv; ti++) \r\n                { \r\n                    int x0 = ti; \r\n                    int x1 = (ti + 1); \r\n                    int y0 = yi * (tDiv + 1); \r\n                    int y1 = (yi + 1) * (tDiv + 1); \r\n \r\n                    mesh.TriangleIndices.Add(x0 + y0); \r\n                    mesh.TriangleIndices.Add(x0 + y1); \r\n                    mesh.TriangleIndices.Add(x1 + y0); \r\n \r\n                    mesh.TriangleIndices.Add(x1 + y0); \r\n                    mesh.TriangleIndices.Add(x0 + y1); \r\n                    mesh.TriangleIndices.Add(x1 + y1); \r\n                } \r\n            } \r\n \r\n            mesh.Freeze(); \r\n            return mesh; \r\n        } \r\n    } \r\n}<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.gisdeveloper.co.kr\/wp-content\/uploads\/1\/1367663552.png\" class=\"aligncenter\" width=\"497\" height=\"307\" alt=\"\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uce5c\uc808\ud55c \uae08\uc790\uc528\ub791 \uc0c1\uad00\uc5c6\ub294 WPF\ub294 \ub9e4\uc6b0 \ubd88\uce5c\uc808\ud558\uac8c\ub3c4 3D\uc5d0\uc11c \uad6c, \uc6d0\ud1b5, \uc6d0\ubfd4 \ub4f1\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 Geometry\ub97c \uc27d\uac8c \ub098\ud0c0\ub0bc \uc218\uac00 \uc5c6\ub2e4. \uc624\uc9c1 WPF\ub294 \uc138\uac1c\uc758 Point\ub85c \uad6c\uc131\ub41c \uc0bc\uac01\ud615(Triangle) Geometry\ub9cc\uc744 \ub098\ud0c0\ub0bc \uc218 \uc788\ub2e4. \uadf8\ub7f0\uc989, \uad6c, \uc6d0, \uc6d0\ubfd4\uc744 \ub098\ud0c0\ub0b4\uae30 \uc704\ud574\uc11c\ub294 \uac1c\ubc1c\uc790 \uc9c1\uc811 \uc0bc\uac01\ud615 \uc694\uc18c\ub97c \uc870\ud569\ud558\ub294 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec\uc57c\ub9cc \ud55c\ub2e4. \ubc14\ub85c \uc774 \uae00\uc774 \uc774\ub7ec\ud55c \ucf54\ub4dc\ub97c \uc704\ud55c \uac83\uc774\ub2e4. \ud2b9\ud788 XAML\uc744 \uc774\uc6a9\ud558\uc5ec \uad6c, \uc6d0\ud1b5 \ub4f1\uc758 &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/www.gisdeveloper.co.kr\/?p=360\" class=\"more-link\">\ub354 \ubcf4\uae30<span class=\"screen-reader-text\"> &#8220;\uad6c(Sphere), \uc6d0\ud1b5(Cylinder), \uc6d0\ubfd4(Cone) \ub80c\ub354\ub9c1&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[19],"class_list":["post-360","post","type-post","status-publish","format-standard","hentry","category-wpf","tag-wpf-3d"],"_links":{"self":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/360","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=360"}],"version-history":[{"count":1,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/360\/revisions"}],"predecessor-version":[{"id":3630,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/360\/revisions\/3630"}],"wp:attachment":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=360"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=360"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=360"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}