Рисование линий под увеличивающимися углами - PullRequest
4 голосов
/ 06 апреля 2011

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

Я пробовал это:

len = 300;
angle = 10;

for (i = 0; i <= 5; ++i) {
    endPointX = 50 + len * Math.cos(angle);
    endPointY = 50 + len * Math.tan(angle);
    draw.Line(50, 50, endPointX, endPointY);
    angle += 10;
}

Тем не менее, это совершенно неправильно и производит что-то вроде этого

http://i.stack.imgur.com/taX40.png

Но я хочу что-то вроде этого (плохой mspaint, извините):

http://i.stack.imgur.com/8xfpp.png

Какая математика для этого подходит?

Ответы [ 4 ]

9 голосов
/ 06 апреля 2011

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


Вот изображение ASCII вашей ситуации:

                   B
                   +
                  /|
                 / |
                /  |
               /   |
         len  /    | y
             /     |
            /      |
           /       |
          /      __|
         / θ    |  |
        +----------+
      A      x       C

Это прямоугольный треугольник. Он имеет три стороны:

  • Диагональная сторона на рисунке, противоположная углу 90 °, называется гипотенузой и имеет длину len. Гипотенуза - это то, что вы пытаетесь нарисовать.
  • Вертикальная сторона является стороной, противоположной углу θ, и имеет длину y.
  • Горизонтальная сторона является стороной, смежной с углом θ, и имеет длину x.

Учитывая приведенную выше иллюстрацию, справедливы следующие уравнения:

cos(θ) = x/len
sin(θ) = y/len

Эти уравнения являются еще одним способом сказать:

  • Косинус угла равен длине соседней стороны, деленной на длину гипотенузы.
  • Синус угла равен длине противоположной стороны, деленной на длину гипотенузы.

При решении уравнения для x и y вы получите:

x = len * cos(θ)
y = len * sin(θ)

То есть вы хотите sin() и cos(), а не cos() и tan(). Если точка A не находится в начале координат, вам необходимо сместить x и y путем сложения, например:

x = len * cos(θ) + 50
y = len * sin(θ) + 50

С помощью значений x и y вы можете найти координаты для точки B на треугольнике и, таким образом, сможете нарисовать ваши линии.


Кроме того, если вы программируете на Java, тригонометрические функции в классе Math ожидают угол в радианах , а не в градусах. Многие языки программирования, которые предоставляют тригонометрические функции, похожи на это.

Радианы и градусы измеряют одно и то же, но полное вращение в градусах идет от 0 до 360°, а полное вращение в радианах - от 0 до .

Чтобы преобразовать углы в градусах в радианы, умножьте угол на π/180. В Java константа π предоставляется Math.PI.

Например, угол в 10 ° градусов эквивалентен 10 * π/180 или π/18 радиан.

0 голосов
/ 06 апреля 2011

Вы должны использовать не загар, а грех. Если я правильно помню, это должно быть что-то вроде: Math.cos (угол / 180); -Math.sin (угол / 180); Негатив на грехе важен.

0 голосов
/ 06 апреля 2011

Причина, по которой вы получаете неровные углы, состоит в том, что каждый раз, когда вы добавляете 10, вы фактически вращаете линию вокруг круга в 1,6 раза.

Математические функции предполагают, что углы будут в радианах, а не в градусах.

360 градусов = 2 * Math.PI радианы.

Вместо 10 напишите "2 * Math.PI / 36.0"

Кроме того, вместо греха используйте грех.

0 голосов
/ 06 апреля 2011

Во-первых, вы хотите cos и sin, а не cos и tan.

Во-вторых, большинство математических библиотек выполняют тригонометрические функции в радианах, а не в градусах. Так что 10 действительно очень большая разница! Чтобы преобразовать градусы в радианы, умножьте на (pi/180).

...