Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Коллизии, очень неточные Math.sin() Math.cos() (http://www.flasher.ru/forum/showthread.php?t=126206)

wvxvw 13.06.2009 18:09

Коллизии, очень неточные Math.sin() Math.cos()
 
Вот, собственно, вопрос, как бороться? Изза того, что синусы и косинусы считаются недостаточно точно, определение места коллизии тоже получается очень приблизительным.
Пример прилагается:
Код AS3:

package com.ayumilove.map 
{
        //{imports
        import flash.geom.Point;
        import flash.geom.Rectangle;
        import flash.utils.Dictionary;
        //}
 
        /**
        * Surface class.
        * @author wvxvw
        * @langVersion 3.0
        * @playerVersion 10.0.12.36
        */

        public class Surface
        {
                //--------------------------------------------------------------------------
                //
                //  Public properties
                //
                //--------------------------------------------------------------------------
 
                //--------------------------------------------------------------------------
                //
                //  Protected properties
                //
                //--------------------------------------------------------------------------
 
                protected var _right:Point;
                protected var _left:Point;
                protected var _top:Point;
                protected var _bottom:Point;
 
                protected var _angle:Number;
                protected var _cos:Number;
                protected var _sin:Number;
                protected var _tan:Number;
                protected var _atan:Number;
                protected var _acos:Number;
                protected var _asin:Number;
                protected var _lineRect:Rectangle;
 
                //--------------------------------------------------------------------------
                //
                //  Private properties
                //
                //--------------------------------------------------------------------------
 
                //--------------------------------------------------------------------------
                //
                //  Constructor
                //
                //--------------------------------------------------------------------------
                public function Surface(left:Point, right:Point)
                {
                        super();
                        _left = left.clone();
                        _right = right.clone();
                        var tempTop:Number = Math.min(_right.y, _left.y);
                        var tempLeft:Number = Math.min(_right.x, _left.x);
                        var tempBottom:Number = Math.max(_right.y, _left.y);
                        var tempRight:Number = Math.max(_right.x, _left.x);
                        _top = new Point(tempLeft, tempTop);
                        _bottom = new Point(tempRight, tempBottom);
                        var x:Number = tempBottom - tempTop;
                        var y:Number = tempRight - tempLeft;
                        _angle = Math.atan2(x, y);
                        _cos = Math.cos(_angle);
                        _sin = Math.sin(_angle);
                        _tan = Math.tan(_angle);
                        _tan = Math.atan(_angle);
                        _acos = Math.acos(_angle);
                        _asin = Math.asin(_angle);
                        trace(_asin, _acos, _atan, _tan, _sin, _cos);
                        trace(_angle * 180 / Math.PI);
                        _lineRect = new Rectangle();
                        _lineRect.top = tempTop;
                        _lineRect.left = tempLeft;
                        _lineRect.bottom = tempBottom;
                        _lineRect.right = tempRight;
                }
 
                //--------------------------------------------------------------------------
                //
                //  Public methods
                //
                //--------------------------------------------------------------------------
 
                public function right():Point { return _right.clone(); }
 
                public function left():Point { return _left.clone(); }
 
                public function top():Point { return _top.clone(); }
 
                public function bottom():Point { return _bottom.clone(); }
 
                public function angle():Number { return _angle; }
 
                public function lineRect():Rectangle { return _lineRect.clone(); }
 
                public function intersects(rect:Rectangle):Boolean
                {
                        if (!rect.intersects(_lineRect)) return false;
                        var cornerPoints:Dictionary = new Dictionary();
                        cornerPoints[new Point(rect.top, rect.left)] = 1;
                        cornerPoints[new Point(rect.top, rect.right)] = 2;
                        cornerPoints[new Point(rect.bottom, rect.left)] = 3;
                        cornerPoints[new Point(rect.bottom, rect.right)] = 4;
                        var lineTop:Point = top();
                        var h:Number;
                        var w:Number;
                        var d:Number;
                        var p:Point;
                        for (var po:Object in cornerPoints)
                        {
                                p = po as Point;
                                w = Math.max(lineTop.x, p.x) - Math.min(lineTop.x, p.x);
                                h = Math.max(lineTop.y, p.y) - Math.min(lineTop.y, p.y);
                                d = Math.sqrt(h * h + w * w);
                                p.x = lineTop.x + _cos * d;
                                p.y = lineTop.y + _sin * d;
                                if (rect.containsPoint(p)) return true;
                        }
                        return false;
                }
 
                public function collisionPoints(rect:Rectangle):Array
                {
                        var topY:Number = Math.max(top().y, rect.top);
                        var bottomY:Number = Math.min(bottom().y, rect.bottom);
                        var d1:Number = (topY - top().y) / _sin;
                        var d2:Number = (bottomY - top().y) / _sin;
                        var topX:Number = top().x + d1 * _cos;
                        var bottomX:Number = top().x + d2 * _cos;
                        var p1:Point = new Point(topX, topY);
                        var p2:Point = new Point(bottomX, bottomY);
                        if (!rect.containsPoint(p1))
                        {
                                p1.x = rect.left;
                                d1 = (p1.x - top().x) / _cos;
                                p1.y = top().y + d1 * _sin;
                        }
                        var p2Clone:Point = p2.clone();
                        p2Clone.x = p2.x - 1;
                        p2Clone.y = p2.y - 1;
                        if (!rect.containsPoint(p2Clone))
                        {
                                p2.x = rect.right;
                                d1 = (p2.x - top().x) / _cos;
                                p2.y = top().y + d1 * _sin;
                        }
                        return [p1, p2];
                }
 
                //--------------------------------------------------------------------------
                //
                //  Protected methods
                //
                //--------------------------------------------------------------------------
 
                //--------------------------------------------------------------------------
                //
                //  Private methods
                //
                //--------------------------------------------------------------------------
        }
 
}

EDIT: Упс, прошу прощения, неправильно посчитал :(


Часовой пояс GMT +4, время: 14:36.

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