User 11061201 Ответов: 2

Нарисуйте маркеры вдоль градусных точек на некруглом эллипсе/струне, деформирующейся вдоль пути


В настоящее время я рисую доску для рулетки в vbnet, и я застрял, когда мне приходится иметь дело с овальным объектом, который имеет 2 радиуса, а не идеальный круг.
Я пытаюсь достичь каждой степени в то время как (360 / 37) * Z
Я делал все другие рисунки, дуги, пироги и т. д., Даже когда имел дело с овальными объектами, но не тогда, когда я пытался получить очевидные X и Y степени, когда эллипс сжимается в высоту, сохраняя свою прежнюю ширину.
Следует также отметить, что маркеры складываются в логический паттерн, но поворачиваются на 90 градусов.

Private Sub DrawText(ByVal gr As Graphics, _
                      ByVal centreX As Double, _
                      ByVal centreY As Double, _
                      ByVal radiusX As Double, _
                      ByVal radiusY As Double, _
                      ByVal part As Double)




     Dim x, y As Double

     Dim count As Integer = -1
     For value As Double = 0.0R To (Math.PI * 2) Step +(part * 4)
         count += 1

         Dim Xcalc As Double = (radiusX / 2) * Math.Cos(value + (-180 * (Math.PI / 360)))
         x = (Me.ClientSize.Width / 2) + Xcalc

         Dim Ycalc As Double = (radiusY / 2) * Math.Sin(value + (-180 * (Math.PI / 360)))
         y = (Me.ClientSize.Height / 2) + Ycalc

         'draw marker on degree
         gr.FillEllipse(Brushes.SteelBlue, New Rectangle(x - 7, y - 7, 14, 14))

     Next

 End Sub


ИЗОБРАЖЕНИЕ
http://i.imgur.com/pCrjWQv.png

Что я уже пробовал:

Отредактировал код для лучшей читабельности

Sergey Alexandrovich Kryukov

- Овальный эллипс?" Как хороший. Есть ли треугольные или какие? Кстати, существует другой термин геометрического "овала", который не является эллипсом.
Так что же это за случай, когда "когда эллипс имеет овальную форму"? Вы имеете в виду, что он повернут, перекошен или что? Чего именно вы пытаетесь достичь?
—СА

Sergey Alexandrovich Kryukov

Нет! Это не верно для эллипса.

Ни один из двух параметров, которые могут определять эллипс, не является «радиусом». Вы, вероятно, перепутали эллипс с овалом, приближающимся к эллипсу; такое приближение в основном является мертвой практикой, которая использовалась в ручном техническом рисовании. Некоторое обобщение понятия «радиус» - это всего лишь одно значение; он описывается как сумма линий: проведите линию от одного фокуса к любой точке линии эллипса, от этой точки проведите линию к другому фокусу. Для эллипса это постоянное значение, которое можно использовать как обобщение понятия «радиус» (точнее, половину этого значения). Очевидно, что для круга, который является частным случаем эллипса, точки фокусировки также сходятся в центре круга, и два описанных мной отрезка линии становятся двумя равными радиусами.

Вы также можете определить свой эллипс по ширине и высоте, но это происходит в системе координат, когда он не вращается.

Смотрите, это часть элементарной математики (или почти элементарной). Вы уверены, что находитесь на нужном сайте? Возможно, вам сначала нужно изучить необходимые математические основы. Я понимаю, почему вы спрашиваете об этом здесь, потому что вы пишете код, но вы должны быть немного более подготовленными. Я не дам вам точного ответа, прежде всего потому, что я не уверен, чего вы пытаетесь достичь. Вы делаете какое-то преобразование. Не мешает ли это вашей проблеме? Сможете ли вы определить свой угол без преобразования, а затем использовать его? Какой именно угол вам нужен? Не используйте неприменимые концепции. Точно сформулируйте геометрическое значение или конструкцию.

—СА

[no name]

Извините, то, что я говорил, не является нарисованным от руки эллипсом. Я имел в виду только два вида эллипсов, один из которых представляет собой круг, скажем, нарисованный внутри прямоугольника размером 50, 50, а другой-асимметричный эллипс, нарисованный на прямоугольнике с границами 50, 70 мат8. И тут у меня возникли проблемы. Нет, трансформация не подразумевает этого, так как я показывал пример с рисованием точек. Вы видели эту фотографию?
Кроме того, если у вас нет идеи, то не дискредитируйте мой вопрос.

Sergey Alexandrovich Kryukov

Что такое "нарисованный от руки эллипс"? О чем ты вообще говоришь? Сделайте себе одолжение, изучите геометрию в соответствующей области. В прямоугольнике можно нарисовать много разных эллипсов (их континуум), но чтобы максимально заполнить прямоугольник размером 50х50, нужно иметь круглую форму, частный случай эллипса. Что такое" асимметричный эллипс"? Все они довольно симметричны... :-)

Я вижу картину, ну и что? Какие линии на этом рисунке представляют угол, который вас интересует? Не волнуйтесь, я легко создам геометрию рулетки. Я просто не знаю, какая часть этого создает для тебя проблему.
(Вздыхать...)

Теперь это просто грубо: "кроме того, если у вас нет идеи, то не дискредитируйте мой вопрос."
Это вы "дискредитируете" свой вопрос. Это ты не даешь мне такой идеи, даже по моей просьбе. Чтобы что-то дискредитировать, это "что-то" нужно приписать.
Помните ли вы, что вы не более свободны, чем другие члены; все имеют равное право на речь (не говоря уже о том, что я действительно пытаюсь вам помочь)? Как вы думаете, кто поможет вам с вашим, по сути, "пожалуйста, заткнись" поведением?

—СА

Sergey Alexandrovich Kryukov

Все еще не ясно. Что значит "достичь каждой степени в то время как (360 /37) * Z"? И так далее...

Я могу предложить, что вы можете сделать. Вы спрашиваете об углах между чем-то и чем-то. Вы можете сделать следующее: нарисовать 2 или 4 линии, сделать точки На концах линии
сегменты и отметьте их буквами и скажите что-то вроде:
"Рассмотрим угол A-C-B и X-C-Z". На настоящей рулетке они должны быть равны, но на моем рисунке они не равны. Они должны быть результатом моего транформирования из-за взгляда под некоторым углом, а не перпендикулярно плоскости эллипса. На чертеже они не должны быть равны, благодаря этому преобразованию, но должны производить впечатление равных углов".

Вас это беспокоит? Или что-то другое? Тогда решение довольно простое. Однако с 3D-рулеткой все не так просто. Более реалистичная рулетка имеет коническую форму. Внешний ободок немного приподнят над внутренним ободом, поэтому черная и считывающая пластины поверхности между ними должны быть коническим сегментом. Обычный 2D-рисунок с эллипсами здесь не поможет. Эллипсы можно просто сдвинуть друг относительно друга по вертикали, вот и все, но поверхность между ними не будет результатом какого-либо аффинного преобразования. Вам нужно будет математически рассчитать каждый сегмент линий на конической поверхности, или вам нужно будет использовать программное обеспечение для 3D-рендеринга, такое как WPF ...

Ваша проблема такова: на картинке отчетливо видно, что вы пытаетесь нарисовать плоскую рулетку, что нереально. Ваша картина вертикально симметрична, но таковой быть не должна, из-за того, что внешний обод приподнят в реальности. Но в этом случае все связанные с этим проблемы тривиальны.

—СА

2 Ответов

Рейтинг:
20

Sergey Alexandrovich Kryukov

Я фактически дал вам ответ в своем последнем комментарии, том самом, с углами" A-C-B "и" X-C-Z". Прежде чем вы проясните свою проблему, я могу дать вам решение для простой рулетки, которую вы пытаетесь изобразить, плоской рулетки.

Вот в чем идея. Поскольку кажется, что у вас нет никаких проблем с рендерингом рулетки, показанной непосредственно сверху, когда все круглые фигуры остаются круглыми. Если вы хотите показать ту же самую рулетку, предполагая, что она плоская (см. Мой комментарий о приподнятом ободке), сделайте такую простую вещь: нарисуйте все для точно круглой концентрической картины, то есть с эллипсами, являющимися строго круглыми, как видно сверху. Сделайте всю визуализацию: все круги, все прямые, как сегменты, заполните все цветами.

После того, как эта работа будет выполнена, вам нужно преобразовать свою картину в картину, видимую под углом. Для этого просто выполните некоторое преобразование к вашему экземпляру Graphics В этом случае вам нужно вертикально выровнять картинку. Это можно сделать с помощью метода System.Drawing.Drawing2D.Matrix.Scale, используя 1 для первого аргумента (горизонтальное направление) и некоторое значение < 1 для второго аргумента (вертикальное направление). Пожалуйста, смотрите:
Матрицы.Данные Метод (Один, Один) (Система.Рисование.Drawing2D)[^],
Матричный Класс (System.Рисование.Drawing2D)[^],
Графика.Свойство Преобразования (System.Рисование)[^].

Я думаю, что эта техника будет легкой для вас, потому что она не требует никакой реальной математики. Кроме того, я думаю, что уже видел, что вы используете System.Drawing.Graphics.Transform, так что использование его не будет проблемой.



А как насчет более реалистичного 3D-изображения? Я уже объяснил: это будет значительно сложнее. Даже если бы внешний обод был приподнят, но коническая поверхность не была «сегментирована» и раскрашена по своему рисунку, это было бы просто: вы могли бы просто сдвинуть внешний ободок вверх и заполнить пространство между ободами перед преобразованием. Но с линиями и разными цветами на конической поверхности этого не сделать. И, конечно же, все мои соображения неприменимы, если вы хотите показать правильное освещение и тени. Если вам все это нужно, я уже объяснил, чем вам нужно заниматься: вы должны либо выполнить всю трехмерную математику, включая расчет всех форм в вашей проекции, что требует много работы, либо вы можете переключиться на трехмерную графику. рендеринг, в частности, OpenGL или WPF:
OpenGL-Википедия, свободная энциклопедия[^],
Обзор Трехмерной Графики[^],
Обзор 3-D Преобразований[^].

Для использования 3D-графики WPF вам следует либо полностью переключиться на пользовательский интерфейс WPF (рекомендуется), либо использовать WPF в своем System.Windows.Forms Пользовательский интерфейс, который также возможен, таким образом: Пошаговое руководство: размещение составного элемента управления WPF в Windows Forms[^].

В частности, об OpenGL для .NET см.:
SharpGL-Главная[^],
эта статья CodeProject также может быть полезна: OpenGL в .NET-начало работы[^].

Смотреть также: 3D-моделирование-Википедия, свободная энциклопедия[^].

Если у вас другие проблемы или у вас есть другие вопросы, пожалуйста, уточните. Помните мой совет о том, как вы могли бы сформулировать свой вопрос в терминах углов A-C-B и X-C-Z или что-то в этом роде.

И, пожалуйста, сделайте себе большое одолжение: не будьте больше таким грубым, не говорите людям, которые просто пытаются Вам помочь и разъяснить, в чем ваша проблема, что они должны "не дискредитировать" ваш вопрос, который, по сути, является способом попросить людей заткнуться. С такими разговорами вряд ли можно надеяться на хорошую помощь.

—СА


[no name]

Это классный расчет и простая мысль для тех, кто возится с этой проблемой.

Sergey Alexandrovich Kryukov

Спасибо. Чем вы собираетесь принять его формально?
—СА

Рейтинг:
11

User 11061201

Я понял это и понял, что решение, которое я искал, требовало далеко продвинутых навыков математической геометрии. Я нашел более простой хак, используя Arc GraphicsPath(Drawing2D) - PathPoints

Смоделируйте дугу, проведенную вокруг эллипса, а затем получите его точки траектории...

  Private Sub DrawText(ByVal gr As Graphics, ByVal rect As Rectangle)

        For value As UShort = 0 To 36 '37Parts of Roulette Wheel

            Dim sz As New PointF(-90.0F + ((360.0F / 37) * (37 - value)), _
                               (360.0F / 37.0F) * 1)
            Dim gp As New GraphicsPath()
            gp.AddArc(rect, sz.X, sz.Y)
            Dim FirstPoint As PointF = gp.PathPoints(0)
            'Dim MidPoint As PointF = gp.PathPoints(gp.PathPoints.Length / 2)

            'DRAW FILLED ELLIPSE
            gr.FillEllipse(Brushes.SteelBlue, _
New Rectangle(FirstPoint.X - 7, FirstPoint.Y - 7, 14, 14))


            'DRAW TEXT (Not complete)
            'gr.TranslateTransform(FirstPoint.X - 6.0F, FirstPoint.Y - 6.0F)
            'gr.RotateTransform(CSng(360 / 37) * (37 - value))
            'Dim ft As Font = New Font("Arial", 12.0F, FontStyle.Regular)
            'gr.DrawString(EUR_ROULETTE(value).ToString, ft, Brushes.White, 0, 0)
            'gr.ResetTransform()
        Next

    End Sub

СМОТРИТЕ КАРТИНКУ
http://i.imgur.com/CjpMyDP.png




Спасибо вам SA за ваши усилия, и хит 5 звезд


Sergey Alexandrovich Kryukov

Добро пожаловать. Вы собираетесь официально принять последнюю версию моего ответа?
—СА

CHill60

Было бы неплохо, если бы вы официально признали длинные ответы SA, а не публиковали свои собственные решения (два!), а затем официально приняли свои собственные решения, а не человека, который явно потратил довольно много времени, пытаясь помочь вам