Здравствуйте, сделал столкновение двух правильных многоугольников с помощью теоремы о разделяющих осях. может подскажет кто, как переделать на множество фигур, так как возник вопрос как отслеживать с какой фигурой я хочу столкнуть выбранную фигуру?
function Shape(points, x, y, color, stroke) {
this.x = x || 0;
this.y = y || 0;
this.points = points.map(function (el) {
return {x: el[0], y: el[1]};
});
this.color = color || "rgba(0,0,0,0)";
this.stroke = stroke || "black";
this.getNormals();
this.getMedians();
}
Shape.prototype.draw = function (ctx) {
var p = this.points;
ctx.save();
ctx.fillStyle = this.color;
ctx.strokeStyle = this.stroke;
ctx.lineWidth = 3;
ctx.translate(this.x, this.y);
p.forEach(function (point, i) {
if (i === 0) {
ctx.beginPath();
ctx.moveTo(point.x, point.y);
} else if (i === (p.length - 1)) {
ctx.lineTo(point.x, point.y);
ctx.lineTo(p[0].x, p[0].y);
ctx.stroke();
ctx.fill();
} else {
ctx.lineTo(point.x, point.y);
}
});
ctx.closePath();
ctx.restore();
};
Shape.prototype.getNormals = function () {
var p = this.points,
n = p.length,
crt, nxt, l, x1, y1;
this.normals = [];
for (var i = 0; i < n; i++) {
crt = p[i];
nxt = p[i + 1] || p[0];
x1 = (nxt.y - crt.y);
y1 = -(nxt.x - crt.x);
l = Math.sqrt(x1 * x1 + y1 * y1);
this.normals[i] = {x: x1 / l, y: y1 / l};
this.normals[n + i] = {x: - x1 / l, y: - y1 / l};
}
};
Shape.prototype.getMedians = function () {
var p = this.points,
crt, nxt;
this.medians = [];
for (var i = 0; i < p.length; i++) {
crt = p[i];
nxt = p[i + 1] || p[0];
this.medians.push({x: (crt.x + nxt.x) / 2, y: (crt.y + nxt.y) / 2});
}
};
Shape.prototype.move = function (x, y) {
this.x = x;
this.y = y;
};
Shape.prototype.checkCollision = function (shape) {
var me = this,
p1, p2;
return me.normals.concat(shape.normals).every(function (v) {
p1 = me.project(v);
p2 = shape.project(v);
return (((p1.min <= p2.max) && (p1.max >= p2.min)) ||
(p2.min >= p1.max) && (p2.max >= p1.min));
});
};
Shape.prototype.project = function (vector) {
var me = this,
p = this.points,
min = Infinity, max = -Infinity,
x, y, proj;
p.forEach(function (p) {
x = me.x + p.x;
y = me.y + p.y;
proj = (x * vector.x + y * vector.y);
min = proj < min ? proj : min;
max = proj > max ? proj : max;
});
return {min: min, max: max};
};
var canvas = document.getElementById("scene"),
ctx = canvas.getContext("2d"),
w = window.innerWidth,
h = window.innerHeight,
isDown = false,
list = {
triangle: new Shape([[30, 0], [60, 60], [0, 60]], 50, 50),
rhombus: new Shape([[50, 0], [100, 50], [50, 100], [0, 50]], 200, 50)
},
render = function () {
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, 0, w, h);
for (var shape in list) {
if (list.hasOwnProperty(shape)) {
list[shape].draw(ctx);
}
}
requestAnimationFrame(render);
};
canvas.addEventListener("mousedown", function (e) {
isDown = true;
checkFigures({x: e.clientX, y: e.clientY});
});
canvas.addEventListener("mouseup", function () {
isDown = false;
for (var figure in list) {
list[figure].moving = false;
}
});
canvas.addEventListener("mousemove", function (e) {
var fig;
if (isDown) {
for (var figure in list) {
fig = list[figure];
if (fig.moving) {
fig.move(e.clientX - fig.delta.x, e.clientY - fig.delta.y);
if (list.triangle.checkCollision(list.rhombus)) {
list.triangle.stroke = 'red';
list.rhombus.stroke = 'red';
} else {
list.triangle.stroke = 'black';
list.rhombus.stroke = 'black';
}
}
}
}
});
function checkFigures(mp) {
for (var fig in list) {
if (isPointInPoly(list[fig].points, {x: mp.x - list[fig].x, y: mp.y - list[fig].y})) {
list[fig].moving = true;
list[fig].delta = {
x: mp.x - list[fig].x,
y: mp.y - list[fig].y
};
}
}
}
function isPointInPoly(poly, pt) {
for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
&& (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
&& (c = !c);
return c;
}
canvas.width = w;
canvas.height = h;
requestAnimationFrame(render);
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<canvas id="scene"></canvas>
<script src="Shape.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
</body>
</html>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
ЗдравствуйтеЕсть ли способ, js-ом исключить из выбора или ввода в <input type="date"> определенные дни недели? Т
Создаю своё первое приложение на nwjs
Есть форма, в нее пользователь вписывает данные и они сохраняются в localStorage массиве под названием todoДанные вписанные в форму оказываются...
Нужно динамически рендерить элементы в браузереС сервера приходит верстка в юникоде