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=16233)

CRASHER 25.01.2012 22:17

Плавное движение по точкам.
 
Дан ряд точек. Как бы так двигаться по ним, плавно меняя направления, когда актуальная точка достигнута. Траектория движение напоминает кривую. Нужно сделать попроще. Какие предложения?

dsd 25.01.2012 22:49

Ответ: Плавное движение по точкам.
 
Всякие там эволюты эвольвенты, диффуры да интегралы, если верить справочнику.

Короче голову как у коня размером иметь надо. Но пусть по ломанной траектории двигается некая виртуальная точка к которой стремится твой объект, чем дальше цель тем охотней объект движется прям на точку, чем ближе тем он ленивей реагирует вплоть до нуля при совпадении координат. Если все-равно криво, то пусть объект обладает массой и скоростью, а расстояние до цели говорит о направлении ускорения и его величине.

CRASHER 25.01.2012 22:54

Ответ: Плавное движение по точкам.
 
dsd, вроде бы по делу, но это как это примерно выглядит?)) У меня движение без поворота по векторам образованным при помощи Cos и Sin угла посчитанного Atan2. К этому можно что то добавить чтобы был нужный результат? Инерцию как нибудь замутить?

dsd 25.01.2012 23:01

Ответ: Плавное движение по точкам.
 
Хоспаде. Точку ты двигать по своей ломанной линии можешь.
xEntityX,Y,Z дадут тебе место твоего шара, координаты точки на кривой найти ты наверно тоже можешь. Теперь магия.
Считаешь вектор от объекта до точки, нормализуешь его. Считаешь расстояние между точкой и объектом.

заводишь три глобальные переменные vx,vy,vz.

vx=vx+ax*distance; ........
ax это координаты нормализованного вектора. Способа еще проще я не знаю. ах да xMoveEntity object,vx,vy,vz/

Hurrit 25.01.2012 23:21

Ответ: Плавное движение по точкам.
 
я юзал кривую безье, суть такова: в 3д максе выставляешь точки, получаешь координаты этих точек и через них строишь кривую безье. в свое время юзал данную статью

CRASHER 26.01.2012 00:03

Ответ: Плавное движение по точкам.
 
dsd, пджиии. а он точно будет плавно менять цель перемещения, а не просто замедлятся при приближении к цели?

Hurrit, Благодарствую, повникаю в это дело!))

dsd 26.01.2012 00:20

Ответ: Плавное движение по точкам.
 
Да. Точно будет. Клянусь физикой за седьмой класс.

CRASHER 26.01.2012 00:27

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

dsd 26.01.2012 01:56

Ответ: Плавное движение по точкам.
 
Умножай все ускорения на 0.9 это будет гасить колебания.

HolyDel 26.01.2012 02:25

Ответ: Плавное движение по точкам.
 
Цитата:

Умножай все ускорения на 0.9
да не, понятно же, что в коде косяк

CRASHER 26.01.2012 02:40

Ответ: Плавное движение по точкам.
 
Скажите пжааалст, где же этот самый косяк (((

Код:

       
dist#=xEntityDistance(Cup_1,point[n])
        If dist<2
                n=n+1
                If n>2 n=0
        EndIf
       
        nen=n+1
        If nen>2 nen=0

        speed#=0.002
       
        xcmp#=(xEntityX(point[n])-xEntityX(Cup_1))
        ycmp#=(xEntityY(point[n])-xEntityY(Cup_1))
        zcmp#=(xEntityZ(point[n])-xEntityZ(Cup_1))
       
        lenght#=Sqr(Ext(xcmp)+Ext(ycmp)+Ext(zcmp))
       
        xcmp=(xcmp/lenght)
        ycmp=(ycmp/lenght)
        zcmp=(zcmp/lenght)
       
        valz=valz+zcmp*lenght*speed
        valx=valx+xcmp*lenght*speed
        valy=valy+ycmp*lenght*speed
       
        xMoveEntity(Cup_1,valx,valy,valz)


dsd 26.01.2012 02:40

Ответ: Плавное движение по точкам.
 
Та не, раз у него по элипсу вокруг точки движется значит относительно правильно, а 0.9 имитирует силу трения, которая и должна сожрать вредную энергию. А если поставить больше единицы то объект будет раскачиваться вокруг положения своего центра гравитации все сильней :-) Если добавить более менее сложную зависимость изменения гравитации можно прикольных эффектов добиться, ну там для логотипа или заставки во время загрузки :-)
Попрбуй умножать только скорость на коэффциент этакого трения наоборот. Эт я с ускорением затупил просто.

valz=0.99*valz+zcmp*lenght*speed valy=0.99*valy+ycmp*lenght*speed

CRASHER 26.01.2012 02:43

dsd, да честно признаться на некоторое время я на косяк забил и стал играться, менять свойства, прикольные колебания получаются.)))

dsd, млин, чот теперь плавно но прямолинейно, гравитация пропала, если отдельно на ускорение тоже делать коэфициент, меняет только скорость перемещения.

LLI.T.A.L.K.E.R. 26.01.2012 03:09

Ответ: Плавное движение по точкам.
 
;Project : WayPointSystem
;Version : 0.01
;Author : H@non ©

Цитата:

В примере кубик следует по расставленным точкам в пространстве.

Описание функций
AddVayPoint - добавление точки, до которой будет перемещаться ентити.
x#, y#, z# - координаты
radius#=1.0 - радиус точки, то есть как близко должен ентити подлететь к точке, чтобы ее активировать.
state=ST_FLY - состояние точки, типо что делает ентити. Есть ST_FLY - лететь, ST_STAY - ждать...

AddNextVP(handleVP1, handleVP2) - соединить точки. Служит для составления путей, то есть от какой точки к какой лететь. Также возможно установить несколько точек к которым может лететь ентити, тогда будет выбираться рандомно одна из этих точек. Первый параметр это точка к которой соединяют, а второй точка которую присоединяют.

AddEntityToVP(ent, spTurn#.1, spMove# = 0.1) - добавить ентити, который будет следовать по точкам. Там указываеться сам ентити, скорость его поворота, и скорость перемещения.

SetEntityVP(entVP, handleVP) - установить ентити текущую точку. Здесь мы задаем точку, к которой будет перемещаться ентити

GetEntityState(entVP) - возвращает текущее состояние ентити. Щас пока ентити может либо лететь, либо стоять... хотя если он достиг конечной точки, то его статус будет равен нулю.

UpdateVP() - упдейт системы, помещаем в главный цикл


Код:
PHP код:

;=================================
;
Project WayPointSystem
;Version 0.01
;Author H@non ©
;Contact hanon90@gmail.com
;Visit http://demon-soul.at.ua
;=================================


Type VayPoint
    Field x
#, y#, z#
    
Field radius#
    
Field state%
    
Field cntVPnextVP[10]
    
Field mesh
End Type
Const ST_FLY=1ST_STAY=2

Type EntVP
    Field ent
    Field spTurn
#, spMove#
    
Field curVP
    Field state
    Field timeLeft
End Type

Graphics3D 800
600322
SetBuffer BackBuffer
()
SeedRnd MilliSecs()

Global 
debug True
Global debugMesh CreateCube()
ScaleMesh debugMesh0.30.30.3
EntityColor debugMesh
02550
HideEntity debugMesh

Local vp1 
AddVayPoint(000)
Local vp2n
For 1 To 5
    vp2 
AddVayPoint(n*5Rnd(-50), Rnd(-1515))
    
AddNextVP(vp1vp2)
    
vp1 AddVayPoint((n+0.5)*5Rnd(-50), Rnd(-1515), 0.1Rand(1,2))
    
AddNextVP(vp2vp1)
Next

Local cube 
CreateCube()
EntityColor cube25500
Local ent 
AddEntityToVP(cube)
Local vp.VayPoint First VayPoint
AddNextVP
(vp1Handle(vp))
SetEntityVP(entHandle(vp))

Local lit CreateLight()
RotateEntity lit45450

Local camera 
CreateCamera()
CameraMove(camera0.5)
PositionEntity camera, -330
RotateEntity camera
10, -900

While KeyDown(1)=0
    UpdateVP
()
    
CameraMove(camera0.5)
    
RenderWorld()
    
Text 1010"entity State: "+GetEntityState(ent)
    
Flip 1
Wend
End

Function CameraMove(camsp#=0.1)
    
Local mxs# = MouseXSpeed()*0.5
    
Local mys# = MouseYSpeed()*0.5
    
MoveMouse 400300
    RotateEntity cam
EntityPitch(cam,1)+mysEntityYaw(cam,1)-mxs01
    MoveEntity cam
, (KeyDown(32)-KeyDown(30))*sp0, (KeyDown(17)-KeyDown(31))*sp
End 
Function

Function 
AddVayPoint(x#, y#, z#, radius#=1.0, state=ST_FLY)
    
Local VP.VayPoint = New VayPoint
    VP
\x
    VP
\y
    VP
\z
    VP
\radius# = radius
    
VP\state state
    
If debug True Then
        VP
\mesh CopyEntity(debugMesh)
        
PositionEntity VP\meshxyz
    
EndIf
    
    Return 
Handle(VP)
End Function

Function 
AddNextVP(handleVP1handleVP2)
    
Local VP1.VayPoint Object.VayPoint(handleVP1)
    
    
VP1\nextVP[VP1\cntVP] = handleVP2
    VP1
\cntVP VP1\cntVP 1
End 
Function

Function 
AddEntityToVP(entspTurn#=0.9, spMove# = 0.1)
    
Local e.EntVP = New EntVP
    e
\ent ent
    e
\spTurn spTurn
    e
\spMove spMove
    
    
Return Handle(e)
End Function

Function 
SetEntityVP(entVPhandleVP)
    
Local e.EntVP Object.EntVP(entVP)
    
e\curVP handleVP
    Local VP
.VayPoint Object.VayPoint(e\curVP)
    
e\state VP\state
End 
Function

Function 
GetEntityState(entVP)
    
Local e.EntVP Object.EntVP(entVP)
    ;If 
Null Then RuntimeError"VP entity not found" )
    Return 
e\state
End 
Function

Function 
UpdateVP()
    
Local e.EntVPVP.VayPoint
    Local dx
#, dy#, dz#, pit#, yaw#
    
For e.EntVP Each EntVP
        
If e\state ST_FLY Then
            VP
.VayPoint Object.VayPoint(e\curVP)
            If 
VP <> Null Then
                dx
# = VP\x - EntityX(e\ent,1)
                
dy# = VP\y - EntityY(e\ent,1)
                
dz# = VP\z - EntityZ(e\ent,1)
                
If Abs(dx)<VP\radius And Abs(dy)<VP\radius And Abs(dz)<VP\radius Then
                    Select VP
\state
                        
Case ST_FLY
                            e
\curVP VP\nextVP[Rand(0,VP\cntVP-1)]
                            
e\state VP\state
                            
If e\curVP <= 0 Then e\state 0
                        
Case ST_STAY
                            e
\timeLeft MilliSecs() + Rand(3,15)*1000
                            e
\state VP\state
                            e
\curVP VP\nextVP[Rand(0,VP\cntVP-1)]
                            If 
e\curVP <= 0 Then e\state 0
                    End Select
                
Else
                    
pit# = VectorPitch(dx, dy, dz)
                    
yaw# = VectorYaw(dx, dy, dz)
                    
pit MergeAngles#(EntityPitch(e\ent,1),pit,e\spTurn)
                    
yaw MergeAngles#(EntityYaw(e\ent,1),yaw,e\spTurn)
                    
RotateEntity e\entpityawEntityRoll(e\ent,1)
                    
MoveEntity e\ent00e\spMove
                
EndIf
            Else
                ;
RuntimeError"Vaypoint not found" )
            EndIf
        ElseIf 
e\state ST_STAY Then
            
If MilliSecs() > e\timeLeft Then
                e
\state ST_FLY
            
EndIf
        EndIf
    
Next
End 
Function

;
/////////////////////////////////////////////////////////////
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
;~
IDEal Editor Parameters:
;~
C#Blitz3D 


dsd 26.01.2012 03:11

Ответ: Плавное движение по точкам.
 
значит проверяй угол между векторами скорости объекта и цели и когда угол больше 100 градусов уменьшай скорость, а если вектора смотрят в одну сторону то не уменьшай. Этим ты добьешся сохранение гладкости и отсутствия колебаний, так как объект на обратном движении будет тормозить. скалярное произведение это косинус угла :-)

CRASHER 26.01.2012 03:32

Ответ: Плавное движение по точкам.
 
dsd, лады, попробую повертеть, а пока пошуршу в коде ханона, который так любезно предоставил LLI.T.A.L.K.E.R., спасибо ему за содействие!)

LLI.T.A.L.K.E.R., слухай, чот намудрено в коде. У тебя исходного оригенала нет? Там типы пропущеные, массивы не объявленные. Поправил что увидел, но все равно не работает.

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


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

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