пересечение прямоугольника с кругом

548 views
Skip to first unread message

Romano

unread,
Dec 20, 2009, 3:52:15 AM12/20/09
to ruF...@googlegroups.com
Есть прямоугольник(с начальными x и y  в центре прямоугольника) и круг, когда круг начинает приближаться к прямоугольнику, скажем на 100px и меньше, то прямоугольник начинает отъезжать от него и уворачиваться. И чтобы это все заработало надо найти пересечение прямоугольник с кругом. Понимаю что надо искать пересечение линий с кругом, но не могу найти формулы, по которым можно найти координаты прямоугольника, т.к. прямоугольник может крутиться вокруг своей оси.

Подскажиет плиз, очень надо :)

Еще был бы благодарен ссылкам на внятные туториалы по box2d.

Valentin Simonov

unread,
Dec 20, 2009, 4:23:45 AM12/20/09
to ruf...@googlegroups.com

Alex Maltsev

unread,
Dec 20, 2009, 4:43:45 AM12/20/09
to ruf...@googlegroups.com
> Понимаю что надо
> искать пересечение линий с кругом,
В книге Джоба Макара Macromedia Flash MX game design demystified
Правдв под AS 1.0
Зато есть на Google.Books
Ссылка на главу Обнаружение пересечения "линия - окружность"
http://books.google.com/books?id=sdfWzPrNx2gC&lpg=PP1&dq=Macromedia%20Flash%20Mx%20Game%20Design%20Demystified&pg=RA1-PA118#v=onepage&q=&f=false

--
Sincerely,
Alex

Romano

unread,
Dec 20, 2009, 4:51:11 AM12/20/09
to ruf...@googlegroups.com


20 декабря 2009 г. 14:43 пользователь Alex Maltsev <maltse...@gmail.com> написал:


Ссылка на главу Обнаружение пересечения "линия - окружность"
http://books.google.com/books?id=sdfWzPrNx2gC&lpg=PP1&dq=Macromedia%20Flash%20Mx%20Game%20Design%20Demystified&pg=RA1-PA118#v=onepage&q=&f=false
Я знаю как определить пересечение линии с окружностью, мне надо координаты точек прямоугольника найти:)

Антон Сидоренко

unread,
Dec 20, 2009, 7:16:06 AM12/20/09
to ruf...@googlegroups.com

> О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫О©╫
> О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫:)
> <http://groups.google.com/group/ruFlash/web/rules>
var spr : Sprite = new Sprite();
spr.graphics.beginFill(0);
spr.graphics.drawCircle(0,0,10);

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);
}

О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫, О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫, О©╫О©╫ О©╫О©╫О©╫О©╫О©╫-О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫:
О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫

О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ (О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫,
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫)


Яски

unread,
Dec 20, 2009, 7:55:17 AM12/20/09
to ruFlash
Привет, Роман

Некоторые геометрические задачи становятся проще при переходе в другую
систему координат. Например, эта задача решается проще в системе
координат относительно прямоугольника.
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;
}

Valentin Simonov

unread,
Dec 20, 2009, 8:07:41 AM12/20/09
to ruf...@googlegroups.com
я для кого линки-то кидал
там написано чуть менее чем все

Яски

unread,
Dec 20, 2009, 8:18:11 AM12/20/09
to ruFlash
Первая ссылка на русском http://noregret.org/tutor/n/collision/
И точно, мой алгоритм не будет работать -- нужны дополнительные
проверки для углов

Яски

unread,
Dec 20, 2009, 9:06:12 AM12/20/09
to ruFlash
Исправленный вариант:
package {

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);
}

}
}

Romano

unread,
Dec 20, 2009, 9:13:35 AM12/20/09
to ruf...@googlegroups.com


20 декабря 2009 г. 19:06 пользователь Яски <xia...@yandex.ru> написал:

ого, почти то что надо :) спасибо :)

Alexander Sergeyev

unread,
Dec 21, 2009, 2:48:26 AM12/21/09
to ruFlash
Правильно говорит Яски, лучший принцип тут - расширить прямоугольник
на радиус окружности, и смотреть на попадание центра окружности в
расширенный прямоугольник.
Реализовать только попроще можно было бы, но это не так важно.
Reply all
Reply to author
Forward
0 new messages