Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Вот решил поделится открытием :)


Автор: cardinal 29.4.2004, 23:10
Блин... Пишу это сообщение второй раз потому, что мой компер ёкнулся sad.gif...

Вот решил поделится: до меня наконец-то доперло как повернуть объект вокруг "наклонённой оси". Как поворачивать объекты вокруг x, y и z осей я давно уже научился, а вот как поворачивать объект вокруг "наклонённой оси" я чего-то понять не мог. А тут понял. Как всегда все прочто, когда знаешь как smile.gif. Надо просто повернуть объект на угол i вокруг оси y (i меняется в цикле), ну а потом поворачивать вокруг осей x и y, например, на определенный угол. Получается как бы вращение вокруг "наклоненной оси" smile.gif.

У меня была уже давно нарисована сфера средствами VB (и немного математики smile.gif). Нарисована она из точек. Когда она вращается, то видно, что это не 2D, а 3D объект. Вот вам screenshot. Можете поделится своими мнениями smile.gif

Автор: Georg4 29.4.2004, 23:55
нУ и откровения блин посещаютsmile.gif
Это ты на чем делал?
Я на делфи это делал и очень долго думал что вращается объект, окатывается вункция вращает не объект а камеруsmile.gif

Автор: cardinal 30.4.2004, 00:39
Цитата
нУ и откровения блин посещают

да бывает у меня... biggrin.gif
Цитата
Это ты на чем делал?

Все сделано чисто на VB. Никаких камер и всяких там DirectX, OpenGL'ов. Все функции написал сам. Правда прикольно? smile.gif

Автор: foRaver 30.4.2004, 03:03
А можешь поделиться примерами кода в учебных целяx, если это конечно не затрудняет, пожалуйста ?

Автор: Secandr 30.4.2004, 09:07
шиза, я помнится на паскале такие трёхмерные объекты рисовал, правда до анимации дело не доходило smile.gif

Автор: cardinal 30.4.2004, 11:24
Secandr, рисовать - это одно, а вот анимация - это даааа... smile.gif
Цитата
А можешь поделиться примерами кода в учебных целяx, если это конечно не затрудняет, пожалуйста ?

Конечно могу, только вот кину я это прямо сюда, т.к. так как все там понаписано показывать кому стыдно smile.gif. Мне главное было добиться результата, а вылизыванием кода и оптимизацией я пока не занимался.

Автор: cardinal 30.4.2004, 11:50
Ввел понятия точка
Код
Public Type Point3D     ' 3D Point
   X As Single
   Y As Single
   Z As Single
End Type

и объект
Код
Public Type Object3D        ' 3D car Object
   pointCol() As Point3D   ' points of the object
   ObjCol() As PObject3D   ' other Objects
   objectsq As Integer ' quantity of PObjects
   pointsq As Integer  ' quantity of points
   enlarge As Single   ' enlarge factor
   center As Point3D   ' center point
End Type

Открыл справочник по математике Корна и написал процедуру, которая мне create'ует сфера из точек.
Код
Public Function CreatePointSphere(Radius As Single, _
                                 center As Point3D _
                                 ) As Object3D
Dim j As Integer            ' counter
Dim k As Integer            ' counter
Dim oldcenter As Point3D    ' copy of the center point
Dim point As Point3D        ' current point
Dim pnum As Integer         ' number of the point
Dim sphere As Object3D      ' new object

' we do not need enlarge factor for this object

' first point is above the center
point.X = center.X
point.Y = center.Y + Radius
point.Z = center.Z + Radius

oldcenter = center      ' copy of center
sphere.pointsq = 683    ' number of points
ReDim sphere.pointCol(sphere.pointsq)
For j = 10 To 190 Step 10
   point = RotateZ(point, center, 10)
   center.Y = point.Y
   For k = 0 To 350 Step 10
       sphere.pointCol(pnum) = point
       pnum = pnum + 1
       point = RotateY(point, center, 10)
   Next
   center.Y = oldcenter.Y
Next
       
'sphere.enlarge =1
sphere.center = oldcenter   ' set the center point
CreatePointSphere = sphere    ' return an object
End Function

Написал процедуры для вращения точек! на такой-то угол по отношению к такой-то оси, координаты которой нам дает точка center.
Код
'**************************************************************************'
'                                                                          '
'                      DIFFERENT ROTATION FUNCTIONS                        '
'                                                                          '
'**************************************************************************'

'**************************************************************************'
' simple rotation around X axis

Public Function RotateX(point As Point3D, _
                       center As Point3D, _
                       Angle As Double _
                       ) As Point3D
Dim newpoint As Point3D

Angle = Angle * PI / 180
point.X = point.X - center.X
point.Y = point.Y - center.Y
point.Z = point.Z - center.Z

newpoint.Y = point.Y * Cos(Angle) - point.Z * Sin(Angle)
newpoint.Z = point.Y * Sin(Angle) + point.Z * Cos(Angle)

newpoint.X = newpoint.X + center.X
newpoint.Y = newpoint.Y + center.Y
newpoint.Z = newpoint.Z + center.Z
RotateX = newpoint
End Function

'**************************************************************************'
' simple rotation around Y axis

Public Function RotateY(point As Point3D, _
                       center As Point3D, _
                       Angle As Double _
                       ) As Point3D
Dim newpoint As Point3D
Angle = Angle * PI / 180
point.X = point.X - center.X
point.Y = point.Y - center.Y
point.Z = point.Z - center.Z

newpoint.X = point.X * Cos(Angle) + point.Z * Sin(Angle)
newpoint.Z = point.Z * Cos(Angle) - point.X * Sin(Angle)

newpoint.X = newpoint.X + center.X
newpoint.Y = newpoint.Y + center.Y
newpoint.Z = newpoint.Z + center.Z
RotateY = newpoint
End Function

'**************************************************************************'
' simple rotation around Z axis

Public Function RotateZ(point As Point3D, _
                       center As Point3D, _
                       Angle As Double _
                       ) As Point3D
Dim newpoint As Point3D
Angle = Angle * PI / 180
point.X = point.X - center.X
point.Y = point.Y - center.Y
point.Z = point.Z - center.Z

newpoint.X = point.X * Cos(Angle) - point.Y * Sin(Angle)
newpoint.Y = point.X * Sin(Angle) + point.Y * Cos(Angle)

newpoint.X = newpoint.X + center.X
newpoint.Y = newpoint.Y + center.Y
newpoint.Z = newpoint.Z + center.Z
RotateZ = newpoint
End Function

Потом есть процедура вращения всех точек объекта вокруг такой-то оси.
Код
'**************************************************************************'
' simple rotation around one axis

Public Function RotateObject(object As Object3D, _
                            angleX As Double, _
                            angleY As Double, _
                            angleZ As Double _
                            ) As Object3D
Dim newcenter As Point3D
Dim i As Integer
newcenter = object.center

' rotate around X axis
If (angleX) Then
   For i = 0 To object.pointsq
       newcenter.X = object.pointCol(i).X
       object.pointCol(i) = RotateX(object.pointCol(i), newcenter, angleX * 1)
       DoEvents
   Next
End If

' rotate around Y axis
If (angleY) Then
   For i = 0 To object.pointsq
      newcenter.Y = object.pointCol(i).Y
      object.pointCol(i) = RotateY(object.pointCol(i), newcenter, angleY * 1)
      DoEvents
   Next
End If

' rotate around Z axis
If (angleZ) Then
   For i = 0 To object.pointsq
       newcenter.Z = object.pointCol(i).Z
       object.pointCol(i) = RotateZ(object.pointCol(i), newcenter, angleZ * 1)
       DoEvents
   Next
End If

RotateObject = object

End Function

Вот так выглядит потом обработка нажатия Command1:
Код
Private Sub Command1_Click()
Dim center As Point3D
Dim i As Double
Dim sphere2 As Object3D
Dim sphere3 As Object3D

Line (5928, 3500)-(9348, 8688), RGB(0, 0, 255)

DrawWidth = 5   ' Set DrawWidth.
Form1.PSet (6732, 4692), RGB(0, 255, 0)
Form1.PSet (8604, 7572), RGB(0, 255, 0)
DrawWidth = 1   ' Set DrawWidth.

center.X = Screen.Width / 2
center.Y = Screen.Height / 2
center.Z = 2500

sphere = CreatePointSphere(2140, center)
sphere2 = sphere
sphere3 = sphere

Do While True
   For i = 0 To 89 Step 1
       sphere3 = sphere
       sphere = sphere2
       RotateObject3D sphere, 0, i, 0
       RotateObject3D sphere, -47, 0, 0
       RotateObject3D sphere, 0, -37, 0
       DrawObject3D sphere
       DeleteObject3D sphere3
       Sleep 50
   Next
Loop
End Sub

Использовались также процедуры:
Код
Public Function DrawObject3D(object As Object3D)
Dim j As Integer

For j = 0 To object.pointsq
   DrawPoint object.pointCol(j), 2
Next

End Function

Код
Public Function DeleteObject3D(object As Object3D)
Dim j As Integer
For j = 0 To object.pointsq
   DrawPoint object.pointCol(j), Form1.BackColor
Next
End Function

Код
Public Function DrawPoint(point As Point3D, color As Long)
Form1.PSet (point.X, point.Y), color
End Function

Может чего-то я и забыл.

Вобщем как уже сказал тут еще до фига всего над чем можно поработать, но так принцип понятен.
Весь проект пока не хочу делать public потому, что "идет стройка". Может когда нибудь сделаю короткий проект и засуну его в FAQ, но пока такого не намечается.

Автор: maxim1000 30.4.2004, 12:54
насколько я понял, тут происходит сначала поворот на нужный угол, а потом - "установка" объекта вдоль прямой
а если нужно просто повернуть объект вокруг прямой, что нужно сначала поворачивать его так, чтобы установить на ось, потом вращать, а потом поворачивать назад?
если да, то есть алгоритм проще, если чего-то недопонял - звиняйте...

Автор: cardinal 30.4.2004, 13:26
Цитата
а если нужно просто повернуть объект вокруг прямой, что нужно сначала поворачивать его так, чтобы установить на ось, потом вращать, а потом поворачивать назад?

это в смысле если объект повернут? и нам надо его крутить вокруг определенной линии? если так, то получается как раз то что ты сказал. А сейчас у меня происходит след.
Цитата
Надо просто повернуть объект на угол i вокруг оси y (i меняется в цикле), ну а потом поворачивать вокруг осей x и y, например, на определенный угол. Получается как бы вращение вокруг "наклоненной оси" .

как уже говорил.

Автор: GoodBoy 30.4.2004, 14:06
А у нас в универе по компьютерной графике лаба была - вращается трехмерный куб, а в некоторой точке экрана источник света. И куб, кроме того, что произвольно вращается еще и освещается по законам физики, в зависимости от угла падения света на его грань - ярче или тусклее...
Да, и писали это на Паскале, безо всяких Опенов и Директов... :-))))))))))))))))))

З.Ы. А вам слабо? :-))))))))))))))))))))))))))))))

Автор: cardinal 30.4.2004, 14:14
Конечно же не слабо smile.gif, только вот проектом на VB я решил занятся. Сейчас будет побольше свободного времени и я буду над ним работать. Кому интересно смотрите здесь:
http://forum.vingrad.ru/index.php?showforum=61

Автор: maxim1000 30.4.2004, 15:22
Цитата
это в смысле если объект повернут? и нам надо его крутить вокруг определенной линии? если так, то получается как раз то что ты сказал. А сейчас у меня происходит след.

тогда можно предложить что-нибудь вроде такого:
есть прямая a, точка A, нужно повернуть точку A на угол alpha вокруг прямой a
1. находим точку B - проекция A на прямую
2. берем вектор x=BA (его мы и будем поворачивать)
3. берем вектор y, перпендикулярный x и a (например, с помощью векторного произведения) и умножаем на такую константу, чтобы по длине он был как x
4. делаем новый вектор z=x*cos(alpha)+y*sin(alpha) - это и есть нужный вектор BC, где C - искомая точка

насчет реализации:
пусть прямая задана одной из своих точек (O) и нормированным направляющим вектором ®
[*,*] - векторное произведение
x=[r , A-O]
B=A-x
y=[r , x]
z=x*cos(alpha)+y*sin(alpha)
C=B+z

Автор: cardinal 30.4.2004, 15:30
хмм... интересно. Надо будет подумать, но не сейчас smile.gif

Автор: javastic 6.10.2005, 10:03
Цитата(cardinal @ 29.4.2004, 23:10)
Блин... Пишу это сообщение второй раз потому, что мой компер ёкнулся smile...

Вот решил поделится: до меня наконец-то доперло как повернуть объект вокруг "наклонённой оси". Как поворачивать объекты вокруг x, y и z осей я давно уже научился, а вот как поворачивать объект вокруг "наклонённой оси" я чего-то понять не мог. А тут понял. Как всегда все прочто, когда знаешь как smile. Надо просто повернуть объект на угол i вокруг оси y (i меняется в цикле), ну а потом поворачивать вокруг осей x и y, например, на определенный угол. Получается как бы вращение вокруг "наклоненной оси" smile.

У меня была уже давно нарисована сфера средствами VB (и немного математики smile). Нарисована она из точек. Когда она вращается, то видно, что это не 2D, а 3D объект. Вот вам screenshot. Можете поделится своими мнениями smile

Круто! Молодец. Люблю людей которые добиваются всего сами.
smile

Автор: cardinal 6.10.2005, 12:23
Да, было дело... smile

И как народ на такие старые темы натыкается только? smile

Автор: takedo 14.10.2005, 14:08
cardinal Я чего-то не понял, если ты вращаешь свободно вокруг оси x,y,z чем тебе прямая то не ось? Взял да повернул координаты, визуализировал в новой СК и обратно(что-то типа того). Я и вдаваться то толком не хочу в эту тему - яйца она выыыеденнооого не стоит! smile Такие вещи все-таки удобнее делать с помощью Якобианов преобразования. Почитай тензорный анализ, все будет тебе ясно и понятно, только в Корне не читай - там для слишком умных, мне не все понятно. Лучшая книга справочник по математике Бронштейн, Семендяев. А по тензорному не могу сказать, забыл я про авторов и книгами этими уже не пользуюсь, сорри. smile

Автор: cardinal 14.10.2005, 19:31
Цитата(takedo @ 14.10.2005, 12:08)
Я и вдаваться то толком не хочу в эту тему - яйца она выыыеденнооого не стоит!

Чего, чего, а его она стоит!
Цитата(takedo @ 14.10.2005, 12:08)
Такие вещи все-таки удобнее делать с помощью Якобианов преобразования. Почитай тензорный анализ, все будет тебе ясно и понятно

Может быть. Тензорным анализом, когда я это намудрил еще и не пахло, а теперь меня больше интересуют проблемы глобального коммунизма! smile
Цитата(takedo @ 14.10.2005, 12:08)
Лучшая книга справочник по математике Бронштейн, Семендяев.

И она имеется... smile

Автор: takedo 17.10.2005, 06:21
cardinal
так я смотрю, для глобализации коммунизма у тебя все есть и яйца smile на проблему и справочники нужные smile

Автор: Elfet 5.6.2007, 12:55
Код

        public void Spin(Vector axis, double angle, Vector basePoint)
        {
            // двигаем в начало координат
            Move(-basePoint);
            // матрица вращения вокруг произвольной оси
            MyMatrix spinMatrix = new MyMatrix(
                new float[3, 3]
                {
                    {
                        (float)(Math.Cos(angle) + (1 - Math.Cos(angle)) * axis.X * axis.X),
                        (float)((1 - Math.Cos(angle)) * axis.X * axis.Y - Math.Sin(angle) * axis.Z),
                        (float)((1 - Math.Cos(angle)) * axis.X * axis.Z + Math.Sin(angle) * axis.Y) 
                    },
                    {
                        (float)((1 - Math.Cos(angle)) * axis.Y * axis.X + Math.Sin(angle) * axis.Z),
                        (float)(Math.Cos(angle) + (1 - Math.Cos(angle)) * axis.Y * axis.Y),
                        (float)((1 - Math.Cos(angle)) * axis.Y * axis.Z - Math.Sin(angle) * axis.X)                         
                    },
                    {
                        (float)((1 - Math.Cos(angle)) * axis.Z * axis.X - Math.Sin(angle) * axis.Y),  
                        (float)((1 - Math.Cos(angle)) * axis.Z * axis.Y + Math.Sin(angle) * axis.X),                                        
                        (float)(Math.Cos(angle) + (1 - Math.Cos(angle)) * axis.Z * axis.Z)
                    }
                }
                );
            // применяем матрицу
            for (int i = 0; i < points.Length; i++)
            {
                points[i] = new Vector(MyMatrix.MatrixMultiplication(points[i], spinMatrix));
            }
            // двигаем в исходное положение
            Move(basePoint);
        }

Автор: cardinal 5.6.2007, 21:16
Elfet, хехе, тема старовата... smile

Ну может кому и интересно будет это встроить.

Автор: Elfet 5.6.2007, 21:27
Ну, да нужно в faq или куда там постнуть smile

Автор: cardinal 19.2.2010, 01:07
Подниму как я тему, которой почти три года... smile Гляди кому интересно будет.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)