------ ФИЗИКА на Блитц3Д --------- ----- ЧАСТЬ 1 Введение ------------ И так, как мы представляем себе физику ? это набор правил и законов, по которым действует наш физический мир. Поэтому будем использовать кое-где реальные физические законы из нашего мира . Наша физика будет основана на частицах и связях между ними. Частица это просто сфера(шар), которая взаимодействует с полигональными объектами (так как в блитце нам не предоставили инструмент по обработке столконвений между полигональными моделями, то мы будем использовать конструкцию "шар-полигон"). Связи будут удерживать наши частицы связанными между собой, чтобы при движении они не смогли "убежать" от своих собратьев)) . То есть мы просто ограничиваем дистанцию между шарами. -------- Часть 2 Первые шаги ------------- И так, приступим. Создадим тип для наших частиц : Type Phys End Type Теперь нужно добавить параметры частице. Какие же свойства должна иметь частица ? Во-первых указатель на объект-частицу, чтобы нам знать что перемещать. Дальше позицию, скорость и ускорение. Позицию можно не записывать, так как мы всегда сможем достать ее из объекта-частицы через наш указатель , но нам понадобится знать предыдущую позицию, поэтому всеже запишем . Также понадобятся еще два важных свойства - это размер и масса. Вот он наш тип для частиц: Code Type Phys Field entity ; указатель Field x#, y#, z# ; позиция Field vx#, vy#, vz# ; вектор скорости Field ax#, ay#, az# ; вектор ускорения Field size# ; размер Field mass# ; масса End Type Чтож, раз тип у нас есть пора написать первую функцию - функцию создания частицы: Code Function AddPhys(x#=0, y#=0, z#=0, size#=1.0, mass#=1.0) Local p.Phys = New Phys p\x=x : p\y=y : p\z=z p\size = size p\mass = mass p\entity = CreateSphere(16) ScaleEntity p\entity, p\size, p\size, p\size PositionEntity p\entity, x, y, z EntityType p\entity, PhysCol EntityRadius p\entity, p\size NameEntity p\entity, Handle(p)
Return p\entity End Function В ней мы создаем частицу, записываем параметры, устанавливаем коллизионный тип, записываем указатель на тип в имя частицы и возвращает указатель на частицу, чтобы потом можно было к ней обратиться. Теперь напишем функцию обновления физики. Для начала заметим, что обновление физики мы разделим на 2 части: присвоение импульсов (сил) и обсчет реакции. И так, рассмотрим функцию добавления сил. Какие силы мы будем присваивать? во первых импульс ускорения, а во-вторых гравитацию, у нас же все таки приземленные взгляды на физику) так что притяним частицы к земле. Помимо константы с типом коллизии добавим туда константу гравитации :
Const PhysCol=1, LevelCol=2 Const Gravity# = -0.04
Теперь можно браться за саму функцию : Code Function PhysAddedForce() Local p.Phys For p.Phys = Each Phys ;-- добавляем гравитацию p\vy = p\vy + Gravity ;-- добавляем ускорения p\vx = p\vx + p\ax p\vy = p\vy + p\ay p\vz = p\vz + p\az ;-- записываем текущую позицию p\x = EntityX(p\entity,1) p\y = EntityY(p\entity,1) p\z = EntityZ(p\entity,1) ;-- изменяем позицию TranslateEntity p\entity, p\vx, p\vy, p\vz ;-- обнуление вектора ускорения p\ax = 0 p\ay = 0 p\az = 0 Next End Function С помощью этой функции наши частицы смогут постоянно набирать скорость. Что же на счет второй функции, так там нам придется сделать чуть больший объем работ. Там мы будет обсчитывать реакцию на коллизию, отскок шарика от поверхности полигона, торможение за счет трения (без углового трения). Вот наша функция : Code Const f_air# = 0.98, f_ground# = 0.8
Function PhysUpdate() Local Nx#, Ny#, Nz#, VdotN# Local NFx#, NFy#, NFz# Local count, i Local p.Phys For p.Phys = Each Phys ; проверка столкновения count = CountCollisions(p\entity) If count > 0 Then For i = 1 To count ; получение нормали от поверхности, с которой столкнулись. Nx# = CollisionNX(p\entity, i) Ny# = CollisionNY(p\entity, i) Nz# = CollisionNZ(p\entity, i) ; перемножение вектора скорости с нормалью поверхности VdotN = p\vx*Nx + p\vy*Ny + p\vz*Nz ; просчет нормали силы ; цифра (-2) значит, что мы отзеркаливаем силу NFx = -2 * Nx * VdotN NFy = -2 * Ny * VdotN NFz = -2 * Nz * VdotN ; добавляем силу в вектор движения p\vx = p\vx + NFx p\vy = p\vy + NFy p\vz = p\vz + NFz Next ; добавляем трение с землей, чтобы тормозить частицы p\vx = p\vx * f_ground p\vy = p\vy * f_ground p\vz = p\vz * f_ground EndIf ; трение с воздухом p\vx = p\vx * f_air p\vy = p\vy * f_air p\vz = p\vz * f_air Next End Function В ней мы стали считать отскок шарика от поверхности. Сначало получили нормаль поверхности, ведь нам надо знать ее ориентацию в мире, чтобы отзеркалить движение частицы Более подробно расчет отскока рассмотрен на рисунке ниже : Вот и готов первый этап нашей физики, чтобы посмотреть конечный результат смотрите пример TutorPhys1.bb . -------- Часть 3 Манипулирование и связи ------------- Раз уж у нас есть физические объекты, то нужно ими как-то манипулировать, например придавать импульс движения. Вот как будет выглядеть функция добавления импульса : Code Function AddForce(phys, ax#, ay#, az#) Local p.Phys = Object.Phys(EntityName(phys)) If p = Null Then Return False p\ax = p\ax + ax p\ay = p\ay + ay p\az = p\az + az Return True End Function Все что она делает, так это добавляет силу в вектор ускорения частицы, который затем будет обсчитываться. Пример с использованием этой функции называется TutorPhys2.bb . Чтож, теперь приступим к связыванию наших частиц между собой. Создадим тип для свя-зей. Code Type Link Field p1.Phys ; первая частица Field p2.Phys ; вторая частица Field dist# ; требуемое расстояние между частицами End Type Теперь приступим к функции связывания, которая будет связывать две частицы между собой. Code Function AddLink(p1, p2, dist#=-1) Local l.Link = New Link l\p1 = Object.Phys(EntityName(p1)) l\p2 = Object.Phys(EntityName(p2)) ;-- если параметр меньше 0, ;-- то рассчитать автоматически, ;-- иначе присвоить значение. If dist < 0 Then l\dist = EntityDistance(p1, p2) Else l\dist = dist EndIf Return Handle(l) End Function Тут все просто, мы заносим в тип две частицы и записываем расстояние между ними. Теперь нам нужно притягивать связанные частицы друг к другу на определенное расстояние: Code Function LinkUpdate() Local dx#, dy#, dz# Local diff# Local deltalength# Local l.Link For l.Link = Each Link ;-- разность позиций dx = EntityX(l\p1\entity,1)-EntityX(l\p2\entity,1) dy = EntityY(l\p1\entity,1)-EntityY(l\p2\entity,1) dz = EntityZ(l\p1\entity,1)-EntityZ(l\p2\entity,1) ;-- текущая дистанция deltalength# = EntityDistance(l\p1\entity, l\p2\entity) ;-- смещения частиц по направлению друг к другу, или наоборот, друг от друга ;-- в зависимости от текущей и требуемых дистанций. Также учитывается масса diff# = (deltalength - l\dist) / (deltalength * (l\p1\mass+l\p2\mass)) ;-- раздвигаем частицы TranslateEntity l\p1\entity, -l\p2\mass*dx*diff, -l\p2\mass*dy*diff, -l\p2\mass*dz*diff TranslateEntity l\p2\entity, l\p1\mass*dx*diff, l\p1\mass*dy*diff, l\p1\mass*dz*diff ;-- записываем смещения в вектор движения l\p1\vx = l\p1\vx - l\p2\mass*dx*diff l\p1\vy = l\p1\vy - l\p2\mass*dy*diff l\p1\vz = l\p1\vz - l\p2\mass*dz*diff l\p2\vx = l\p2\vx + l\p1\mass*dx*diff l\p2\vy = l\p2\vy + l\p1\mass*dy*diff l\p2\vz = l\p2\vz + l\p1\mass*dz*diff Next End Function Выглядит сложно, но разобрать думаю не составит труда Эта функция распределяет между частицами силу притяжения/отталкивания друг к другу, также тут учитывается их масса, поэтому более тяжелая частица будет перемещаться на меньшее расстояние, чем ее связь – легкая частица. Пример можете посмотреть, запустив файл TutorPhys3.bb . Внизу приведен полный код выполненных нами программ. TutorPhys1.bb Code ;==================================================================== ; Project: Physic Sample ; Version: 0.0.1 ; Author: H@non ; Email: hanon90@gmail.com ; Description: Tutorial ; ; ;====================================================================
Global GraphW = 800 Global GraphH = 600 Global GraphBits = 32 Global GraphMode = 2
Graphics3D GraphW, GraphH, GraphBits, GraphMode SetBuffer BackBuffer() SeedRnd MilliSecs()
;========== Global Variables =========== ;--- Main --------- Global GraphWmid = GraphW Shr 1 Global GraphHmid = GraphH Shr 1 Global Quit=False, Vsync=False
Const PhysCol=1, LevelCol=2 Const Gravity# = -0.04
Type Phys Field entity ; указатель Field x#, y#, z# ; позиция Field vx#, vy#, vz# ; вектор скорости Field ax#, ay#, az# ; вектор ускорения Field size# ; размер Field mass# ; масса Field vel# ; скорость (скалярное значение) End Type
;------ СОЗДАНИЕ МИРА ---------
;-- свет Local lit = CreateLight() RotateEntity lit, 45, 45, 0
;-- камера Local camera = CreateCamera() PositionEntity camera, 0, 5, -5 RotateEntity camera, 30, 0, 0
;-- земля Local plane = CreatePlane() Local texplane = CreateTexture( 128, 128 ) SetBuffer TextureBuffer(texplane) For Y = 0 To 128 For X = 0 To 128 WritePixel X, Y, (Rand(96,160) * $010101) Or $FF000000 Next Next SetBuffer BackBuffer() ScaleTexture texplane, 5, 5 EntityTexture plane, texplane EntityColor plane, 0, 255, 0 EntityType plane, LevelCol
;-- физическая частица Local phys = AddPhys(0, 5, 0)
Collisions PhysCol, LevelCol, 2, 3 ;=========== ГЛАВНЫЙ ЦИКЛ ======================= While KeyDown(1)=0 PhysAddedForce() UpdateWorld() PhysUpdate()
RenderWorld() Flip Wend
End
;========================================================= ;================== ФУНКЦИИ ==============================
Function AddPhys(x#=0, y#=0, z#=0, size#=1.0, mass#=1.0) Local p.Phys = New Phys p\x=x : p\y=y : p\z=z p\size = size p\mass = mass p\entity = CreateSphere(16) ScaleEntity p\entity, p\size, p\size, p\size PositionEntity p\entity, x, y, z EntityType p\entity, PhysCol EntityRadius p\entity, p\size NameEntity p\entity, Handle(p) Return p\entity End Function
Function PhysAddedForce() Local p.Phys For p.Phys = Each Phys ;-- добавляем гравитацию p\vy = p\vy + Gravity ;-- добавляем ускорения p\vx = p\vx + p\ax p\vy = p\vy + p\ay p\vz = p\vz + p\az ;-- записываем текущую позицию p\x = EntityX(p\entity,1) p\y = EntityY(p\entity,1) p\z = EntityZ(p\entity,1) ;-- изменяем позицию TranslateEntity p\entity, p\vx, p\vy, p\vz ;-- обнуление вектора ускорения p\ax = 0 p\ay = 0 p\az = 0 Next End Function
Function PhysUpdate() Local vx2#, vy2#, vz2# Local Nx#, Ny#, Nz#, VdotN# Local NFx#, NFy#, NFz# Local count, i Local p.Phys For p.Phys = Each Phys ; обсчет скорости после коллизии vx2 = EntityX(p\entity,1) - p\x vy2 = EntityY(p\entity,1) - p\y vz2 = EntityZ(p\entity,1) - p\z p\x = EntityX(p\entity,1) p\y = EntityY(p\entity,1) p\z = EntityZ(p\entity,1) p\vel = 0.0 ; проверка столкновения count = CountCollisions(p\entity) If count > 0 Then ; считаем линейную скорость p\vel = Sqr(vx2*vx2 + vy2*vy2 + vz2*vz2) For i = 1 To count ; получение нормали от поверхности, с которой столкнулись. Nx# = CollisionNX(p\entity, i) Ny# = CollisionNY(p\entity, i) Nz# = CollisionNZ(p\entity, i) ; перемножение вектора скорости с нормалью поверхности VdotN = p\vx*Nx + p\vy*Ny + p\vz*Nz ; просчет нормали силы ; цифра (-2) значит, что мы отзеркаливаем силу NFx = -2 * Nx * VdotN NFy = -2 * Ny * VdotN NFz = -2 * Nz * VdotN ; добавляем силу в вектор движения p\vx = p\vx + NFx p\vy = p\vy + NFy p\vz = p\vz + NFz Next ; добавляем трения, чтобы тормозить частицы p\vx = p\vx * 0.8 p\vy = p\vy * 0.8 p\vz = p\vz * 0.8 EndIf Next End Function TutorPhys2.bb Code ;==================================================================== ; Project: Physic Sample ; Version: 0.0.2 ; Author: H@non ; Email: hanon90@gmail.com ; Description: Tutorial ; ; ;====================================================================
Global GraphW = 800 Global GraphH = 600 Global GraphBits = 32 Global GraphMode = 2
Graphics3D GraphW, GraphH, GraphBits, GraphMode SetBuffer BackBuffer() SeedRnd MilliSecs()
;========== Global Variables =========== ;--- Main --------- Global GraphWmid = GraphW Shr 1 Global GraphHmid = GraphH Shr 1 Global Quit=False, Vsync=False
Const PhysCol=1, LevelCol=2 Const Gravity# = -0.04 Const f_air# = 0.98, f_ground# = 0.8
Type Phys Field entity ; указатель Field x#, y#, z# ; позиция Field vx#, vy#, vz# ; вектор скорости Field ax#, ay#, az# ; вектор ускорения Field size# ; размер Field mass# ; масса End Type
;------ СОЗДАНИЕ МИРА --------- Local font = LoadFont("arial cyr", 20) SetFont font
;-- свет Local lit = CreateLight() RotateEntity lit, 45, 45, 0
;-- камера Local camera = CreateCamera() PositionEntity camera, 0, 5, -15 RotateEntity camera, 30, 0, 0
;-- земля Local plane = CreatePlane() Local texplane = CreateTexture( 128, 128 ) SetBuffer TextureBuffer(texplane) For Y = 0 To 128 For X = 0 To 128 WritePixel X, Y, (Rand(96,160) * $010101) Or $FF000000 Next Next SetBuffer BackBuffer() ScaleTexture texplane, 5, 5 EntityTexture plane, texplane EntityColor plane, 0, 255, 0 EntityType plane, LevelCol
;-- физическая частица Local phys = AddPhys(0, 5, 0)
Collisions PhysCol, LevelCol, 2, 3 ;=========== ГЛАВНЫЙ ЦИКЛ ======================= While KeyDown(1)=0 AddForce(phys, 0, (KeyDown(200)-KeyDown(208))*0.1, 0) PhysAddedForce() UpdateWorld() PhysUpdate() PointEntity camera, phys
RenderWorld() Text 10, 10, "управление : стрелки вверх / вниз" Flip Wend
End
;========================================================= ;================== ФУНКЦИИ ==============================
Function AddPhys(x#=0, y#=0, z#=0, size#=1.0, mass#=1.0) Local p.Phys = New Phys p\x=x : p\y=y : p\z=z p\size = size p\mass = mass p\entity = CreateSphere(16) ScaleEntity p\entity, p\size, p\size, p\size PositionEntity p\entity, x, y, z EntityType p\entity, PhysCol EntityRadius p\entity, p\size NameEntity p\entity, Handle(p) Return p\entity End Function
Function AddForce(phys, ax#, ay#, az#) Local p.Phys = Object.Phys(EntityName(phys)) If p = Null Then Return False p\ax = p\ax + ax p\ay = p\ay + ay p\az = p\az + az Return True End Function
Function PhysAddedForce() Local p.Phys For p.Phys = Each Phys ;-- добавляем гравитацию p\vy = p\vy + Gravity ;-- добавляем ускорения p\vx = p\vx + p\ax p\vy = p\vy + p\ay p\vz = p\vz + p\az ;-- записываем текущую позицию p\x = EntityX(p\entity,1) p\y = EntityY(p\entity,1) p\z = EntityZ(p\entity,1) ;-- изменяем позицию TranslateEntity p\entity, p\vx, p\vy, p\vz ;-- обнуление вектора ускорения p\ax = 0 p\ay = 0 p\az = 0 Next End Function
Function PhysUpdate() Local Nx#, Ny#, Nz#, VdotN# Local NFx#, NFy#, NFz# Local count, i Local p.Phys For p.Phys = Each Phys ; проверка столкновения count = CountCollisions(p\entity) If count > 0 Then For i = 1 To count ; получение нормали от поверхности, с которой столкнулись. Nx# = CollisionNX(p\entity, i) Ny# = CollisionNY(p\entity, i) Nz# = CollisionNZ(p\entity, i) ; перемножение вектора скорости с нормалью поверхности VdotN = p\vx*Nx + p\vy*Ny + p\vz*Nz ; просчет нормали силы ; цифра (-2) значит, что мы отзеркаливаем силу NFx = -2 * Nx * VdotN NFy = -2 * Ny * VdotN NFz = -2 * Nz * VdotN ; добавляем силу в вектор движения p\vx = p\vx + NFx p\vy = p\vy + NFy p\vz = p\vz + NFz Next ; добавляем трение с землей, чтобы тормозить частицы p\vx = p\vx * f_ground p\vy = p\vy * f_ground p\vz = p\vz * f_ground EndIf ; трение с воздухом p\vx = p\vx * f_air p\vy = p\vy * f_air p\vz = p\vz * f_air Next End Function TutorPhys3.bb Code ;==================================================================== ; Project: Physic Sample ; Version: 0.0.3 ; Author: H@non ; Email: hanon90@gmail.com ; Description: Tutorial ; ; ;====================================================================
Global GraphW = 800 Global GraphH = 600 Global GraphBits = 32 Global GraphMode = 2
Graphics3D GraphW, GraphH, GraphBits, GraphMode SetBuffer BackBuffer() SeedRnd MilliSecs()
;========== Global Variables =========== ;--- Main --------- Global GraphWmid = GraphW Shr 1 Global GraphHmid = GraphH Shr 1 Global Quit=False, Vsync=False
Const PhysCol=1, LevelCol=2 Const Gravity# = -0.04 Const f_air# = 0.98, f_ground# = 0.8
Type Phys Field entity ; указатель Field x#, y#, z# ; позиция Field vx#, vy#, vz# ; вектор скорости Field ax#, ay#, az# ; вектор ускорения Field size# ; размер Field mass# ; масса End Type
Type Link Field p1.Phys ; первая частица Field p2.Phys ; вторая частица Field dist# ; требуемое расстояние между частицами End Type
;------ СОЗДАНИЕ МИРА --------- Local font = LoadFont("arial cyr", 20) SetFont font
;-- свет Local lit = CreateLight() RotateEntity lit, 45, 45, 0
;-- камера Local camera = CreateCamera() PositionEntity camera, 0, 5, -15 RotateEntity camera, 30, 0, 0
;-- земля Local plane = CreatePlane() Local texplane = CreateTexture( 128, 128 ) SetBuffer TextureBuffer(texplane) For Y = 0 To 128 For X = 0 To 128 WritePixel X, Y, (Rand(96,160) * $010101) Or $FF000000 Next Next SetBuffer BackBuffer() ScaleTexture texplane, 5, 5 EntityTexture plane, texplane EntityColor plane, 0, 255, 0 EntityType plane, LevelCol
;-- физическая частица Local phys = AddPhys(0, 5, 0) Local phys2 = AddPhys(3, 5, 0, 2, 4)
;-- соединяем частицы AddLink(phys, phys2)
Collisions PhysCol, LevelCol, 2, 3 ;=========== ГЛАВНЫЙ ЦИКЛ ======================= While KeyDown(1)=0 AddForce(phys, (KeyDown(205)-KeyDown(203))*0.2, KeyDown(57)*0.2, (KeyDown(200)-KeyDown(208))*0.2) PhysAddedForce() UpdateWorld() PhysUpdate() LinkUpdate() PointEntity camera, phys
RenderWorld() Text 10, 10, "управление : стрелки + пробел" Flip Wend
End
;========================================================= ;================== ФУНКЦИИ ==============================
;--------- Функции создания ----------------
Function AddPhys(x#=0, y#=0, z#=0, size#=1.0, mass#=1.0) Local p.Phys = New Phys p\x=x : p\y=y : p\z=z p\size = size p\mass = mass p\entity = CreateSphere(16) ScaleEntity p\entity, p\size, p\size, p\size PositionEntity p\entity, x, y, z EntityType p\entity, PhysCol EntityRadius p\entity, p\size NameEntity p\entity, Handle(p) Return p\entity End Function
Function AddLink(p1, p2, dist#=-1) Local l.Link = New Link l\p1 = Object.Phys(EntityName(p1)) l\p2 = Object.Phys(EntityName(p2)) ;-- если параметр меньше 0, ;-- то рассчитать автоматически, ;-- иначе присвоить значение. If dist < 0 Then l\dist = EntityDistance(p1, p2) Else l\dist = dist EndIf Return Handle(l) End Function
;--------- Функции манипуляции ---------------
Function AddForce(phys, ax#, ay#, az#) Local p.Phys = Object.Phys(EntityName(phys)) If p = Null Then Return False p\ax = p\ax + ax p\ay = p\ay + ay p\az = p\az + az Return True End Function
;--------- Функции обновления состояния -----------
Function PhysAddedForce() Local p.Phys For p.Phys = Each Phys ;-- добавляем гравитацию p\vy = p\vy + Gravity ;-- добавляем ускорения p\vx = p\vx + p\ax p\vy = p\vy + p\ay p\vz = p\vz + p\az ;-- записываем текущую позицию p\x = EntityX(p\entity,1) p\y = EntityY(p\entity,1) p\z = EntityZ(p\entity,1) ;-- изменяем позицию TranslateEntity p\entity, p\vx, p\vy, p\vz ;-- обнуление вектора ускорения p\ax = 0 p\ay = 0 p\az = 0 Next End Function
Function PhysUpdate() Local Nx#, Ny#, Nz#, VdotN# Local NFx#, NFy#, NFz# Local count, i Local p.Phys For p.Phys = Each Phys ; проверка столкновения count = CountCollisions(p\entity) If count > 0 Then For i = 1 To count ; получение нормали от поверхности, с которой столкнулись. Nx# = CollisionNX(p\entity, i) Ny# = CollisionNY(p\entity, i) Nz# = CollisionNZ(p\entity, i) ; перемножение вектора скорости с нормалью поверхности VdotN = p\vx*Nx + p\vy*Ny + p\vz*Nz ; просчет нормали силы ; цифра (-2) значит, что мы отзеркаливаем силу NFx = -2 * Nx * VdotN NFy = -2 * Ny * VdotN NFz = -2 * Nz * VdotN ; добавляем силу в вектор движения p\vx = p\vx + NFx p\vy = p\vy + NFy p\vz = p\vz + NFz Next ; добавляем трение с землей, чтобы тормозить частицы p\vx = p\vx * f_ground p\vy = p\vy * f_ground p\vz = p\vz * f_ground EndIf ; трение с воздухом p\vx = p\vx * f_air p\vy = p\vy * f_air p\vz = p\vz * f_air Next End Function
Function LinkUpdate() Local dx#, dy#, dz# Local diff# Local deltalength# Local l.Link For l.Link = Each Link ;-- разность позиций dx = EntityX(l\p1\entity,1)-EntityX(l\p2\entity,1) dy = EntityY(l\p1\entity,1)-EntityY(l\p2\entity,1) dz = EntityZ(l\p1\entity,1)-EntityZ(l\p2\entity,1) ;-- текущая дистанция deltalength# = EntityDistance(l\p1\entity, l\p2\entity) ;-- смещения частиц по направлению друг к другу, или наоборот, друг от друга ;-- в зависимости от текущей и требуемых дистанций. Также учитывается масса diff# = (deltalength - l\dist) / (deltalength * (l\p1\mass+l\p2\mass)) ;-- раздвигаем частицы TranslateEntity l\p1\entity, -l\p2\mass*dx*diff, -l\p2\mass*dy*diff, -l\p2\mass*dz*diff TranslateEntity l\p2\entity, l\p1\mass*dx*diff, l\p1\mass*dy*diff, l\p1\mass*dz*diff ;-- записываем смещения в вектор движения l\p1\vx = l\p1\vx - l\p2\mass*dx*diff l\p1\vy = l\p1\vy - l\p2\mass*dy*diff l\p1\vz = l\p1\vz - l\p2\mass*dz*diff l\p2\vx = l\p2\vx + l\p1\mass*dx*diff l\p2\vy = l\p2\vy + l\p1\mass*dy*diff l\p2\vz = l\p2\vz + l\p1\mass*dz*diff Next End Function
|