![]() |
|
||||||||||
|
|||||
|
Ну.. Просвети пожалуйста, что такое LCP...=) Статья на английском... Это конечно не критично, но требует в несколько раз больше времени для освоения=(
Последний раз редактировалось Crash512; 19.09.2008 в 16:39. |
|
|||||
|
Регистрация: Feb 2008
Сообщений: 111
|
Ну есть два подхода, первый элементарный и неточный это Верлетовский (position based). Второй намного точнее и использующийся во всех нормальных движках (например в box2d) это - импульсный подход. Там как раз вылезает LCP задача - Это когда надо найти такие x и y, что Ax+b=y при условии что x*y=0 , x>=0 y>=0. Про это написано например в статьях Michael Cline'а или Миртича, еще на gamedev в сообществах много написано.
|
|
|||||
|
вот интересная реализация рагдол... ) http://www.salex.ru/fun/falling-girl.php
__________________
Кто может делать - делает, кто не может делать - учит, кто не может учить - управляет... |
|
|||||
|
Регистрация: Jun 2005
Адрес: Moscow - immigrate from Volgodonsk
Сообщений: 2,534
|
можно вечно смотреть на три вещи:огонь, воду и падающую девушку ))
|
|
|||||
|
В движке Хитмана использовалось интегрирование Верлета для одежды и падающих трупов.. Неточность компенсирует быстродействие=)
Господа! Ну ответьте пожалуйста на вопрос про треугольник... Очень надо... Я ж знаю, кто-то точно в курсе=) |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Цитата:
Ждите ответа молча. |
|
|||||
|
Регистрация: Feb 2008
Сообщений: 111
|
Crash512
1) У вас не правильное разрешение ограничений. Нужно двигать обе точки, а не одну из них. На сом деле вам нужно два типа связей первый тип- это связь мышки с партиклом(то что у вас написано именно тот случай), а второй тип - связь партикла с партиклом - там как раз надо обе двигать на 0.5*dp (в случае равных масс). 2)У вас неверная структура "движка". Все внешние силы (например сила тяжести) должны применяться строго до разрешения ограничений в одной и той же функции. Так же разрешение ограничений делается не 1ой итерацией как у вас а несколькими ( в этом и есть основная фишка данного подхода - все быстро сойдется). 3)Нельзя использовать для расчетов x и y координаты спрайта, лучше завести отдельные переменные, а после каждого шага интегрирования приравнивать их. Вобщем я бы советовал все же прочесть ту статью, и заново все переписать ![]() |
|
|||||
|
Спасибо за ответ!=)
Т.е. мне надо проводить интеграцию Верлета не для каждой частицы отдельно, а допустим, загнать все частицы в массив, и использовать цикл с перебором его элементов? При этом, на время разрешения ограничений надо прекращать этот цикл?.. |
|
|||||
|
Вот обновочка... Учёл все замечания. Треугольник выровнялся, но всю верёвку немного клонит влево... Не могу понять, почему..=(
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main extends Sprite
{
private var pt:Array = new Array();
private var particles:Sprite = new Sprite();
private var canvas:Shape = new Shape();
private var grav:Number = 5;
// ========================================================== //
public function Main():void
{
stage.frameRate = 40;
addChild(canvas);
addChild(particles);
pt.push(new Particle(270,150));
pt.push(new Particle(270,175));
pt.push(new Particle(270,200));
pt.push(new Particle(270,225));
pt.push(new Particle(270,250));
pt.push(new Particle(270,275));
pt.push(new Particle(255,285));
pt.push(new Particle(285,285));
for (var i in pt)
{
particles.addChild(pt[i]);
}
addEventListener(Event.ENTER_FRAME, checkJoints);
addEventListener(Event.ENTER_FRAME, ptMouse);
}
// ========================================================== //
private function checkJoints(event:Event):void
{
var dx:Number;
var dy:Number;
canvas.graphics.clear();
// Gravity
for (var i in pt)
{
dx = (pt[i].x - pt[i].old_x);
dy = (pt[i].y - pt[i].old_y) + grav;
pt[i].old_x = pt[i].x;
pt[i].old_y = pt[i].y;
pt[i].x += dx/1.1;
pt[i].y += dy/1.1;
}
// Joints
for (var z:int=0; z<5; z++)
{
mouseJoint(pt[0], pt[1], 25);
ptJoint(pt[1], pt[2], 25);
ptJoint(pt[2], pt[3], 25);
ptJoint(pt[3], pt[4], 25);
ptJoint(pt[4], pt[5], 25);
ptJoint(pt[5], pt[6], 25);
ptJoint(pt[5], pt[7], 25);
ptJoint(pt[6], pt[7], 25);
}
// Lines
drawLine(pt[1], pt[2]);
drawLine(pt[2], pt[3]);
drawLine(pt[3], pt[4]);
drawLine(pt[4], pt[5]);
drawLine(pt[5], pt[6]);
drawLine(pt[5], pt[7]);
drawLine(pt[6], pt[7]);
}
// ========================================================== //
private function ptMouse(event:Event):void
{
pt[0].x = mouseX;
pt[0].y = mouseY;
drawLine(pt[0], pt[1]);
}
// ========================================================== //
private function mouseJoint(p1:Particle, p2:Particle, len:int):void
{
var dx:Number;
var dy:Number;
var d_len:Number;
var diff:Number;
dx = p2.x-p1.x;
dy = p2.y-p1.y;
d_len = Math.sqrt(dx*dx + dy*dy);
diff = (d_len-len)/d_len;
dx *= diff;
dy *= diff;
p2.x -= dx;
p2.y -= dy;
}
// ========================================================== //
private function ptJoint(p1:Particle, p2:Particle, len:int):void
{
var dx:Number;
var dy:Number;
var d_len:Number;
var diff:Number;
dx = p2.x-p1.x;
dy = p2.y-p1.y;
d_len = Math.sqrt(dx*dx + dy*dy);
diff = (d_len-len)/d_len;
dx *= 0.5*diff;
dy *= 0.5*diff;
p2.x -= dx;
p2.y -= dy;
p1.x += dx;
p1.y += dy;
}
// ========================================================== //
private function drawLine(p1:Particle, p2:Particle):void
{
canvas.graphics.lineStyle(1,0x000000);
canvas.graphics.moveTo(p1.x,p1.y);
canvas.graphics.lineTo(p2.x, p2.y);
}
// ========================================================== //
}
}
// ***** [ Particle Class ] ***************************************** //
import flash.display.Sprite;
internal class Particle extends Sprite
{
public var old_x:Number;
public var old_y:Number;
// ========================================================== //
public function Particle(_x:int, _y:int):void
{
x = _x;
y = _y;
old_x = _x;
old_y = _y;
graphics.lineStyle(1, 0x000000);
graphics.beginFill(0xFFD22B);
graphics.drawCircle(0,0,5);
graphics.endFill();
}
// ========================================================== //
}
|
|
|||||
|
Да, добавь переменные xx,yy в класс Particle и все расчёты веди в них, а потом сливай в x и y - все проблемы пропадут!
Добавлено через 19 минут Вот, это работает: package gerich.verlet { import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class Main extends Sprite { private var pt:Array = new Array(); private var particles:Sprite = new Sprite(); private var canvas:Shape = new Shape(); private var grav:Number = 5; private var timeSqr:Number; // ========================================================== // public function Main():void { stage.frameRate = 40; timeSqr=1/stage.frameRate;timeSqr*=timeSqr; addChild(canvas); addChild(particles); pt.push(new Particle(270,150)); pt.push(new Particle(270,175)); pt.push(new Particle(270,200)); pt.push(new Particle(270,225)); pt.push(new Particle(270,250)); pt.push(new Particle(270,275)); pt.push(new Particle(255,285)); pt.push(new Particle(285,285)); for (var i in pt) { particles.addChild(pt[i]); } addEventListener(Event.ENTER_FRAME, checkJoints); addEventListener(Event.ENTER_FRAME, ptMouse); } // ========================================================== // private function checkJoints(event:Event):void { var dx:Number; var dy:Number; canvas.graphics.clear(); // Gravity for (var i in pt) { dx = (pt[i].xx - pt[i].old_x); dy = (pt[i].yy - pt[i].old_y); pt[i].old_x = pt[i].xx; pt[i].old_y = pt[i].yy; pt[i].xx += dx; pt[i].yy += dy+grav*timeSqr; } // Joints for (var z:int=0; z<5; z++) { mouseJoint(pt[0], pt[1], 25); ptJoint(pt[1], pt[2], 25); ptJoint(pt[2], pt[3], 25); ptJoint(pt[3], pt[4], 25); ptJoint(pt[4], pt[5], 25); ptJoint(pt[5], pt[6], 25); ptJoint(pt[5], pt[7], 25); ptJoint(pt[6], pt[7], 25); } for (var i in pt) { pt[i].x = pt[i].xx; pt[i].y = pt[i].yy; } // Lines drawLine(pt[1], pt[2]); drawLine(pt[2], pt[3]); drawLine(pt[3], pt[4]); drawLine(pt[4], pt[5]); drawLine(pt[5], pt[6]); drawLine(pt[5], pt[7]); drawLine(pt[6], pt[7]); } // ========================================================== // private function ptMouse(event:Event):void { pt[0].xx = mouseX; pt[0].yy = mouseY; pt[0].x = mouseX; pt[0].y = mouseY; drawLine(pt[0], pt[1]); } // ========================================================== // private function mouseJoint(p1:Particle, p2:Particle, len:int):void { var dx:Number; var dy:Number; var d_len:Number; var diff:Number; dx = p2.xx-p1.xx; dy = p2.yy-p1.yy; d_len = Math.sqrt(dx*dx + dy*dy); diff = (d_len-len)/d_len; dx *= diff; dy *= diff; p2.xx -= dx; p2.yy -= dy; } // ========================================================== // private function ptJoint(p1:Particle, p2:Particle, len:int):void { var dx:Number; var dy:Number; var d_len:Number; var diff:Number; dx = p2.xx-p1.xx; dy = p2.yy-p1.yy; d_len = Math.sqrt(dx*dx + dy*dy); diff = (d_len-len)/d_len; dx *= 0.5*diff; dy *= 0.5*diff; p2.xx -= dx; p2.yy -= dy; p1.xx += dx; p1.yy += dy; } // ========================================================== // private function drawLine(p1:Particle, p2:Particle):void { canvas.graphics.lineStyle(1,0x000000); canvas.graphics.moveTo(p1.x, p1.y); canvas.graphics.lineTo(p2.x, p2.y); } // ========================================================== // } } // ***** [ Particle Class ] ***************************************** // import flash.display.Sprite; internal class Particle extends Sprite { public var old_x:Number; public var old_y:Number; public var xx:Number; public var yy:Number; // ========================================================== // public function Particle(_x:int, _y:int):void { x = _x; y = _y; xx = _x; yy = _y; old_x = _x; old_y = _y; graphics.lineStyle(1, 0x000000); graphics.beginFill(0xFFD22B); graphics.drawCircle(0,0,5); graphics.endFill(); } // ========================================================== // } |
![]() |
![]() |
Часовой пояс GMT +4, время: 14:01. |
|
|
« Предыдущая тема | Следующая тема » |
|
|