Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Пишу Ragdoll (http://www.flasher.ru/forum/showthread.php?t=116009)

Crash512 19.09.2008 16:33

Ну.. Просвети пожалуйста, что такое LCP...=) Статья на английском... Это конечно не критично, но требует в несколько раз больше времени для освоения=(

mikleb 19.09.2008 16:50

Ну есть два подхода, первый элементарный и неточный это Верлетовский (position based). Второй намного точнее и использующийся во всех нормальных движках (например в box2d) это - импульсный подход. Там как раз вылезает LCP задача - Это когда надо найти такие x и y, что Ax+b=y при условии что x*y=0 , x>=0 y>=0. Про это написано например в статьях Michael Cline'а или Миртича, еще на gamedev в сообществах много написано.

divinus 19.09.2008 17:24

вот интересная реализация рагдол... ) http://www.salex.ru/fun/falling-girl.php

motor4ik 19.09.2008 18:21

можно вечно смотреть на три вещи:огонь, воду и падающую девушку ))

Crash512 20.09.2008 19:04

В движке Хитмана использовалось интегрирование Верлета для одежды и падающих трупов.. Неточность компенсирует быстродействие=)

Господа! Ну ответьте пожалуйста на вопрос про треугольник... Очень надо... Я ж знаю, кто-то точно в курсе=)

etc 20.09.2008 20:28

Цитата:

Сообщение от Crash512 (Сообщение 765252)
В движке Хитмана использовалось интегрирование Верлета для одежды и падающих трупов.. Неточность компенсирует быстродействие=)

Господа! Ну ответьте пожалуйста на вопрос про треугольник... Очень надо... Я ж знаю, кто-то точно в курсе=)

Если вы думаете, что удаляя свои сообщения и оставляя новое с тем же контентом, вы не получите плюс, то вы ошибаетесь.
Ждите ответа молча.

mikleb 20.09.2008 20:59

Crash512
1) У вас не правильное разрешение ограничений. Нужно двигать обе точки, а не одну из них. На сом деле вам нужно два типа связей первый тип- это связь мышки с партиклом(то что у вас написано именно тот случай), а второй тип - связь партикла с партиклом - там как раз надо обе двигать на 0.5*dp (в случае равных масс).
2)У вас неверная структура "движка". Все внешние силы (например сила тяжести) должны применяться строго до разрешения ограничений в одной и той же функции. Так же разрешение ограничений делается не 1ой итерацией как у вас а несколькими ( в этом и есть основная фишка данного подхода - все быстро сойдется).
3)Нельзя использовать для расчетов x и y координаты спрайта, лучше завести отдельные переменные, а после каждого шага интегрирования приравнивать их.

Вобщем я бы советовал все же прочесть ту статью, и заново все переписать:)

Crash512 21.09.2008 01:08

Спасибо за ответ!=)

Т.е. мне надо проводить интеграцию Верлета не для каждой частицы отдельно, а допустим, загнать все частицы в массив, и использовать цикл с перебором его элементов? При этом, на время разрешения ограничений надо прекращать этот цикл?..

Crash512 21.09.2008 02:56

Вот обновочка... Учёл все замечания. Треугольник выровнялся, но всю верёвку немного клонит влево... Не могу понять, почему..=(

Код:

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();
        }
        // ========================================================== //
}


Герыч 01.05.2009 00:42

Да, добавь переменные xx,yy в класс Particle и все расчёты веди в них, а потом сливай в x и y - все проблемы пропадут!

Добавлено через 19 минут
Вот, это работает:
Код AS3:

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:51.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.