суббота, 20 февраля 2016 г.

Описание эффекта гравитации в maxscript


 для одного объекта
------------------------------------------------------------------------
try(delete objects)catch()

theObj = sphere pos: [0, 0, 0] radius: 10
theObj.showTrajectory = on
   
f = [0,0,-10000]
m = 1.0
dt = 0.005
tk = 15
p0 = theObj.pos
v0 = [200,200,2000]
arrPos = #(p0)
arrV = #(v0)
num = 1

for t = 0 to tk by dt do(
   
    arrV[num+1] = arrV[num] + f*dt/m -- V1 = V0 + f*dt/m
    arrPos[num+1] = arrPos[num] + arrV[num+1]*dt -- P1 = P0 + V1*dt
    append arrPos arrPos[num+1]
    append arrV arrV[num+1]
    num += 1
    )

---animate
animationRange = interval animationRange.start 100
NumArr =  arrPos.count   
k=1
animate on
for t = 1 to (NumArr-1) by 1  do
(
    at time t
    (
            theObj.pos = arrPos[k]
            k+= 1
    )
)
------------------------------------------------------------------------
для нескольких объектов, но с ограничением по количеству (на нескольких сотнях зависает из-за переполнения массива)

------------------------------------------------------------------------
 try(delete objects)catch()
arM = #()
arP = #()
arV = #()

numObj = 30
tk = 30

arM = for i = 1 to numObj collect random 0.01 0.7  
arP = for i = 1 to numObj collect #(random [-100, -100, -100] [100, 100, 100])  --
arV = for i = 1 to numObj collect #(random [-20, -20, 0] [20, 20, 0])


dt = 0.01
n = 1
progressstart "calculate..."
for t = 0 to tk by dt do(
    for i = 1 to numObj do(
        --summarnaya sila deystvuyshaya na i-iy object
        sF = [0.0, 0.0, 0.0]
        for j = 1 to numObj where j != i do(
                nAr = arP[i].count
                dS = arP[j][nAr] - arP[i][nAr]
                dSn = normalize dS
                dist = length dS
                F = if dist < 100 then -1.0*dSn*arM[j] else dSn*arM[j]
                sF += F
            )
            arV[i][n+1] = arV[i][n] + sF*dt/arM[i] -- V1 = V0 + f*dt/m; F = ma => F=m*dV/dt => dV = F*dt/m
            arP[i][n+1] = arP[i][n] + arV[i][n+1]*dt -- P1 = P0 + V1*dt => dS = P1 - P0
            )-- end i
    n += 1
    progressupdate (t*100.0/tk)
    )
progressend ()

--create objects
arO = #()  
nAr =  arP.count  
for i = 1 to nAr do append arO (sphere pos:arP[i][1] radius:(10*arM[i]))

---animate

nnAr =  arP[1].count  
nFrame = 300  
animationRange = interval animationRange.start nFrame
delta = (nnAr/nFrame) as integer
k = 1
animate on
for t = 1 to nFrame do(
    at time t(
            for i = 1 to nAr do arO[i].pos = arP[i][k]
            k += delta
        )
)
------------------------------------------------------------------------

То же, но для большего количества объектов с покадровым расчетом.
------------------------------------------------------------------------
try(delete objects)catch()
global numObj = 1000
global nFrame = 200   
global arO = #()   

for i = 1 to numObj do(
    local p = random [-50, -50, -50] [50, 50, 50]
    local r = random 1 3
    local v = random [-10, -10, -10] [10, 10, 10]
    append arO #(sphere pos:p radius:r, r, p, v)  -- r-radius sphere ili massa, p - position, v - velosity
)
--tk=1
--dt=0.01

fn grav dt dataObj = (  --tk - konechnoe vremya, dt - shag,
    dataObj_out = #()
    nO = dataObj.count
        --progressstart "calculate..."
        --for t = 0 to tk by dt do(
            for i = 1 to nO do(
                --summarnaya sila deystvuyshaya na i-iy object
                sF = [0.0, 0.0, 0.0]
                mObj = dataObj[1]
                for j = 1 to nO where j != i do(
                        dS = dataObj[j][3] - dataObj[i][3]; dSn = normalize dS; dist = length dS;
                        F = if dist < 1 then -1000.0*dSn*dataObj[j][2] else dSn*dataObj[j][2]
                        sF += F
                    )
                   
                    V2 = dataObj[i][4] + sF*dt/dataObj[i][2] -- V1 = V0 + f*dt/m; F = ma => F=m*dV/dt => dV = F*dt/m
                    P2 = dataObj[i][3] + V2*dt -- P1 = P0 + V1*dt => dS = P1 - P0
                    append dataObj_out #(dataObj[i][1], dataObj[i][2], P2, V2)
                    )-- end i
            arO = dataObj_out
            --progressupdate (t*100.0/tk) 
            --)
        --progressend ()
    )


---animate

nnAr =  arP[1].count   

animationRange = interval animationRange.start nFrame
animate on
for t = 1 to nFrame do(
    at time t(
            sliderTime = t
            redrawViews()    
            Grav 0.05 arO
            for i = 1 to numObj do    arO[i][1].pos = arO[i][3]
        )
)
------------------------------------------------------------------------

Комментариев нет:

Отправить комментарий