Giter VIP home page Giter VIP logo

issues's People

Contributors

mrold avatar

Stargazers

 avatar

Watchers

 avatar  avatar

issues's Issues

关于旋转矩形相交判断问题,求指教!

这是浏览器中渲染的样式,两个矩形出现相交

image

但是console.log()打印出的结果竟然是false

image

这是javascript (react)代码

import React from 'react';
const a = {
  left: 50, top: 50,
  width: 200, height: 100,
  angle: 45
};
const b = {
  left: 100, top: 200,
  width: 200, height: 100,
  angle: 45
};
console.log(isRectCollision(a, b));

export default function App() {
  return (
    <div style={{width: 500, height: 500, margin: '100px auto', background: '#eee', position: 'relative'}}>
      <div style={{ width: a.width, height: a.height,  position: 'absolute', left: a.left, top: a.top, border: '1px solid red', transform: `rotate(${a.angle}deg)` }} />
      <div style={{ width: b.width, height: b.height, position: 'absolute', left: b.left, top: b.top, border: '1px solid green', transform: `rotate(${b.angle}deg)`}} />
    </div>
  );
}

function isRectCollision(a, b) {
  // 绕原点逆时针旋转后的点坐标
  // 默认绕原点旋转
  const rotate = ({ x, y }, deg, origin = { x: 0, y: 0 }) => ({
    x: (x - origin.x) * Math.cos(deg) + (y - origin.y) * Math.sin(deg) + origin.x,
    y: (origin.x - x) * Math.sin(deg) + (y - origin.y) * Math.cos(deg) + origin.y
  });

  const toDeg = (angle) => angle / 180 * Math.PI;
  const getCenterPoint = (box) => ({
    x: box.left + box.width / 2,
    y: box.top + box.height / 2
  });
  /**
   * 转化为顶点坐标数组
   * @param {Object} box
   */
  function toRect (box) {
    let deg = toDeg(box.angle)
    let cp = getCenterPoint(box)
    return [rotate({
      x: box.left,
      y: box.top
    }, deg, cp), rotate({
      x: box.left + box.width,
      y: box.top,
    }, deg, cp), rotate({
      x: box.left + box.width,
      y: box.top + box.height,
    }, deg, cp), rotate({
      x: box.left,
      y: box.top + box.height
    }, deg, cp)]
  }
  /**
   * 计算投影半径
   * @param {Array(Number)} checkAxis 检测轴 [cosθ,sinθ]
   * @param {Array} axis 目标轴 [x,y]
   */
  function getProjectionRadius (checkAxis, axis) {
    return Math.abs(axis[0] * checkAxis[0] + axis[1] * checkAxis[1])
  }
  /**
   * 判断是否碰撞
   * @param {Array} rect1 矩形顶点坐标数组 [Pa,Pb,Pc,Pd]
   * @param {*} rect2
   */
  function isCollision (box1, box2) {
    let rect1 = toRect(box1)
    let rect2 = toRect(box2)
    const vector = (start, end) => {
      return [end.x - start.x, end.y - start.y]
    }
    // 两个矩形的中心点
    const p1 = getCenterPoint(box1)
    const p2 = getCenterPoint(box2)
    //向量 p1p2
    const vp1p2 = vector(p1, p2)
    //矩形1的两边向量
    let AB = vector(rect1[0], rect1[1])
    let BC = vector(rect1[1], rect1[2])
    //矩形2的两边向量
    let A1B1 = vector(rect2[0], rect2[1])
    let B1C1 = vector(rect2[1], rect2[2])
    // 矩形1 的两个弧度
    let deg11 = toDeg(box1.angle)
    let deg12 = toDeg(90 - box1.angle)
    // 矩形2 的两个弧度
    let deg21 = toDeg(box2.angle)
    let deg22 = toDeg(90 - box2.angle)
    // 投影重叠
    const isCover = (checkAxisRadius, deg, targetAxis1, targetAxis2) => {
      let checkAxis = [Math.cos(deg), Math.sin(deg)]
      let targetAxisRadius = (getProjectionRadius(checkAxis, targetAxis1) + getProjectionRadius(checkAxis, targetAxis2)) / 2
      let centerPointRadius = getProjectionRadius(checkAxis, vp1p2)
      console.log(`checkAxis:${checkAxis},三个投影:${checkAxisRadius}, ${targetAxisRadius}, ${centerPointRadius}`)
      return checkAxisRadius + targetAxisRadius > centerPointRadius
    };
    return isCover(box1.width / 2, deg11, A1B1, B1C1) &&
      isCover(box1.height / 2, deg12, A1B1, B1C1) &&
      isCover(box2.width / 2, deg21, AB, BC) &&
      isCover(box2.height / 2, deg22, AB, BC)
  }
  // (function main () {
  //   let box1 = {
  //     left: 0,
  //     top: 0,
  //     width: 100,
  //     height: 100,
  //     angle: 30
  //   }
  //   let box2 = {
  //     left: 100,
  //     top: 0,
  //     width: 100,
  //     height: 100,
  //     angle: 0
  //   }
  //   return isCollision(box1, box2)
  // })()

  return isCollision(a,b);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.