如何在纯JavaScript中检查两个元素是否相交?

4

I have code like this:

$(function() {
  var $selection = $('.selection');
  $('li').filter(function() {
    var self = $(this);
    return /* ????? */;
  }).addClass('selected');
});
.widget {
  width: 320px;
  height: 200px;
  border: 1px solid gray;
  position: absolute;
  overflow: scroll;
}
.selection {
  position: absolute;
  top: 90px;
  left: 90px;
  border: 1px dotted black;
  height: 120px;
  width: 120px;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
li {
  float: left;
  background: blue;
  width: 40px;
  height: 40px;
  margin: 10px;
}
li.selected {
  background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="widget">
  <div class="selection"></div>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

我该如何选择与.selection矩形相交的li元素?

https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection - Rayon
我投票要重新打开这个问题,因为我认为它与被标记为重复的问题有足够的不同之处。 - Greg
2个回答

11

使用标准的DOM技术,您可以对每个LI元素进行迭代,并获得一个边界矩形,其中包含LI矩形的坐标。

同样地,对于选择矩形也是如此,然后您可以简单地检查这些坐标是否在选择范围内。

Element.getBoundingClientRect()

Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。

返回值是一个DOMRect对象,该对象是与元素相关的CSS border-box的getClientRects()返回的矩形的并集。

返回值是一个DOMRect对象,包含只读的left、top、right、bottom、x、y、width、height属性来描述边框盒(border-box)的像素。宽度和高度之外的属性都是相对于视口左上角的。

请参见以下编辑后的代码,该代码选择了完全包含或部分交叉选择的LI元素。

var selection = document.querySelector(".selection");
var rectSelection = selection.getBoundingClientRect();

// Iterate over all LI elements.
[].forEach.call(document.querySelectorAll("li"), function(li) {
    var rect = li.getBoundingClientRect();

    if(rect.bottom > rectSelection.top 
    && rect.right > rectSelection.left 
    && rect.top < rectSelection.bottom 
    && rect.left < rectSelection.right) {
        li.classList.add("selected");
    }
});
.widget {
  width: 320px;
  height: 200px;
  border: 1px solid gray;
  position: absolute;
  overflow: scroll;
}
.selection {
  position: absolute;
  top: 90px;
  left: 90px;
  border: 1px dotted black;
  height: 120px;
  width: 120px;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
li {
  float: left;
  background: blue;
  width: 40px;
  height: 40px;
  margin: 10px;
}
li.selected {
  background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="widget">
  <div class="selection"></div>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>


使用更新版本工作更有效率 ;) - Arthur
@Arthur 是的,我注意到我之前只选中了完全包含的方块,而没有选择相交的方块。我希望这正是您所需要的。 - Greg
这可以是您函数的一个选项...可能很有趣。red在大正方形上,而绿色则刚好碰撞。 - Arthur
如果我们使用相反的边来代替添加/减去宽度/高度,是否会得到相同的结果呢?像这样:rect.bottom > rectSelection.top && rect.right > rectSelection.left && rect.top < rectSelection.bottom && rect.left < rectSelection.right。这样写更易于阅读。 - H K
@HK 这是一个可爱简单的解决方案 - 我会更新答案 :) - Greg

4
了解盒子碰撞的概念 原始答案

如果您必须检查带有旋转的2个矩形,则必须在其他矩形的轴上对矩形角进行投影。 如果矩形1的所有投影都击中矩形2,并且矩形2的投影击中矩形1,则两个矩形相互碰撞。

这里有些投影不会相互碰撞,两个矩形不会相互碰撞。 enter image description here

4个投影都会击中另一个矩形,两个矩形相互碰撞。 enter image description here

我制作了这个 CodePen 的演示文稿,以便更好地理解。

Clone of the code here (it's old and durty, don't be rude it's just to display.. don't look the code to much :p)

function merge_object(obj1, obj2){
    var obj3 = {};
    for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
    for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
    return obj3;
};
/** 
 * Transforme degrees to radians
 */
Math.radians = function(degrees) {
    return degrees * Math.PI / 180;
};
Math.degrees = function(radians) {
  return radians * 180 / Math.PI;
};

/**
 * Square Javascript File
 *
 * -- Changelog
 * Version 1.0.0 (11/05/2013) AGE
 * - Début du versionnement
 *
 * @package js
 * @author AGE
 * @version 1.0.0
 */

// App Object
var collide = {
    
    // Define
    PROJECT_ID : 'collide',
    PROJECT_SPEED : 50, // FPS : 1000/PROJECT_SPEED
    
    FIXED_SQUARE_SIZE : 100,
    FIXED_SQUARE_X : 250,
    FIXED_SQUARE_Y : 250,
    
    CURSOR_SQUARE_SIZE : 50,
        
    // Attribute
    $el : null,
    $ctx : null,
    project_pos_top : null,
    project_pos_left : null,
    width : null,
    height : null,
    
    cursor_x : 0,
    cursor_y : 0,
    
    fixed_angle : 0,
    fixed_rotaton_speed : null,
    cursor_angle : 0,
    cursor_rotaton_speed : null,
     
    draw_approx : true, 
    fixed_projections : {},
    cursor_projections : {},
        
    /**
     * Init Square Game
     */
    __init : function( options ){
        
        // Get element and informations
        collide.$el = $('#' + collide.PROJECT_ID);
        collide.$ctx = collide.$el[0].getContext('2d');
        
        var offset = collide.$el.offset();
        collide.project_pos_top = offset.top;
        collide.project_pos_left = offset.left;
        collide.width = collide.$el.width();
        collide.height = collide.$el.height();
        
        // Events on Move
        collide.$el.mousemove(function(e){
            // Calculate new position
            collide.cursor_x = e.pageX - collide.project_pos_left;           
            collide.cursor_y = e.pageY - collide.project_pos_top;           
        });
        
        $('#cursor_set_angle').change(function(){
            collide.cursor_angle = parseInt($(this).val());
        });
        $('#fixed_set_angle').change(function(){
            collide.fixed_angle = parseInt($(this).val());
        });
        
        // Run the project
        collide.run();
    },
    
    /**
     * Run the project
     */
    run : function(){
                
        // Reset HTML
        $('.corners, .functions, .projections').remove();
        
        // Get 2 angles rotation speed
        collide.fixed_rotaton_speed = parseInt($('#fixed_rotation_speed').val());
        collide.cursor_rotaton_speed = parseInt($('#cursor_rotation_speed').val());
                                
        // Upadte rotation
        collide.fixed_angle = collide.fixed_angle+collide.fixed_rotaton_speed;  
        if(collide.fixed_angle > 360) {collide.fixed_angle -= 360}; 
        if(collide.fixed_angle < 0) {collide.fixed_angle += 360};             
        $('#fixed_angle').val(collide.fixed_angle);

        collide.cursor_angle = collide.cursor_angle+collide.cursor_rotaton_speed;  
        if(collide.cursor_angle > 360) {collide.cursor_angle -= 360}; 
        if(collide.cursor_angle < 0) {collide.cursor_angle += 360}; 
        $('#cursor_angle').val(collide.cursor_angle);

        // Approx Collide
        if(collide.is_approx_collide()){
            
            collide.draw_approx = false;
            
            // Get corners
            var fixer_corner = collide.get_corners(
                collide.FIXED_SQUARE_X,  collide.FIXED_SQUARE_Y, 
                collide.FIXED_SQUARE_SIZE, collide.fixed_angle);
            var cursor_corner = collide.get_corners(
                collide.cursor_x, collide.cursor_y, 
                collide.CURSOR_SQUARE_SIZE, collide.cursor_angle);
                
                
            // Get projections
                // CURSOR on FIXED.X && FIXED.Y
            collide.cursor_projections = collide.get_projections(
                collide.FIXED_SQUARE_X,  collide.FIXED_SQUARE_Y,
                collide.fixed_angle,cursor_corner);  
                // FIXED on CURSOR.X && CURSOR.Y
            collide.fixed_projections = collide.get_projections(
                collide.cursor_x,  collide.cursor_y,
                collide.cursor_angle, fixer_corner);  
                      
        }else{
            collide.draw_approx = true;
        }
        
        collide.draw();
        
        // Re-lauch Run
        setTimeout(function(){
            collide.run();
        }, collide.PROJECT_SPEED);
    },
    
    
    draw : function(){
        // Clear
        collide.$ctx.clearRect(0, 0, collide.width, collide.height);
        collide.$ctx.setTransform(1, 0, 0, 1, 0, 0);
        collide.$ctx.save();
        
        // Draw squares
        collide.draw_square(collide.FIXED_SQUARE_X, collide.FIXED_SQUARE_Y,
            collide.FIXED_SQUARE_SIZE, collide.fixed_angle, '0,0,255');
        
        collide.draw_square(collide.cursor_x, collide.cursor_y,
            collide.CURSOR_SQUARE_SIZE, collide.cursor_angle, '255,128,0');
            
        if(collide.draw_approx){
            
            // Approx 
            collide.draw_approx_square(collide.FIXED_SQUARE_X, collide.FIXED_SQUARE_Y,
                collide.FIXED_SQUARE_SIZE, '0,0,255');

            collide.draw_approx_square(collide.cursor_x, collide.cursor_y,
                collide.CURSOR_SQUARE_SIZE, '255,128,0');
        }   
        else{
            
            // Axes
            collide.draw_axe(collide.FIXED_SQUARE_X, collide.FIXED_SQUARE_Y,
                collide.fixed_angle, '0,0,255');

            collide.draw_axe(collide.cursor_x, collide.cursor_y,
                collide.cursor_angle, '255,128,0');
                
            // Projections
            collide.draw_projections( collide.fixed_projections, '0,0,255');
            collide.draw_projections( collide.cursor_projections, '255,128,0');
            
        }
    },
    draw_square : function(center_x, center_y, size, angle, rgb){
        
        // Is collide ? 
        if(collide.is_approx_collide() && collide.is_collide()){ rgb = "255,0,0"; } 
        
        collide.$ctx.save();
        
        // Draw Fixed square
        collide.$ctx.translate(center_x, center_y);
        collide.$ctx.rotate( Math.radians( angle ) );
        collide.$ctx.fillStyle = 'rgba('+rgb+',.2)';
        collide.$ctx.fillRect(size / -2, size / -2, size, size);
        
        // Draw Corner
        collide.$ctx.translate(size/2, size/2);
        collide.$ctx.beginPath();
        collide.$ctx.fillStyle = 'rgba('+rgb+',1)';
        collide.$ctx.arc(0, 0, 2, 0, Math.PI*2, true); 
        collide.$ctx.closePath();
        collide.$ctx.fill();
        collide.$ctx.translate(-size, 0);
        collide.$ctx.beginPath();
        collide.$ctx.fillStyle = 'rgba('+rgb+',1)';
        collide.$ctx.arc(0, 0, 2, 0, Math.PI*2, true); 
        collide.$ctx.closePath();
        collide.$ctx.fill();
        collide.$ctx.translate(0, -size);
        collide.$ctx.beginPath();
        collide.$ctx.fillStyle = 'rgba('+rgb+',1)';
        collide.$ctx.arc(0, 0, 2, 0, Math.PI*2, true); 
        collide.$ctx.closePath();
        collide.$ctx.fill();
        collide.$ctx.translate(size,0);
        collide.$ctx.beginPath();
        collide.$ctx.fillStyle = 'rgba('+rgb+',1)';
        collide.$ctx.arc(0, 0, 2, 0, Math.PI*2, true); 
        collide.$ctx.closePath();
        collide.$ctx.fill();
        
        collide.$ctx.restore();
    },
    draw_approx_square : function(center_x, center_y, size, rgb){
        
        collide.$ctx.save();
        
        // Draw Fixed square
        collide.$ctx.translate(center_x, center_y);
        collide.$ctx.strokeStyle = 'rgba('+rgb+',1)';
        collide.$ctx.lineWidth = 1;
        collide.$ctx.strokeRect(-size, -size, 2*size, 2*size);
        
        collide.$ctx.restore();        
    },
    draw_axe : function (center_x, center_y, angle, rgb){
        collide.$ctx.save();
        
        collide.$ctx.translate(center_x, center_y);
        collide.$ctx.rotate( Math.radians( angle ) );
        
        collide.$ctx.beginPath();
        collide.$ctx.strokeStyle = 'rgba('+rgb+',1)';
        collide.$ctx.moveTo(-500, 0);
        collide.$ctx.lineTo(500,0);
        collide.$ctx.stroke();
        
        collide.$ctx.restore();
        collide.$ctx.save();
        
        collide.$ctx.translate(center_x, center_y);
        collide.$ctx.rotate( Math.radians( angle+90 ) );
        
        collide.$ctx.beginPath();
        collide.$ctx.strokeStyle = 'rgba('+rgb+',1)';
        collide.$ctx.moveTo(-500,0);
        collide.$ctx.lineTo(500,0);
        collide.$ctx.stroke();
        
        collide.$ctx.restore();  
    },
    draw_projections : function(projections, rgb){
        for(axe in projections){
            for(key in ['min', 'max']){                
                var projection = projections[axe][key==0?"min":"max"];

                collide.$ctx.save();

                collide.$ctx.translate(projection.x, projection.y);
                collide.$ctx.beginPath();
                collide.$ctx.fillStyle = 'rgba('+rgb+',1)';
                collide.$ctx.arc(0, 0, 2, 0, Math.PI*2, true); 
                collide.$ctx.closePath();
                collide.$ctx.fill();  
                
                collide.$ctx.beginPath();
                collide.$ctx.strokeStyle = 'rgba('+rgb+',.2)';
                collide.$ctx.moveTo(00,0);
                collide.$ctx.lineTo(projection.corner.x - projection.x, 
                                    projection.corner.y - projection.y);
                collide.$ctx.stroke();
                collide.$ctx.restore();  
            }
            
            
            collide.$ctx.save();
            
            collide.$ctx.beginPath();
            collide.$ctx.strokeStyle = (projections[axe].is_collide)? 'rgba(255,0,0,1)' : 'rgba('+rgb+',1)'; 
            collide.$ctx.lineWidth = 2;
            collide.$ctx.moveTo(projections[axe].min.x, projections[axe].min.y);
            collide.$ctx.lineTo(projections[axe].max.x,projections[axe].max.y);
            collide.$ctx.stroke();
            
            collide.$ctx.restore(); 
                
            
        }
    },
    
    /**
     * Calculate corners position and draw it
     */    
    get_corners : function(x, y, size, angle){
        var corners = [];
        var radius = parseInt(Math.sqrt(2*size*size)/2);
        
        for(var i_angle=0; i_angle<=270; i_angle+=90){
            var corner = {
                x : parseInt(x + radius * Math.cos(Math.radians(angle + 45 + i_angle) )),
                y : parseInt(y + radius * Math.sin(Math.radians(angle + 45 + i_angle) ))
            };
            corners.push(corner);
        }
        return corners;
    },
    
    /**
     * Calculate square functions and draw it
     */    
    get_functions : function(x, y, size, angle){
        var functions = {
            x : Math.tan(Math.radians( - angle%90)),
            y : Math.tan(Math.radians(90 - angle%90))
        };
        return functions;
    },
    
    get_projections : function(center_x, center_y,angle, corners){
        
        // Genere start Min-Max projection on center of Square
        var projections = {
            "x": {
                'min' : null,
                'max' : null,
                'distance' : null
            },
            "y": {
                'min' : null,
                'max' : null,
                'distance' : null
            }
        };
        
        for(i in corners){
            var corner = corners[i];
            var projection_x = {}, projection_y = {};
            
            /**
             * Global calcul for projection X and Y
             */ 
            
            // Angle 0:horizontale (center > left) 90:verticatale (center > top)
            var angle90 = -(angle%90);
            
            //Distance :
            var distance_corner_center = Math.floor(Math.sqrt((center_x-corner.x)*(center_x-corner.x) + (center_y-corner.y)*(center_y-corner.y)));
            
            // Angle between segment [center-corner] and real axe X (not square axe), must be negative (radius are negative clockwise) 
            var angle_with_axeX = -Math.floor(Math.degrees(Math.atan((corner.y-center_y) / (corner.x-center_x))));  // Tan(alpha) = opposé (ecart sur Y) / adjacent (ecart sur X)
            // If angle is ]0;90[, he is on the 2em et 4th quart of rotation
            if(angle_with_axeX > 0) {angle_with_axeX -= 180;}
            // If corner as upper (so with less pixel on y) thant center, he is on 3th or 4th quart of rotation
            if(corner.y < center_y || (corner.y == center_y && corner.x < center_x) ){angle_with_axeX -= 180;}

            // Calculate difference between 2 angles to know the angle between [center-corner] and Square axe X
            var delta_angle = angle_with_axeX - angle90;
            // If angle is on ]-180;-360], corner are upper than Square axe X, so set a positive angle on [0;180] 
            if(delta_angle < -180){delta_angle += 360;}
            
            /**
             * Projection on X
             */
            
            // Calculate distance between center and projection on axe X
            var distance_center_projection_x = Math.floor(distance_corner_center * Math.cos(Math.radians( delta_angle )));
            
            // Create projection
            projection_x.x = Math.floor(center_x + distance_center_projection_x * Math.cos(Math.radians( -angle90 ))); 
            projection_x.y =  Math.floor(center_y + distance_center_projection_x * Math.sin(Math.radians( -angle90 ))); 
            
            // If is the min ?   
            if(projections.x.min == null
                || distance_center_projection_x < projections.x.min.distance){
            
                projections.x.min = projection_x;
                projections.x.min.distance = distance_center_projection_x;
                projections.x.min.corner = corner;
            }
            // Is the max ?
            if(projections.x.max == null
                || distance_center_projection_x > projections.x.max.distance){
            
                projections.x.max = projection_x;
                projections.x.max.distance = distance_center_projection_x;
                projections.x.max.corner = corner;
            }
            
            /**
             * Projection on Y
             */
           
            // Calculate distance between center and projection on axe Y
            var distance_center_projection_y = Math.floor(distance_corner_center * Math.cos(Math.radians( delta_angle-90 )));
            
            // Create projection
            projection_y.x = Math.floor(center_x + distance_center_projection_y * Math.cos(Math.radians( -angle90 -90 ))); 
            projection_y.y =  Math.floor(center_y + distance_center_projection_y * Math.sin(Math.radians( -angle90 -90))); 
            
            // If is the min ? 
            if(projections.y.min == null
                || distance_center_projection_y < projections.y.min.distance){
            
                projections.y.min = projection_y;
                projections.y.min.distance = distance_center_projection_y;
                projections.y.min.corner = corner;
            }
            // Is the max ?
            if(projections.y.max == null
                || distance_center_projection_y > projections.y.max.distance){
            
                projections.y.max = projection_y;
                projections.y.max.distance = distance_center_projection_y;
                projections.y.max.corner = corner;
            }            
        }
        
        // Return object
        return projections;
    },
    
    is_approx_collide : function(){
        return (collide.FIXED_SQUARE_X + collide.FIXED_SQUARE_SIZE + collide.CURSOR_SQUARE_SIZE >= collide.cursor_x
            && collide.FIXED_SQUARE_Y + collide.FIXED_SQUARE_SIZE + collide.CURSOR_SQUARE_SIZE  >= collide.cursor_y
            && collide.FIXED_SQUARE_X <= collide.cursor_x + collide.FIXED_SQUARE_SIZE + collide.CURSOR_SQUARE_SIZE
            && collide.FIXED_SQUARE_Y <= collide.cursor_y + collide.FIXED_SQUARE_SIZE + collide.CURSOR_SQUARE_SIZE) ? true : false;
    },
    
    is_collide : function(){
        
        collide.fixed_projections.x.is_collide = 
                ( (collide.fixed_projections.x.min.distance <= -collide.CURSOR_SQUARE_SIZE/2 && collide.fixed_projections.x.max.distance >= -collide.CURSOR_SQUARE_SIZE/2 )
            ||  (collide.fixed_projections.x.min.distance <= collide.CURSOR_SQUARE_SIZE/2 && collide.fixed_projections.x.max.distance >= collide.CURSOR_SQUARE_SIZE/2 )
            ||  (collide.fixed_projections.x.min.distance >= -collide.CURSOR_SQUARE_SIZE/2 && collide.fixed_projections.x.max.distance <= collide.CURSOR_SQUARE_SIZE/2 )) ? true : false;
        collide.fixed_projections.y.is_collide = 
                ( (collide.fixed_projections.y.min.distance <= -collide.CURSOR_SQUARE_SIZE/2 && collide.fixed_projections.y.max.distance >= -collide.CURSOR_SQUARE_SIZE/2 )
            ||  (collide.fixed_projections.y.min.distance <= collide.CURSOR_SQUARE_SIZE/2 && collide.fixed_projections.y.max.distance >= collide.CURSOR_SQUARE_SIZE/2 )
            ||  (collide.fixed_projections.y.min.distance >= -collide.CURSOR_SQUARE_SIZE/2 && collide.fixed_projections.y.max.distance <= collide.CURSOR_SQUARE_SIZE/2 )) ? true : false;
        
        collide.cursor_projections.x.is_collide = 
                ( (collide.cursor_projections.x.min.distance <= -collide.FIXED_SQUARE_SIZE/2 && collide.cursor_projections.x.max.distance >= -collide.FIXED_SQUARE_SIZE/2 )
            ||  (collide.cursor_projections.x.min.distance <= collide.FIXED_SQUARE_SIZE/2 && collide.cursor_projections.x.max.distance >= collide.FIXED_SQUARE_SIZE/2 )
            ||  (collide.cursor_projections.x.min.distance >= -collide.FIXED_SQUARE_SIZE/2 && collide.cursor_projections.x.max.distance <= collide.FIXED_SQUARE_SIZE/2 )) ? true : false;
        collide.cursor_projections.y.is_collide = 
                ( (collide.cursor_projections.y.min.distance <= -collide.FIXED_SQUARE_SIZE/2 && collide.cursor_projections.y.max.distance >= -collide.FIXED_SQUARE_SIZE/2 )
            ||  (collide.cursor_projections.y.min.distance <= collide.FIXED_SQUARE_SIZE/2 && collide.cursor_projections.y.max.distance >= collide.FIXED_SQUARE_SIZE/2 )
            ||  (collide.cursor_projections.y.min.distance >= -collide.FIXED_SQUARE_SIZE/2 && collide.cursor_projections.y.max.distance <= collide.FIXED_SQUARE_SIZE/2 )) ? true : false;
        
        return (collide.fixed_projections.x.is_collide 
            && collide.fixed_projections.y.is_collide
            && collide.cursor_projections.x.is_collide
            && collide.cursor_projections.y.is_collide) ? true : false;
    }
    
};
$(document).ready(function(){
    collide.__init();
});



var debug = function(attr){
    if($('.debugjs').length == 0){
        $('<span class="debugjs"></span>').appendTo('body');
    }
    $('.debugjs').text(attr);
}
#collide {
  margin: 25px;
  border: 1px solid black;
  float: left;
}

#form {
  margin-left: 550px;
  padding-top: 2px;
}

#fixed_form h2 {
  color: #0033FF;
}

#cursor_form h2 {
  color: #FF8800;
}

#fixed_form input, #cursor_form input {
  margin-left: 25px;
  width: 50px;
}

#fixed_rotation_speed, #cursor_rotation_speed {
  margin-right: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="collide" width="500" height="500"></canvas>


<div id="form">
  <h3>Understand how to detect if 2 rotates squares collide.</h3>
  <p>The 2 rotates squares collide only when all the projection of a square hit the second one.</p>
  <div id="fixed_form">
      <h2>Fixed square :</h2>
      Rotation speed : <input type="number" id="fixed_rotation_speed" value="0"/>
      Angle : <input type="number" id="fixed_angle" value="0"/>
      (Set : <input type="number" id="fixed_set_angle" value="0"/>)
  </div>
  <div id="cursor_form">
      <h2>Cursor square :</h2>
      Rotation speed : <input type="number" id="cursor_rotation_speed" value="-1"/>
      Angle : <input type="number" id="cursor_angle" value="0"/>
      (Set : <input type="number" id="cursor_set_angle" value="0"/>)
  </div>
</div>

使用不旋转的矩形来完成相同的工作(这将更加容易),并且它将在所有情况下都有效。


4
虽然这是一个非常漂亮的答案,提供了理解问题的理论基础,但如果您发表答案并链接到解决问题的代码,您应该将该代码包含在问题本身中,以便于其他人在未来使用时仍然有用,即使外部资源出现故障、停止工作或被重新组织。 - David Thomas
是的,我同意,但我的代码并不是问题的答案 :/ 它只是一个理论上的例子,使用浏览器来理解问题的基础。这是很多旧代码,在这里并不真正有用。 - Arthur
1
如果您能够针对具体问题提供一个明确的答案(尽管概括和抽象化代码也是可以接受的),我愿意提供一份赏金(不过我需要等待几天)以回应最佳答案,仅出于个人兴趣和好奇心,想了解您在JavaScript(或jQuery,我猜也可以)中实现的方法。 :) - David Thomas
2
@Arthur - 如果你已经在其他地方回答了这个问题,请将此帖标记为重复,而不是在此处粘贴相同的解决方案... 在我看来 :) - Rayon
你的示例和 Code Pen 真是太棒了! - Garavani
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接