04.12.2012, 21:44
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
Области Вороного
В этой статье http://noregret.org/tutor/n/collision/#2.2 описаны Области Вороного , но как их реализовать не могу найти, может кто подскажет?
Нужно для того что бы определить к какой части многоугольника окружность находиться ближе или проще говоря в какую часть блока летит шарик.
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
05.12.2012, 10:24
|
Аспирант
|
|
Регистрация: 02.12.2012
Сообщений: 30
|
|
Берём для примера прямоугольник. Дальше мы считаем его проекцию на Ох. Она делит эту ось координат на три части: от минус бесконечности до начала проекции, от начала проекции до конца проекции, от конца проекции до плюс бесконечности. Обозначим их, для примера, -1, 0, 1. После этого мы проверяем, какой из частей принадлежит координата X центра окружности. Тоже самое делаем с осью Oy. Итого у нас получается девять возможных комбинаций. В зависимости от каждой из этих комбинаций мы берём нужную точку прямоугольника.
|
|
05.12.2012, 10:55
|
Аспирант
|
|
Регистрация: 02.12.2012
Сообщений: 30
|
|
Вот примерный код, хотя я не тестировал его.
function distance(x1, y1, x2, y2) { // считаем расстояние между двумя точками
return Math.sqrt(Math.power((x2-x1), 2) + Math.power((y2-y1), 2))
}
/*
Проверка на столкновение.
x1, y1 -- координаты левой верхней точки прямоугольника.
x2, y2 -- координаты правой нижней точки прямоугольника.
x, y -- координаты центра окружности
r -- радиус окружности.
*/
function isCollision(x1, y1, x2, y2, x, y, r) {
var compX, compY;
// выбираем точку X прямоугольника, которая ближе всего к центру окружности.
if (x <= x1) { // если X центра слева от проекции на Ox...
compX= x1;
} else if (x < x2) { // ...принадлежит проекции
compX= x;
} else { // ...справа от проекции
compX= x2;
}
// выбираем точку Y прямоугольника, которая ближе всего к центру окружности.
if (y <= y1) { // если y центра слева от проекции на Oy...
compY= y1;
} else if (y < y2) { // ...принадлежит проекции
compY= y;
} else { // ...справа от проекции
compY= y2;
}
return r <= distance(x, y, compX, compY);
}
Последний раз редактировалось schmetterling, 05.12.2012 в 11:41.
|
|
05.12.2012, 14:35
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
schmetterling, спасибо, буду разбираться)
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
05.12.2012, 16:34
|
Аспирант
|
|
Регистрация: 02.12.2012
Сообщений: 30
|
|
Сообщение от cyber
|
schmetterling, спасибо, буду разбираться)
|
Не за что, удачи)
|
|
06.12.2012, 18:42
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
schmetterling, сразу поверхностно глянул на код , а теперь сел дальше мучатся со своим арканоидом, и понял что ваш код в общем работает так же как и мой)
вот из тестового варианта
(y <= Bl_bottom && y >= block.y - ball.R) && (x >= block.x - ball.R && x <= Bl_right)
код ниже это просто черновик
<!DOCTYPE HTML>
<html>
<head> </head>
<body>
<canvas width="500" height="500"></canvas>
<script>
var canva = document.body.children[0];
var ctx = canva.getContext("2d");
var ball = {
x:20,
y:280,
R:20,
Draw: function (x, y) {
ctx.clearRect(this.x - this.R, this.y - this.R, this.R *2,this.R *2);
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(x,y, this.R,0, (Math.PI / 180)* 360, false);
ctx.fill();
this.y = y;
this.x = x;
}
};
var block = {
width:150,
height:30,
Draw: function (x, y) {
ctx.beginPath();
ctx.fillStyle = "green";
ctx.fillRect(x,y,this.width, this.height);
this.y = y;
this.x = x;
}
};
block.Draw(150,100);
var valX = -10 , valY = -10;
var Bl_bottom = block.y + block.height + ball.R ;
var Bl_right = block.x + block.width + ball.R ;
var one = false;
function action(){
if(ball.x < 0 + ball.R || ball.x > canva.width - ball.R){
valX = -valX;
};
if(ball.y < 0 + ball.R || ball.y > canva.height - ball.R){
valY = -valY;
//y = canva.height - ball.R;
}
var x = ball.x;
var y = ball.y ;
if((y <= Bl_bottom && y >= block.y - ball.R) && (x >= block.x - ball.R && x <= Bl_right)){
if(!one) drawOs(x,y);
if(!one){// запускаем еще один мячик
ball.x = 200;
ball.y = 200;
action();
one = true;
}
return;
};
x += valX;
y += valY;
ball.Draw(x,y);
setTimeout(action,1000/60);
};
action();
function drawOs(x,y){
ctx.beginPath();
ctx.moveTo(block.x - ball.R ,Bl_bottom);
ctx.lineTo(x,y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(Bl_right ,Bl_bottom);
ctx.lineTo(x,y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(block.x - ball.R,block.y - ball.R);
ctx.lineTo(x,y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(Bl_right,block.y - ball.R );
ctx.lineTo(x,y);
ctx.stroke();
};
</script>
</body>
</html>
проблема в столкновение с углом, в примере выше видно что если сталкивается не с углом все работает.
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
06.12.2012, 20:02
|
Аспирант
|
|
Регистрация: 02.12.2012
Сообщений: 30
|
|
Вот картинка, тут понятно, что идёт не так)
|
|
07.12.2012, 01:08
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
schmetterling,я и так это понял
и вообще уже знаю как поправить, просто показал если кто то будет писать арканоид и будет читать эту тему и мучатся)
вот так должен выглядить блок
<!DOCTYPE HTML>
<html>
<head> </head>
<body>
<canvas width="500" height="500"></canvas>
<script>
var canva = document.body.children[0];
var ctx = canva.getContext("2d");
var block = {
width:150,
height:30,
Draw: function (x, y) {
ctx.beginPath();
ctx.fillStyle = "green";
ctx.fillRect(x,y,this.width, this.height);
this.y = y;
this.x = x;
boundary();
}
};
block.Draw(150,100);
function boundary() {
var rad = 20;
ctx.beginPath();
ctx.moveTo(block.x,block.y - rad);
ctx.lineTo(block.x + block.width , block.y - rad);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(block.x+ block.width + rad,block.y);
ctx.lineTo(block.x+ block.width + rad , block.y + block.height);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(block.x, block.y + block.height + rad);
ctx.lineTo(block.x + block.width , block.y + block.height + rad);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(block.x- rad,block.y);
ctx.lineTo(block.x - rad , block.y + block.height);
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.moveTo(block.x,block.y);
ctx.arc(block.x,block.y, rad,(Math.PI / 180)* -90, (Math.PI / 180)* -180, true);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.moveTo(block.x +block.width,block.y);
ctx.arc(block.x +block.width, block.y, rad,(Math.PI / 180)* -90, (Math.PI / 180)* 0, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.moveTo(block.x + block.width, block.y + block.height);
ctx.arc(block.x + block.width, block.y + block.height, rad,(Math.PI / 180)* 0, (Math.PI / 180)* 90, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.moveTo(block.x ,block.y + block.height);
ctx.arc(block.x ,block.y + block.height, rad,(Math.PI / 180)* 180, (Math.PI / 180)* 90, true);
ctx.fill();
}
</script>
</body>
</html>
но я так и не понял раз 15 перечитывал коммент canvas и метод arc как правильно определить окружность ...
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
07.12.2012, 01:14
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
просто не пойму фишки кода не увеличиваю блок на радиус шарик вроде нормально входит в угол, но наверно просто так кажется ...
<!DOCTYPE HTML>
<html>
<head> </head>
<body>
<canvas width="500" height="500"></canvas>
<script>
var canva = document.body.children[0];
var ctx = canva.getContext("2d");
var ball = {
x:20,
y:280,
R:20,
Draw: function (x, y) {
ctx.clearRect(this.x - this.R, this.y - this.R, this.R *2,this.R *2);
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(x,y, this.R,0, (Math.PI / 180)* 360, false);
ctx.fill();
this.y = y;
this.x = x;
}
};
var block = {
width:150,
height:30,
Draw: function (x, y) {
ctx.beginPath();
ctx.fillStyle = "green";
ctx.fillRect(x,y,this.width, this.height);
this.y = y;
this.x = x;
}
};
block.Draw(150,100);
var valX = -10 , valY = -10;
var Bl_bottom = block.y + block.height ;
var Bl_right = block.x + block.width ;
!function action(){
if(ball.x < 0 + ball.R || ball.x > canva.width - ball.R){
valX = -valX;
};
if(ball.y < 0 + ball.R || ball.y > canva.height - ball.R){
valY = -valY;
//y = canva.height - ball.R;
}
var x = ball.x ;
var y = ball.y ;
if((y <= Bl_bottom && y >= block.y ) && (x >= block.x && x <= Bl_right)){
//if(isCollision(block.x ,block.y , Bl_right, Bl_bottom ,x,y, ball.R)){
drawOs(x,y);
return;
};
x = ball.x + valX;
y = ball.y + valY;
ball.Draw(x,y);
setTimeout(action,1000/60);
}();
function drawOs(x,y){
ctx.beginPath();
ctx.moveTo(block.x ,Bl_bottom);
ctx.lineTo(x,y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(Bl_right ,Bl_bottom);
ctx.lineTo(x,y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(block.x ,block.y );
ctx.lineTo(x,y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(Bl_right,block.y );
ctx.lineTo(x,y);
ctx.stroke();
};
function distance(x1,y1,x2,y2){
return Math.sqrt(Math.pow(x2-x1,2) + Math.pow(y2-y1,2));
};
</script>
</body>
</html>
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
07.12.2012, 01:18
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
кажеться понял, но разберусь уже завтра)
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
|
|