gpt4 book ai didi

javascript - 两个旋转元素之间的碰撞

转载 作者:行者123 更新时间:2023-11-29 16:45:50 25 4
gpt4 key购买 nike

var keys = new Array();
var direction;
var direction;
var iNr = 0;

$(document).ready(function(){
looper();
$("#demo1").css("margin-top", 400 + "px");
$("#demo2").css("margin-left", 380 + "px");
myFunction();
});

function myFunction()
{
iNr = iNr + 0.5;
$("#main").css("transition","all 0.1s");
$("#main").css("transform","rotate(" + iNr + "deg)");


setTimeout(function()
{
myFunction();
}, 50);

}

function looper()
{
var p =$("#circle");
var offset = p.offset();
var t =$(".red");
var roffset = t.offset();

var rect1 = {x: offset.left, y: offset.top, width: p.width(), height: p.height()}
var rect2 = {x: roffset.left, y: roffset.top, width: t.width(), height: t.height()}

if (rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x && rect1.y < rect2.y + rect2.height && rect1.height + rect1.y > rect2.y) {

console.log("now");
}

if(direction == "left")
{
if(offset.left - 50 > 0)
{
$("#circle").css("left", ($("#circle").position().left - 2) + "px");
}
}
if(direction == "up")
{
if(offset.top - 50 > 0)
{
$("#circle").css("top", ($("#circle").position().top - 2) + "px");
}
}
if(direction == "right")
{
if((offset.left + 50) < $(window).width())
{
$("#circle").css("left", ($("#circle").position().left + 2) + "px");
}
}
if(direction == "down")
{
if((offset.top + 50) < $(window).height())
{
$("#circle").css("top", ($("#circle").position().top + 2) + "px");
}
}



ID=window.setTimeout("looper();", 1);
}


$(document).keyup(function(event) {

if (event.keyCode == 37)
{
var index = keys.indexOf("37");
keys.splice(index, 1);
direction = "";
}
if (event.keyCode == 38)
{
var index = keys.indexOf("38");
keys.splice(index, 1);
direction = "";
}
if (event.keyCode == 39)
{
var index = keys.indexOf("39");
keys.splice(index, 1);
direction = "";
}
if (event.keyCode == 40)
{
var index = keys.indexOf("40");
keys.splice(index, 1);
direction = "";
}
});

$(document).keydown(function(event) {

if (event.keyCode == 37)
{
keys.push("37");
direction = "left";
}
if (event.keyCode == 38)
{
keys.push("38");
direction = "up";
}
if (event.keyCode == 39)
{
keys.push("39");
direction = "right";
}
if (event.keyCode == 40)
{
keys.push("40");
direction = "down";
}
});
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>test</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

</head>


<body style="background-color:black; overflow-y:scroll;">

<div style="width:400px; margin-left:500px; height:400px;" id="main">
<div id="demo1" style="width:400px; height:20px; background-color:red; position:absolute;" class="red test all"></div>
<div id="demo2" style="width:20px; height:400px; background-color:yellow; position:absolute;" class="test all"></div>
<div id="demo3" style="width:400px; height:20px; background-color:blue; position:absolute;" class="test all"></div>
<div id="demo4" style="width:20px; height:400px; background-color:green; position:absolute;" class="test all"></div>
</div>

<div style="width:25px; height:25px; background-color:white; position:absolute; border-radius:50%;" id="circle"></div>

</body>
</html>

我编写了一个游戏。在这个游戏中,我的函数检查 div1div2 之间是否存在碰撞。或者如果它们是重叠的……你想怎么拼写。没有轮换一切正常。

但是现在我遇到了一个问题。我想用 transform:rotate(Xdeg);

旋转 div2

但如果我这样做,我的碰撞计算就不起作用了。

我用这个:

var rect1 = {x: 5, y: 5, width: 50, height: 50}
var rect2 = {x: 20, y: 10, width: 10, height: 10}

if (rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x && rect1.y < rect2.y + rect2.height && rect1.height + rect1.y > rect2.y) {
// collision detected!
}

你有解决这个问题的想法吗?

感谢您的帮助:-)

最佳答案

有几种方法可以做到这一点。这个例子只是指导你如何用矩形完成它。

这些是这里完成的步骤:

  • 您必须计算要检查它们是否发生碰撞的所有矩形的所有旋转 Angular 的位置。要获得这些旋转的 Angular ,您可以使用多种方法。在此示例中,使用了 2d 向量和 2d 旋转矩阵:

    • 一个以矩形中心为原点并指向矩形左上角 (x,y) 的矢量:

      var center = {
      x: x + width / 2,
      y: y + height / 2
      };

      var vector = {
      x: (x - center.x),
      y: (y - center.y)
      };
    • 将此向量与旋转矩阵相乘以旋转此向量:

      // modified sin function to calulcate sin in the unit degrees instead of radians
      function sin(x) {
      return Math.sin(x / 180 * Math.PI);
      }

      // modified cos function
      function cos(x) {
      return Math.cos(x / 180 * Math.PI);
      }

      var rotationMatrix = [[cos(angle), -sin(angle)],[sin(angle), cos(angle)]];

      var rotatedVector = {
      x: vector.x * rotationMatrix[0][0] + vector.y * rotationMatrix[0][1],
      y: vector.x * rotationMatrix[1][0] + vector.y * rotationMatrix[1][1]
      };
    • 最后得到旋转后的左上角,你可以从矩形的中心开始,到旋转后的矢量指向的地方。这是旋转后左上角所在的位置:

      {
      x: (center.x + rotatedVector.x),
      y: (center.y + rotatedVector.y)
      }
    • 上述所有步骤均由 getRotatedTopLeftCornerOfRect 完成,并且还必须对所有其他 Angular 完成。前下位置可以计算 Angular 点(右上角) 必须计算指向该 Angular 点的下一个向量。为了获得指向右上角的下一个向量,计算第一个向量(左上)和第二个向量(右上)之间的 Angular 。当第三向量的 Angular 增加第一 Angular 和第二 Angular 时,第三向量指向右下角,第四向量旋转第一、第二和第三 Angular 之和的 Angular 。所有这些都是在 setCorners 方法中完成的,这张图片部分显示了这个过程:

enter image description here


  • 要检测碰撞,有大量的算法。在这个例子中 Point in polygon算法用于检查矩形的每个旋转 Angular 是否有边界或在另一个矩形内,如果是,则方法 isCollided 返回 true。 pointInPoly 中使用了 Point in polygon 算法,也可以在 here 中找到.

组合上述所有步骤很棘手,但它适用于各种尺寸的所有矩形,最重要的是您可以在没有库的情况下通过单击“运行代码片段”在此处对其进行测试。

(测试的浏览器:FF 50.1.0,IE:10-EDGE,Chrome:55.0.2883.87 m):

    var Rectangle = (function () {

function sin(x) {
return Math.sin(x / 180 * Math.PI);
}

function cos(x) {
return Math.cos(x / 180 * Math.PI);
}

function getVectorLength(x, y, width, height){
var center = {
x: x + width / 2,
y: y + height / 2
};
//console.log('center: ',center);
var vector = {
x: (x - center.x),
y: (y - center.y)
};
return Math.sqrt(vector.x*vector.x+vector.y*vector.y);
}

function getRotatedTopLeftCornerOfRect(x, y, width, height, angle) {
var center = {
x: x + width / 2,
y: y + height / 2
};
//console.log('center: ',center);
var vector = {
x: (x - center.x),
y: (y - center.y)
};
//console.log('vector: ',vector);
var rotationMatrix = [[cos(angle), -sin(angle)],[sin(angle), cos(angle)]];
//console.log('rotationMatrix: ',rotationMatrix);
var rotatedVector = {
x: vector.x * rotationMatrix[0][0] + vector.y * rotationMatrix[0][1],
y: vector.x * rotationMatrix[1][0] + vector.y * rotationMatrix[1][1]
};
//console.log('rotatedVector: ',rotatedVector);
return {
x: (center.x + rotatedVector.x),
y: (center.y + rotatedVector.y)
};
}

function getOffset(el) {
var _x = 0;
var _y = 0;
while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return {
top: _y,
left: _x
};
}

function pointInPoly(verties, testx, testy) {
var i,
j,
c = 0
nvert = verties.length;
for (i = 0, j = nvert - 1; i < nvert; j = i++) {
if (((verties[i].y > testy) != (verties[j].y > testy)) && (testx < (verties[j].x - verties[i].x) * (testy - verties[i].y) / (verties[j].y - verties[i].y) + verties[i].x))
c = !c;
}
return c;
}

function Rectangle(htmlElement, width, height, angle) {
this.htmlElement = htmlElement;
this.width = width;
this.height = height;
this.setCorners(angle);
}

function testCollision(rectangle) {
var collision = false;
this.getCorners().forEach(function (corner) {
var isCollided = pointInPoly(rectangle.getCorners(), corner.x, corner.y);
if (isCollided) collision = true;
});
return collision;
}

function checkRectangleCollision(rect, rect2) {
if (testCollision.call(rect, rect2)) return true;
else if (testCollision.call(rect2, rect)) return true;
return false;
}

function getAngleForNextCorner(anc,vectorLength) {
var alpha = Math.acos(anc/vectorLength)*(180 / Math.PI);
return 180 - alpha*2;
}

Rectangle.prototype.setCorners = function (angle) {
this.originalPos = getOffset(this.htmlElement);
this.leftTopCorner = getRotatedTopLeftCornerOfRect(this.originalPos.left, this.originalPos.top, this.width, this.height, angle);

var vecLength = getVectorLength(this.originalPos.left, this.originalPos.top, this.width, this.height);
//console.log('vecLength: ',vecLength);

angle = angle+getAngleForNextCorner(this.width/2, vecLength);
//console.log('angle: ',angle);
this.rightTopCorner = getRotatedTopLeftCornerOfRect(this.originalPos.left, this.originalPos.top, this.width, this.height, angle);

angle = angle+getAngleForNextCorner(this.height/2, vecLength);
//console.log('angle: ',angle);
this.rightBottomCorner = getRotatedTopLeftCornerOfRect(this.originalPos.left, this.originalPos.top, this.width, this.height, angle);

angle = angle+getAngleForNextCorner(this.width/2, vecLength);
//console.log('angle: ',angle);
this.leftBottomCorner = getRotatedTopLeftCornerOfRect(this.originalPos.left, this.originalPos.top, this.width, this.height, angle);

//console.log(this);
};

Rectangle.prototype.getCorners = function () {
return [this.leftTopCorner,
this.rightTopCorner,
this.rightBottomCorner,
this.leftBottomCorner];
};

Rectangle.prototype.isCollided = function (rectangle) {
return checkRectangleCollision(this, rectangle);
};

return Rectangle;

}) ();


var rotA = 16;
var widthA = 150;
var heightA = 75;
var htmlRectA = document.getElementById('rectA');

var rotB = 28.9;
var widthB = 50;
var heightB = 130;
var htmlRectB = document.getElementById('rectB');

var msgDiv = document.getElementById('msg');

var rectA = new Rectangle(htmlRectA, widthA, heightA, rotA);
var rectB = new Rectangle(htmlRectB, widthB, heightB, rotB);

window.requestAnimFrame = function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame;
}();

function draw(){

rotA+=1.2;
htmlRectA.setAttribute('style','-ms-transform: rotate('+rotA+'deg);-webkit-transform: rotate('+rotA+'deg);transform: rotate('+rotA+'deg)');

rotB+=5.5;
htmlRectB.setAttribute('style','-ms-transform: rotate('+rotB+'deg);-webkit-transform: rotate('+rotB+'deg);transform: rotate('+rotB+'deg)');

rectA.setCorners(rotA);
rectB.setCorners(rotB);

if(rectA.isCollided(rectB)){
msgDiv.innerHTML = 'Collision detected!';
msgDiv.setAttribute('style','color: #FF0000');
}
else {
msgDiv.innerHTML = 'No Collision!';
msgDiv.setAttribute('style','color: #000000');
}

setTimeout(function(){
window.requestAnimFrame(draw);
},50);
}

window.requestAnimFrame(draw);
#rectA{
background-color: #0000FF;
width:150px;
height:75px;
position:absolute;

top:60px;
left:180px;

-ms-transform: rotate(16deg);
-webkit-transform: rotate(16deg);
transform: rotate(16deg);
}

#rectB{
background-color: #FF0000;
width:50px;
height:130px;
position:absolute;

top:140px;
left:250px;

-ms-transform: rotate(28.9deg);
-webkit-transform: rotate(28.9deg);
transform: rotate(28.9deg);

}
<div id="rectA">A</div>
<div id="rectB">B</div>

<div id="msg"></div>

关于javascript - 两个旋转元素之间的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41489627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com