Показать сообщение отдельно
Старый 15.10.2015, 19:18   #12
polopok
ПроЭктировщик
 
Регистрация: 17.07.2009
Сообщений: 182
Написано 51 полезных сообщений
(для 71 пользователей)
Ответ: RagDoll physic. Физика взаимодействия

Несколько иной вариант реализации ,на основе пружин. Минимальный
Оригинал статьи http://pmg.org.ru/nehe/nehe40.htm
Код под спойлером :
;
Global ptx#[150], pty#[150] 
; создаются пружины
    For x = 1 To 15 
        ptx[x] = x * 40
        pty[x] = 200
        po = po + 1
    Next 


Global mx#,my#

Graphics 800,600,32,2
SetBuffer BackBuffer()

k# = 0.05 ; упругость пружины
f# = 0.8 ; внешняя сила трения
m1# = 1 : m2# = 0.5 ; массы ! ни в коим случае не должны быть равны нулю !!!
d# = 40 ; длина пружины

While Not KeyHit(1)
ClsColor 128,128,128
Cls 
; если расстояние от стрелки курсора до точки < 5
; запоминаем точку
mx = MouseX() : my = MouseY() 
For n = 1 To po - 1
    If Distance(mx, my, ptx[n], pty[n] ) < 5 
    num = n 
    EndIf 
Next 

; если левая кнопка мыши нажата перемещаем точку в координаты мыши
; а нулевой точки , то нету :)   
If MouseDown(1) ptx[num] = mx : pty[num] = my

For n = 1 To po - 2
; вычисление вектора
    vx# = (ptx[n] - ptx[n + 1]) : vy# = (pty[n ] - pty[n +1])
; длинна вектора (расстояние)
    r# = Sqr(vx * vx + vy * vy) : If r = 0 r = 0.00001
    
;    { вектор силы = вектор пружины * упругость пружины * длину пружины 

    fx# = (vx/r) * -k * (r - d) 
    fy# = (vy/r) * -k * (r - d)

;    }
    ; если точки совпадают ,то будут расходиться
    If ptx[n] = ptx[n + 1] And pty[n] = pty[n + 1]
        ptx[n] = ptx[n]  - (fx * m1 * f) 
        pty[n] = pty[n]  - (fy * m1* f)
        
        ptx[n + 1] = ptx[n + 1] + (fx * m2 * f) 
        pty[n + 1] = pty[n + 1] + (fy * m2 * f)
    EndIf 
    
    ;  будут сходиться пока не достигнут длины пружины
    ptx[n] = ptx[n]  + (fx * m1 * f) 
    pty[n] = pty[n]  + (fy * m1* f)
                                         ; сила * массу * на трение
    ptx[n + 1] = ptx[n + 1] - (fx * m2 * f) 
    pty[n + 1] = pty[n + 1] - (fy * m2 * f)
Next 

; рисуем пружины
For n = 1 To po - 2
;    DrawSpring#(ptx[n], pty[n], ptx[n + 1], pty[n + 1], d, 4)
    
    Color 255, 255, 255
    Line ptx[n], pty[n], ptx[n + 1], pty[n + 1]
    
    Color 255, 0, 0
    Oval ptx[n] - 2, pty[n] - 2, 4, 4, 1
    
;Text ptx[n], pty[n] - 15,"m1 "+m1
;Text ptx[n + 1], pty[n + 1] - 15,"m2 "+m2    
Next 


Flip 
Wend
End 

; графический примитив Пружина
Function DrawSpring#(ox#, oy#, px#, py#, lenght#, psr = 2)
    Local tt#, t#, cx#, cy#, dx# = ox, dy# = oy
    Local vx# = (px - ox), vy# = (py - oy), r# = Sqr(vx * vx + vy * vy)
    
    If r = 0 r = 0.00001
    vx = vx / r  :  vy = vy / r
    tt# = 1.0 /( lenght * (psr * 0.25)) ; 0.5
    t# = tt    
        dx = (1 - t) * ox + px * t
        dy = (1 - t) * oy + py * t    

        Color 255, 255, 255
        Line ox + vy , oy + -vx , dx + vy * -psr, dy + -vx * -psr
    t = t + tt
    While t <= 1
        cx = (1 - t) * ox + px * t
        cy = (1 - t) * oy + py * t

        Color 55, 55, 55
        Line dx + vy * psr, dy + -vx * psr, dx + vy * -psr, dy + -vx * -psr        
        Color 255, 255, 255
        Line dx + vy * psr, dy + -vx * psr, cx + vy * -psr, cy + -vx * -psr
        
        dx = cx : dy = cy
        t = t + tt
    Wend
        Color 55, 55, 55
        Line cx + vy * psr, cy + -vx * psr, cx + vy * -psr, cy + -vx * -psr
        Color 255, 255, 255
        
        Text (ox + px) / 2 + vy * (psr + 12), (oy + py) / 2 + -vx * (psr + 12), r Shr 0
End Function

Function Distance#( Point_X1#,Point_Y1#,Point_X2#,Point_Y2# )
    Return ((Point_X1 - Point_X2)*(Point_X1 - Point_X2) + (Point_Y1 - Point_Y2)*(Point_Y1 - Point_Y2))^0.5 
End Function
__________________
Мой проект здесь
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
St_AnGer (16.10.2015)