--
Sincerely,
Alex
Ссылка на главу Обнаружение пересечения "линия - окружность"
http://books.google.com/books?id=sdfWzPrNx2gC&lpg=PP1&dq=Macromedia%20Flash%20Mx%20Game%20Design%20Demystified&pg=RA1-PA118#v=onepage&q=&f=false
spr.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDownHandler);
spr.x = spr.y = 100;
addChild(spr);
var rectWidth : Number = 100;
var rectHeight : Number = 150;
//О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
var rectRotation : Number = 0;
var shape : Shape = new Shape();
addChild(shape);
stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUpHandler);
function onMouseDownHandler(e : Event) {
stage.addEventListener(Event.ENTER_FRAME,update);
spr.startDrag();
}
function update(e : Event) : void {
rectRotation++;
var a : Point = new Point();
var b : Point = new Point();
var c : Point = new Point();
var d : Point = new Point();
var angleTemp : Number = Math.atan2(rectHeight/2,rectWidth/2);
var angleDifference : Number = Math.PI -angleTemp*2;
var angleA : Number = angleTemp+rectRotation/180*Math.PI;
var angleB : Number = angleA + angleDifference;
var radius : Number =
Math.sqrt(Math.pow(rectHeight/2,2)+Math.pow(rectWidth/2,2));
a.x = spr.x + Math.cos(angleA)*radius;
a.y = spr.y + Math.sin(angleA)*radius;
b.x = spr.x + Math.cos(angleB)*radius;
b.y = spr.y + Math.sin(angleB)*radius;
c.x = spr.x + spr.x-a.x;
c.y = spr.y + spr.y-a.y;
d.x = spr.x + spr.x-b.x;
d.y = spr.y + spr.y-b.y;
shape.graphics.clear();
shape.graphics.beginFill(0xff0000);
shape.graphics.drawCircle(a.x,a.y,2);
shape.graphics.drawCircle(b.x,b.y,2);
shape.graphics.drawCircle(c.x,c.y,2);
shape.graphics.drawCircle(d.x,d.y,2);
}
function onMouseUpHandler(e : Event) {
spr.stopDrag();
stage.removeEventListener(Event.ENTER_FRAME,update);
}
О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫, О©╫О©╫ О©╫О©╫О©╫О©╫О©╫-О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫:
О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ (О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫,
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫)
Некоторые геометрические задачи становятся проще при переходе в другую
систему координат. Например, эта задача решается проще в системе
координат относительно прямоугольника.
http://www.image123.net/apaeclq5fa8ppic.html
Допустим нам известно о прямоугольнике его width, height, x, y и
rotation. О окружности нам известны: circleX, circleY, radius. Нужно
определить не пересекаются ли они:
Сперва переводим их в систему координат относительно прямоугольника --
свойства прямоугольника в новой системе координат будут равны:
x = 0, y = 0, rotation = 0, width и height не изменятся. Остается
только найти центр окружности в новой системе координат, радиус
останется прежним.
dx = circleX - x;
dy = circleY - y;
// Поварачиваем на -rotation
circleX = dx*cos(rotation) + dy*sin(rotation);
circleY = dy*cos(rotation) - dx*sin(rotation);
// В новой системе координат проверка на пересечение очень простая:
halfW = width/2;
halfH = height/2;
if (circleX <= (halfW + radius) && circleX >= -(halfW + radius) &&
circleY <= (halfH + radius) && circleY >= -(halfH + radius)) {
return true;
} else {
return false;
}
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class IntersectionTest extends Sprite {
private var spr:Sprite;
private var shape:Shape;
private var rectRotation:Number = 0;
private var rectWidth : Number = 100;
private var rectHeight : Number = 150;
private var radius:Number = 50;
public function IntersectionTest() {
spr = new Sprite();
spr.graphics.beginFill(0);
spr.graphics.drawCircle(0,0,radius);
spr.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDownHandler);
spr.x = spr.y = 100;
addChild(spr);
shape = new Shape();
redrawRect(0xFF00);
shape.x = 100;
shape.y = 200;
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
private function redrawRect(color:uint):void {
shape.graphics.beginFill(color);
shape.graphics.drawRect(-rectWidth/2, -rectHeight/2, rectWidth,
rectHeight);
addChild(shape);
}
private function onMouseDownHandler(e : Event):void {
stage.addEventListener(Event.ENTER_FRAME,update);
spr.startDrag();
}
private function update(e : Event) : void {
rectRotation++;
shape.rotation = rectRotation;
if (intersect()) {
redrawRect(0xFF0000);
} else {
redrawRect(0xFF00);
}
}
private function intersect():Boolean {
var dx:Number = spr.x - shape.x;
var dy:Number = spr.y - shape.y;
// Поварачиваем на -rotation
var rotation:Number = rectRotation*Math.PI/180;
var circleX:Number = dx*Math.cos(rotation) + dy*Math.sin
(rotation);
var circleY:Number = dy*Math.cos(rotation) - dx*Math.sin
(rotation);
// Фигура симметричная, поэтому проверки можно упростить еще
circleX = (circleX < 0) ? -circleX - rectWidth/2 : circleX -
rectWidth/2;
circleY = (circleY < 0) ? -circleY - rectHeight/2 : circleY -
rectHeight/2;
if (circleX <= 0) {
return circleY <= radius;
} else {
if (circleY <= 0) {
return circleX <= radius;
} else {
// Дополнительная проверка для углов
return (circleX*circleX + circleY*circleY) <= radius*radius;
}
}
}
private function onMouseUpHandler(e : Event):void {
spr.stopDrag();
stage.removeEventListener(Event.ENTER_FRAME,update);
}
}
}