【发布时间】:2013-08-14 17:20:26
【问题描述】:
如果给定一个n 边的多边形和一条长度为k 的线(在x,y 和角度a),是否有一种算法可以检测我有多边形的哪一侧(如果有)与相撞?到目前为止,我已经求助于测试x,y 是否在多边形之外,然后遍历多边形的每个边缘,计算到每一端的距离。这是一个JS Fiddle,展示了我创造的世界。
这里是 JavaScript(HTML 和 CSS 并不值得复制):
var eventLoop,
maxVelocity = 10,
agility = 5,
baseLength = 5,
degree = ((2*Math.PI)/360),
world = document.getElementById('world'),
context = world.getContext("2d"),
boundry = [[180, 120],[240, 60],[360, 40],[420, 120],[360, 220],[350, 240],[360, 265],[470,360],[450,480],[360,540],[240,550],[140,480],[120,470],[100,360],[120,300],[220,240],[240,220]],
camera = {
location: {
x:300,
y:90
},
angle: 0,
velocity: 0
},
engine = {
drawWorld: function(shape, context) {
var point,
index,
size = shape.length;
context.clearRect(0, 0, world.width, world.height);
context.beginPath();
for(index = 0; index < size; index++) {
point = shape[index];
if(index == 0) {
context.moveTo(point[0], point[1]);
} else {
context.lineTo(point[0], point[1]);
}
}
context.closePath();
context.stroke();
},
drawCamera: function(camera, context) {
var a = camera.location,
b = this.calcNextPoint(camera, 1);
context.beginPath();
context.moveTo(a.x, a.y);
context.lineTo(b.x, b.y);
context.stroke();
context.beginPath();
context.arc(a.x, a.y, baseLength, 0, Math.PI*2, true);
context.closePath();
context.stroke();
},
calcNextPoint: function(camera, moment) {
return {
x: camera.location.x + ((camera.velocity*(1/moment))*Math.sin(camera.angle)),
y: camera.location.y + ((camera.velocity*(1/moment))*(Math.cos(camera.angle)))
};
},
isInside: function(point, shape) {
var i, j, c = 0;
for (i = 0, j = shape.length - 1; i < shape.length; j = i++) {
if (((shape[i][1] > point.y) != (shape[j][1] > point.y)) && (point.x < (shape[j][0] - shape[i][0]) * (point.y - shape[i][1]) / (shape[j][1] - shape[i][1]) + shape[i][0])) {
c = !c;
}
}
return c;
}
};
document.onkeydown = function(e) {
e = e || window.event;
if (e.keyCode == '37') {
// left arrow
camera.angle += degree*agility;
}
else if (e.keyCode == '39') {
// right arrow
camera.angle -= degree*agility;
}
else if (e.keyCode == '38') {
// up arrow
camera.velocity += 1;
if(camera.velocity > maxVelocity) {
camera.velocity = maxVelocity;
}
}
else if (e.keyCode == '40') {
// down arrow
camera.velocity -= 1;
if(camera.velocity < 0) {
camera.velocity = 0;
}
}
}
engine.drawWorld(boundry, context);
engine.drawCamera(camera, context);
eventLoop = setInterval(function() {
engine.drawWorld(boundry, context);
engine.drawCamera(camera, context);
if(engine.isInside(camera.location, boundry)) {
camera.location = engine.calcNextPoint(camera, 1);
}
}, 100);
我一直在玩弄一些 JavaScript 来模拟 ThatGameComapny 的游戏 Flower 的 2-Dementional 版本,最终我想尝试实现一个 Oculus Rift 版本。我要解决的下一个问题是,一旦玩家与边缘发生碰撞,就将其转回多边形。
【问题讨论】:
-
我建议你使用带有 d3.js 或 dc.js 的动态 svg,它们会让你非常流畅地使用剪辑路径。
-
我用 JavaScript 编写了这个,因为(对我来说)一个想法更容易破解并与他人分享,但算法的最终实现可能会在 Unity Engine 的脚本框架内,我不知道我是否可以在那个环境中使用 d3.js 或 dc.js。
-
我不知道那个引擎,但如果它支持 javascript 和 svg 元素,那么我 100% 确定你可以使用 d3.js。试试看!如果没有其他东西对你有用。
-
多边形是凸的吗?
-
为了解决最困难的用例,我构建的多边形是凸的。至少它不会像莫比乌斯带那样封闭自己:) jsfiddle 有我正在使用的多边形。
标签: javascript algorithm collision-detection computational-geometry polygons