Поворот точки вокруг точки

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Александр Дмитриев
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 296
Зарегистрирован: 05.01.2005 (Ср) 3:39
Откуда: Санкт-Петербург    Куда: /dev/null

Поворот точки вокруг точки

Сообщение Александр Дмитриев » 28.08.2005 (Вс) 3:30

Второй день парюсь с ерундой какой-то. :bounce: :x :x Помогите, пожалуйста, кто может! Сделал программу - рисует звёздочку вертящуюся:
На форме только таймер (Timer1), код формы (Form1):
Код: Выделить всё
Dim tmrCount As Integer

Private Sub Form_Load()
Mod1.DrawStar Form1, 0
End Sub

Private Sub Timer1_Timer()
tmrCount = tmrCount + 1
If tmrCount = 360 Then
tmrCount = 0
End If
Mod1.DrawStar Form1, tmrCount
End Sub

Ещё модуль (Mod1):
Код: Выделить всё
Type CoordVozvrat
x As Single
y As Single
End Type

Sub DrawStar(pic As Form, Angle As Integer)
Dim Psets(16, 4) As Single
pic.Cls
For T = 1 To 5 Step 0.08
Psets(1, 1) = (((T - 0.2) / 0.08) + 60) * 15 + 120
Psets(2, 1) = ((((1 / T) - 0.2) / 0.08) + 60) * 15 + 120
Psets(3, 1) = (((T - 0.2) / 0.08) + 60) * 15 + 120
Psets(4, 1) = ((((1 / T) - 0.2) / 0.08) + 60) * 15 + 120
Psets(5, 1) = (60 - (((1 / T) - 0.2) / 0.08)) * 15 + 120
Psets(6, 1) = (60 - ((T - 0.2) / 0.08)) * 15 + 120
Psets(7, 1) = (60 - ((T - 0.2) / 0.08)) * 15 + 120
Psets(8, 1) = (60 - (((1 / T) - 0.2) / 0.08)) * 15 + 120
Psets(9, 1) = (Cos(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) + 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(10, 1) = (Cos(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) + 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(11, 1) = (Cos(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) + 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(12, 1) = (Cos(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) + 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(13, 1) = (60 - Cos(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) - 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2)) * 15 + 120
Psets(14, 1) = (60 - Cos(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) - 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2)) * 15 + 120
Psets(15, 1) = (Cos(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) - 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(16, 1) = (Cos(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) - 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(1, 2) = (60 - (((1 / T) - 0.2) / 0.08)) * 15 + 120
Psets(2, 2) = (60 - ((T - 0.2) / 0.08)) * 15 + 120
Psets(3, 2) = ((((1 / T) - 0.2) / 0.08) + 60) * 15 + 120
Psets(4, 2) = (((T - 0.2) / 0.08) + 60) * 15 + 120
Psets(5, 2) = (60 - ((T - 0.2) / 0.08)) * 15 + 120
Psets(6, 2) = (60 - (((1 / T) - 0.2) / 0.08)) * 15 + 120
Psets(7, 2) = ((((1 / T) - 0.2) / 0.08) + 60) * 15 + 120
Psets(8, 2) = (((T - 0.2) / 0.08) + 60) * 15 + 120
Psets(9, 2) = (60 - Sin(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) + 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2)) * 15 + 120
Psets(10, 2) = (60 - Sin(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) + 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2)) * 15 + 120
Psets(11, 2) = (Sin(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) + 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(12, 2) = (Sin(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) + 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(13, 2) = (60 - Sin(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) - 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2)) * 15 + 120
Psets(14, 2) = (60 - Sin(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) - 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2)) * 15 + 120
Psets(15, 2) = (Sin(Atn((((1 / T) - 0.2) / 0.08) / ((T - 0.2) / 0.08)) - 0.785398163397448) * Sqr(((T - 0.2) / 0.08) ^ 2 + (((1 / T) - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
Psets(16, 2) = (Sin(Atn(((T - 0.2) / 0.08) / (((1 / T) - 0.2) / 0.08)) - 0.785398163397448) * Sqr((((1 / T) - 0.2) / 0.08) ^ 2 + ((T - 0.2) / 0.08) ^ 2) + 60) * 15 + 120
For i = 1 To 16
If Angle <> 0 Then
Psets(i, 1) = Povernuti(1020, 1020, Psets(i, 1), Psets(i, 2), Angle / 57.2957795130823).x
Psets(i, 2) = Povernuti(1020, 1020, Psets(i, 1), Psets(i, 2), Angle / 57.2957795130823).y
End If
pic.PSet (Psets(i, 1), Psets(i, 2)), vbRed
Next i
Next T
DoEvents
End Sub

Function Povernuti(DotInX As Single, DotInY As Single, DotOutX As Single, DotOutY As Single, Ugol As Single) As CoordVozvrat
Dim x0 As Single, y0 As Single, x As Single, y As Single, x1 As Single, y1 As Single
x0 = DotInX
y0 = DotInY
x = DotOutX
y = DotOutY
x1 = x0 + ((x - x0) * Cos(Ugol)) - ((y - y0) * Sin(Ugol))
y1 = y0 + ((x - x0) * Sin(Ugol)) + ((y - y0) * Cos(Ugol))
Povernuti.x = x1
Povernuti.y = y1
End Function

Но дело всё в том, что мне нужно, чтоб она крутилась по-обычному, по часовой стрелке, относительно своего центра симметрии, без изменения формы, а не так, как она - в трёхмерном пространстве... :lol: Что-то не то в процедуре поворота точки относительно другой точки (Povernuti), хотя формулу, которая в ней используется можно легко вывести, зная математику. Процедура не переводит экранные координаты точки в школьные декартовские, но если их перевести, получится ещё хуже... Что только я вней не изменял, по-всякому делал - ничего не получается...
Последний раз редактировалось Александр Дмитриев 28.08.2005 (Вс) 18:15, всего редактировалось 2 раз(а).

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 28.08.2005 (Вс) 4:09

Ты знаешь, а так гораздо красивее :)
Может оставить?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

newonline
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 115
Зарегистрирован: 13.08.2005 (Сб) 14:50
Откуда: Воронеж

Сообщение newonline » 28.08.2005 (Вс) 7:50

Мне нравица. Я бы оставил... :wink:
Оно конечно да, ежели что как...а то ведь как получится, так вот вам и пожалуйста...

Faust
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 649
Зарегистрирован: 29.12.2003 (Пн) 13:38
Откуда: лаборатория

Сообщение Faust » 28.08.2005 (Вс) 10:32

ИМХО, вся проблема из-за того, что у тебя в процедуре DrawStar() функция Povernuti() вызывается два раза:
Код: Выделить всё
Psets(i, 1) = Povernuti(1020, 1020, Psets(i, 1), Psets(i, 2), Angle / 57.2957795130823).x 'Первый раз. Берется значение .x
Psets(i, 2) = Povernuti(1020, 1020, Psets(i, 1), Psets(i, 2), Angle / 57.2957795130823).y 'Второй раз. Берется значение .y

Я бы либо возращаемое функцией значение присваивал некой временной переменной типа CoordVozvrat, либо избавился бы от вызова функции (ты же её всегда из одного и того же места в коде вызываешь?).
Листинги не горят!

Faust
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 649
Зарегистрирован: 29.12.2003 (Пн) 13:38
Откуда: лаборатория

Сообщение Faust » 28.08.2005 (Вс) 11:05

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

Const pina5 As Double = 0.6283185307179586476925286766559
Private Type Vec2
   x As Single
   y As Single
End Type

Dim working As Boolean

Private Sub Form_Load()
Dim res(0 to 9) As Vec2
Dim i As Byte, j As Byte, ra As Double, rb As Double, t As Single, f As Double
'ra и rb - радиусы вписанной и описанной около звезды окружности
ra=100*cos(2*pina5)
rb=100*cos(pina5)
working=True
While working
   DoEvents
   t=timer
   j=0
   f=0
   For i=0 to 4
      res(j).x = 100+ra*cos(t/4+f)
      res(j).y = 100+ra*sin(t/4+f)
      j=j+1
      f=f+pina5
      res(j).x = 100+rb*cos(t/4+f)
      res(j).y = 100+rb*sin(t/4+f)
      j=j+1
      f=f+pina5
   Next i
   For i=0 to 8
      Me.Line (res(i).x,res(i).y)-(res(i+1).x,res(i+1).y)
   Next i
   Me.Line (res(9).x,res(9).y)-(res(0).x,res(0).y)
Wend
End Sub

Private Sub Form_Click()
   working=False
End Sub

Не проверял (студии на том компе, откуда я пишу, нет), но вроде бы должно работать.
Листинги не горят!

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 28.08.2005 (Вс) 13:18

Faust писал(а):ИМХО, вся проблема из-за того, что у тебя в процедуре DrawStar() функция Povernuti() вызывается два раза:

Подтверждаю. Вот простой фикс:
Код: Выделить всё
For i = 1 To 16
Dim pt As CoordVozvrat
If Angle <> 0 Then pt = Povernuti(1020, 1020, Psets(i, 1), Psets(i, 2), Angle / 57.2957795130823)
pic.PSet (pt.x, pt.y), vbRed
Next i
Изображение

Александр Дмитриев
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 296
Зарегистрирован: 05.01.2005 (Ср) 3:39
Откуда: Санкт-Петербург    Куда: /dev/null

Сообщение Александр Дмитриев » 28.08.2005 (Вс) 15:29

Огромное спасибо! Всё теперь работает :D . Действительно всё было из-за того, что процедура вызывается два раза.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 64

    TopList  
cron