Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 13.06.2009, 18:09
wvxvw вне форума Посмотреть профиль Отправить личное сообщение для wvxvw Найти все сообщения от wvxvw
  № 1  
Ответить с цитированием
wvxvw
Modus ponens
 
Аватар для wvxvw

модератор форума
Регистрация: Jul 2006
Адрес: #1=(list #1#)
Сообщений: 8,049
Записей в блоге: 38
По умолчанию Коллизии, очень неточные 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: Упс, прошу прощения, неправильно посчитал
__________________
Hell is the possibility of sanity


Последний раз редактировалось wvxvw; 13.06.2009 в 18:52.
Создать новую тему Ответ Часовой пояс GMT +4, время: 01:20.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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