Каким образом можно построить на C# изображение шара как многогранника?
Формулировка задачи:
Какие средства можно использовать в Visual Studio? И как можно это реализовать?
Должно выйти нечто из разряда трёхмерных объектов!!!
Решение задачи: «Каким образом можно построить на C# изображение шара как многогранника?»
textual
Листинг программы
class Triangle { public IList<Vector3> Vertices = new Vector3[3]; public IList<Triangle> ApplyBisection() { var middles = Vertices.Select((v, i) => (v + Vertices[(i + 1) % 3]) / 2).ToList(); var res = new List<Triangle>(); for (int i = 0; i < 3; i++) { var triangle = new Triangle(); triangle.Vertices[0] = Vertices[i]; triangle.Vertices[1] = middles[i]; triangle.Vertices[2] = middles[(i - 1 + 3) % 3]; res.Add(triangle); } res.Add(new Triangle { Vertices = middles }); return res; } public Vector3 Middle => Vertices.Aggregate((r, v) => r + v) / 3; } static class FloatExtentions { public static float ToDegrees(this float radians) { return (float)(radians * 180 / Math.PI); } public static float ToRadians(this float degrees) { return (float)(degrees * Math.PI / 180); } } class IcosahedronBuilder { private IList<Vector3> _topRing = new List<Vector3>(); private IList<Vector3> _bottomRing = new List<Vector3>(); private Vector3 _top = new Vector3(0, 1, 0); private Vector3 _bottom = new Vector3(0, -1, 0); private IList<Vector3> BuildTopRing() { var result = new List<Vector3>(); var basis = new Vector3(0, 0, -1); float pitch = 30f.ToRadians(); for (int i = 0; i < 5; i++) { float yaw = -(360f / 5f * i).ToRadians(); var transform = Matrix4x4.CreateFromYawPitchRoll(yaw, pitch, 0); result.Add(Vector3.Transform(basis, transform)); } return result; } private IList<Vector3> BuildBottomRing(IList<Vector3> topRing) { var transform = Matrix4x4.CreateFromYawPitchRoll((360f / 10f).ToRadians(), 0, 0f.ToRadians()); transform = transform * Matrix4x4.CreateScale(1, -1, 1); return topRing.Select(p => Vector3.Transform(p, transform)).ToList(); } public List<Triangle> Build() { _topRing = BuildTopRing(); _bottomRing = BuildBottomRing(_topRing); var result = new List<Triangle>(); for (int i = 0; i < _topRing.Count; i++) { var triangle = new Triangle(); triangle.Vertices[0] = _top; triangle.Vertices[1] = _topRing[i]; triangle.Vertices[2] = _topRing[(i + 1) % _topRing.Count]; result.Add(triangle); } for (int i = 0; i < _topRing.Count; i++) { var triangle = new Triangle(); triangle.Vertices[0] = _topRing[i]; triangle.Vertices[1] = _bottomRing[i]; triangle.Vertices[2] = _bottomRing[(i + 1) % _bottomRing.Count]; result.Add(triangle); } for (int i = 0; i < _bottomRing.Count; i++) { var triangle = new Triangle(); triangle.Vertices[0] = _bottomRing[i]; triangle.Vertices[1] = _topRing[i]; triangle.Vertices[2] = _topRing[(i - 1 + _topRing.Count) % _topRing.Count]; result.Add(triangle); } for (int i = 0; i < _bottomRing.Count; i++) { var triangle = new Triangle(); triangle.Vertices[0] = _bottom; triangle.Vertices[1] = _bottomRing[i]; triangle.Vertices[2] = _bottomRing[(i - 1 + _bottomRing.Count) % _bottomRing.Count]; result.Add(triangle); } return result; } } class Model { public IList<Triangle> Triangles = new List<Triangle>(); } class MainForm : Form { private Model _model = new Model(); public MainForm() { base.DoubleBuffered = true; base.WindowState = FormWindowState.Maximized; _model.Triangles = new IcosahedronBuilder().Build(); for (int i = 0; i < 2; i++) { _model.Triangles = _model.Triangles.SelectMany(t => { IList<Triangle> derivatives = t.ApplyBisection(); foreach (var triangle in derivatives) { triangle.Vertices = triangle.Vertices.Select(v => Vector3.Normalize(v)).ToList(); } return derivatives; }).ToList(); } var scale = Matrix4x4.CreateScale(200, -200, 200); var translate = Matrix4x4.CreateTranslation(500, 500, 0); var transform = scale * translate; foreach (var triangle in _model.Triangles) triangle.Vertices = triangle.Vertices.Select(v => Vector3.Transform(v, transform)).ToList(); } protected override void OnPaint(PaintEventArgs e) { var g = e.Graphics; g.SmoothingMode = SmoothingMode.HighQuality; using (var gp = new GraphicsPath()) using (var brush = new SolidBrush(Color.Black)) { foreach (var triangle in _model.Triangles.OrderByDescending(t => t.Middle.Z)) { gp.AddPolygon(triangle.Vertices.Select(v => new PointF(v.X, v.Y)).ToArray()); var n = Vector3.Cross(triangle.Vertices[2] - triangle.Vertices[1], triangle.Vertices[1] - triangle.Vertices[0]); n = 10 * Vector3.Normalize(n); var light = 1 - 0.8f * new Vector3(n.X, n.Y, 0).Length()/n.Length();//1 - cos(a) int gray = (int)(light * 255); brush.Color = Color.FromArgb(gray, gray, gray); g.FillPath(brush, gp); //g.DrawPath(Pens.Red, gp); gp.Reset(); } } } } void Main() { Application.Run(new MainForm()); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д