forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Кротчайшее направление плавного разворота! (http://forum.boolean.name/showthread.php?t=8212)

ELIAS 25.04.2009 14:14

Кротчайшее направление плавного разворота!
 
Опять похожая проблема.
В этот раз просто необходимо поворачивать плано объект в то же направление куда повернут другой объект-пивот. В примере для удобства я взял только поворот по оси игрек.

Вот код:
Код:

Graphics3D 1280, 1024, 32, 1

cam=CreateCamera()
CameraClsColor cam, 0, 100,255
CameraRange cam, 1, 1000
MoveEntity cam,0,0,-50
lit=CreateLight()
PositionEntity cam, 2, 10,-2



cube=CreateWCone()
EntityColor cube, 255,0,0

PointEntity cam, cube


pivot=CreateWCone()
PositionEntity pivot, 5,0,0
RotateEntity pivot, 0, Rand(0,360), 0


Repeat
       
       
        If Abs(EntityYaw(cube)-EntityYaw(pivot))<2
                RotateEntity pivot, 0, Rand(0,360), 0
        EndIf
       
       
       
        SmoothTurn4(cube, pivot, 0.01)
       
        If KeyDown(200)=1 Then MoveEntity cam, 0,0,0.5
        If KeyDown(208)=1 Then MoveEntity cam, 0,0,-0.5
       
        RotateEntity cam, EntityPitch(cam)+MouseYSpeed()*0.2, EntityYaw(cam)-MouseXSpeed()*0.2 ,0
       
        MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
       
       
       
       
        UpdateWorld
    RenderWorld
       
       
    Flip 60
       
       
       
Until KeyHit(1)
End

Function CreateWCone()
        f=CreateCone(4)
        RotateMesh f,0,0,90
        ScaleMesh f, 1,2,2
        RotateMesh f, 45,90,0
        ScaleMesh f,1.2,1,1
        Return f
End Function

Function SmoothTurn4#(ent1,ent2,speed# = 1)
       
        smx#=(EntityPitch(ent2)-EntityPitch(ent1))*speed
        smy#=(EntityYaw(ent2)-EntityYaw(ent1))*speed
        smz#=(EntityRoll(ent2)-EntityRoll(ent1))*speed
        TurnEntity ent1, smx, smy, smz
       
End Function

Если внимательно приглядыватьтся то совсем несложно увидеть то что красный объект вовсе не всегда поворачивается так как это обычно происходит в жизни. Вместо того чтобы повернуться на -90 градусов, он к примеру повернйтся на 270, и наоборот. Вот именно этот недостаток необходимо устранить.
Я сам никак не могу додуматься как это возможно. Жду вашей помощи! :)
Спасибо! :)

Main Cry 25.04.2009 14:36

Ответ: Кротчайшее направление плавного разворота!
 
Внутри блока
Код:

        If Abs(EntityYaw(cube)-EntityYaw(pivot))<2
                RotateEntity pivot, 0, Rand(0,360), 0
        EndIf

поменяй Rand(0,360) на Rand(-180,180)

ELIAS 25.04.2009 16:59

Ответ: Кротчайшее направление плавного разворота!
 
Цитата:

поменяй Rand(0,360) на Rand(-180,180)
Мм.Может я не прав, но тут разницы то никакой, при снятии yaw`ов получатся такиеже значения, блитц все подстраивает под себя в любом случае и преобразует любой угол поворота в промежуток [-180;180).
Но я попробовал - ничего не изменилось:)
Тут полюбому надо что-то с функцией делать. причем что-то хитрое.
Жду ещё ответов.
Спасибо Main Cry

HolyDel 25.04.2009 18:36

Ответ: Кротчайшее направление плавного разворота!
 
под -180..180 систему.

Код:

float AngleDist(float a1,float a2)
{
        if(a1-a2>180.0f)
                return  360.0f - (a1-a2);
       
        if(a1-a2<-180.0f)
                return 360.0f + (a1-a2);

        return a1-a2;
}

float AngleLerp(float a1,float a2,float scalar)
{
        return a1+AngleDist(a2,a1)*scalar;
}


ELIAS 25.04.2009 19:33

Ответ: Кротчайшее направление плавного разворота!
 
HolyDel, на блитце эти функции будут выглядеть так?
Код:

Function AngleDist#(a1#,a2#)
        If a1-a2>180 Then Return  360 - (a1-a2)
       
        If a1-a2<-180 Then Return 360 + (a1-a2)
End Function
               
               
               
Function AngleLerp#(a1#,a2#,scalar#)
        Return a1+AngleDist(a2,a1)*scalar
End Function

И в этом случае в моём коде вместо
Код:

SmoothTurn4(cube, pivot, 0.01)
пишем
Код:

RotateEntity cube, 0,  AngleLerp(EntityYaw(cube), EntityYaw(pivot), 0.01),0
Сделал. Фигурка вообще не вращается!!!!!! %(

HolyDel 25.04.2009 21:01

Ответ: Кротчайшее направление плавного разворота!
 
я хз. вот пример:
http://sigelengine.googlecode.com/fi...leLerpTest.zip

правда на с++, но там не сложно. математика то одна для всех.

ELIAS 25.04.2009 21:23

Ответ: Кротчайшее направление плавного разворота!
 
Посмотрел, есть что-то общее конечно с моей проблемой, но уж совсем другое дело...Но имхо это не решит мою проблему - слишком сильно отличаются задачи:(((

HolyDel 25.04.2009 21:53

Ответ: Кротчайшее направление плавного разворота!
 
а.. ну ты используй AngleDist.
если меньше нуля - крути в одну сторону.
если больше - в другую.

ELIAS 25.04.2009 22:01

Ответ: Кротчайшее направление плавного разворота!
 
Код:

Graphics3D 640, 480, 32, 1

cam=CreateCamera()
CameraClsColor cam, 0, 100,255
CameraRange cam, 1, 1000
MoveEntity cam,0,0,-50
lit=CreateLight()
PositionEntity cam, 2, 10,-2



cube=CreateWCone()
EntityColor cube, 255,0,0

PointEntity cam, cube


pivot=CreateWCone()
PositionEntity pivot, 5,0,0
RotateEntity pivot, 0, Rand(0,360), 0

o1=0

Repeat
       
       
        If Abs(EntityYaw(cube)-EntityYaw(pivot))<1
                o1=EntityYaw(cube)
                RotateEntity pivot,0,  Rand(-180,180),0
        EndIf
       
       
       
        ;SmoothTurn4(cube, pivot, 0.01)
        gh#=AngleLerp(EntityYaw(cube), EntityYaw(pivot), 1)
        RotateEntity cube, 0,  AngleLerp(EntityYaw(cube), EntityYaw(pivot), 0.04),0
       
        If KeyDown(200)=1 Then MoveEntity cam, 0,0,0.5
        If KeyDown(208)=1 Then MoveEntity cam, 0,0,-0.5
       
        RotateEntity cam, EntityPitch(cam)+MouseYSpeed()*0.2, EntityYaw(cam)-MouseXSpeed()*0.2 ,0
       
        MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
       
       
       
       
        UpdateWorld
    RenderWorld
       
       
        Text 20,20, "povorot = " + (EntityYaw(cube)-o1)
       
    Flip 60
       
       
       
       
Until KeyHit(1)
End

Function AngleDist#(a1#,a2#)
        If a1-a2>180 Then Return  360 - (a1-a2)
       
        If a1-a2<-180 Then Return 360 + (a1-a2)
       
        If a1-a2>-180 And a1-a2<180 Then Return a1-a2
End Function

               
               
               
Function AngleLerp#(a1#,a2#,scalar#)
        Return a1+AngleDist(a2,a1)*scalar
End Function


Function CreateWCone()
        f=CreateCone(4)
        RotateMesh f,0,0,90
        ScaleMesh f, 1,2,2
        RotateMesh f, 45,90,0
        ScaleMesh f,1.2,1,1
        Return f
End Function

Function SmoothTurn4#(ent1,ent2,speed# = 1)
       
        smx#=(EntityPitch(ent2)-EntityPitch(ent1))*speed
        smy#=(EntityYaw(ent2)-EntityYaw(ent1))*speed
        smz#=(EntityRoll(ent2)-EntityRoll(ent1))*speed
        TurnEntity ent1, smx, smy, smz
       
End Function

Вот HolyDel, пока только это есть. Тут какбы используются твои алгоритмы. Результатов не дают.....:(((((

moka 26.04.2009 10:58

Ответ: Кротчайшее направление плавного разворота!
 
Вот функция, плавно смешивает два угла, с учётом цикличности.
Код:

Function MergeAngles#(Angle1#,Angle2#,Morph#=.5)
  If Abs(Angle1-Angle2)>180
      If Angle1<Angle2
        Return Angle1-((360-Angle2)+Angle1)*(.5-(Morph-.5))
      Else
        Return Angle2-((360-Angle1)+Angle2)*(.5+(Morph-.5))
      EndIf
  Else
      Return Angle1*(Morph)+Angle2*(1.0-Morph)
  EndIf
End Function

Плавность не постоянная, и чем выше разница углов, тем выше скорость смещения к новому данному. Можно сделать и постоянную, либо любую другую модель смазывания, главное суть функции.

ELIAS 26.04.2009 13:49

Ответ: Кротчайшее направление плавного разворота!
 
Огромное Спасибо, MoKa!!! Теперь всё окей, насчет непостоянности плавности - как раз такая мне и нужна, чтобы под конец затухала.


Часовой пояс GMT +4, время: 17:55.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot