圆与旋转矩形的碰撞检测

2024-06-12 17:08
文章标签 旋转 矩形 碰撞检测

本文主要是介绍圆与旋转矩形的碰撞检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

圆与旋转矩形的碰撞检测

本文我将解释如何实现圆和旋转矩形的碰撞检测。碰撞检测用于确定对象A是否碰撞了对象B。圆包含圆心位置x,y和一个半径。矩形包含左上角的x,y位置、宽度、长度和一个可以旋转的角度。我们假设矩形沿着它的中心点旋转。


我将使用一个小程序、图片和代码来展示这一点。为了更好地理解圆和不旋转矩形之间的碰撞检测,可以阅读这篇文章


程序示例

这里有一个程序示例来展示碰撞检测。如果检测到碰撞,图形就变为蓝色。绿色轮廓形状表示该用于计算的状态。橙色的线将未旋转圆的圆心与矩形上最近的一个点连接。你可以设置一个角度,点击按钮使其旋转。点击或者拖动某个地方使圆形移动。


设置一个角度实现圆形和矩形碰撞检测

想法很简单。为了计算方便,我们需要在矩形角度为0时,记下两个形状的位置。如果我们将矩形旋转一个角度,计算将会有一点复杂。将矩形保持0度角时候通过简单的加法就可以很容易地获得其他点的位置坐标。左上角为(x,y),右上角为(x+width, y),左下角为(x, y+height)。

c1.png

这里我们不旋转矩形,而是用同样的角度旋转圆。将圆心放在矩形角度为0时的位置。单点比较容易旋转。如下简图所示,蓝色区域代表我们所看到的矩形在旋转。黑色区域用于计算。我们用0度调整形状,换言之,我们将矩形设为0度,用矩形的角度来旋转圆。


所用的公式如下所示。变量cx/cy代表圆心点,originX/originY代表旋转圆的点,x’/y’为旋转点。

x’= cos(theta) * (cx – originX) – sin(theta) * (cy – originY) + originX

y’= sin(theta) * (cx – originX) + cos(theta) * (cy – originY) + originY

c2.png

找到离未旋转的圆和矩形最近的点,我们需要做的就是分别为x和y做if-else判断。


对于x,使用矩形的left x(rx)和right x(rx+width)与圆心x(cx)做比较。如果cx在rx的左边,那么rx离x最近。如果cx在rx+width的右边,那么rx+width离x最近。最后如果以上两点都不符合,那么cx本身离x最近。如下图所示,红色线表示x的位置。

c3.png


对于y,与x的规则相同。如果圆心y(cy)在top y(ry)的上面,那么ry离y点最近。如果cy在bottom y(ry+height)的下面,ry+heigh离y最近。如果以上两点都不符合,那么cy离y最近。

c4.png


最后,我们需要计算未旋转圆的圆心和我们所找到的最近点的距离。我使用勾股定理计算这个最近距离(a^2 + b^2 = c^2)。然后将这个值与圆的半径作比较,如果这个距离远远小于半径,那么这两个图形就会发生碰撞。

c5.png

代码实例

1
2
3
4
5
6
7
8
9
10
11
// Rotate circle's center point backdouble unrotatedCircleX = Math.cos(rect.angle) * (circle.x - rect.centerX) - 
Math. sin (rect.angle) * (circle.y - rect.centerY) + rect.centerX; double  unrotatedCircleY  = Math. sin (rect.angle) * (circle.x - rect.centerX) + 
Math. cos (rect.angle) * (circle.y - rect.centerY) + rect.centerY;  // Closest point in the rectangle to the center of circle rotated backwards(unrotated)double closestX, closestY; // Find the unrotated closest x point from center of unrotated circleif (unrotatedCircleX  < rect.x)
closestX = rect.x; else  if  (unrotatedCircleX  > rect.x + rect.width)
closestX = rect.x + rect.width; else
closestX = unrotatedCircleX ;  // Find the unrotated closest y point from center of unrotated circleif (unrotatedCircleY < rect.y)
closestY = rect.y; else  if  (unrotatedCircleY > rect.y + rect.height)
closestY = rect.y + rect.height; else
closestY = unrotatedCircleY;  // Determine collisionboolean collision = false; double distance = findDistance(unrotatedCircleX , unrotatedCircleY, closestX, closestY);if (distance < circle.radius)
collision =  true // Collisionelse
collision =  false ;
1
2
3
4
5
6
7
8
9
/**
  * Pythagorean theorem
  * @param fromX
  * @param fromY
  * @param toX
  * @param toY
  */ public  double  findDistance( double  fromX,  double  fromY,  double  toX,  double  toY){
  double  a = Math. abs (fromX - toX);
  double  b = Math. abs (fromY - toY);      return  Math. sqrt ((a * a) + (b * b));}

这篇关于圆与旋转矩形的碰撞检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054820

相关文章

css实现图片旋转功能

《css实现图片旋转功能》:本文主要介绍了四种CSS变换效果:图片旋转90度、水平翻转、垂直翻转,并附带了相应的代码示例,详细内容请阅读本文,希望能对你有所帮助... 一 css实现图片旋转90度.icon{ -moz-transform:rotate(-90deg); -webkit-transfo

Qt QWidget实现图片旋转动画

《QtQWidget实现图片旋转动画》这篇文章主要为大家详细介绍了如何使用了Qt和QWidget实现图片旋转动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、效果展示二、源码分享本例程通过QGraphicsView实现svg格式图片旋转。.hpjavascript

poj 2187 凸包or旋转qia壳法

题意: 给n(50000)个点,求这些点与点之间距离最大的距离。 解析: 先求凸包然后暴力。 或者旋转卡壳大法。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <s

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

二维旋转公式

二维旋转公式 ros的tf工具包可以很方便的实现任意坐标系之间的坐标转换。但是,如果只是想简单的测试想法,而又不想编写过于庞杂的代码,考虑自己写二维旋转的函数。而与二维旋转问题对偶的另一个问题便是二维坐标系旋转变换。这两个问题的形式基本一样,只是旋转的角度相差一个负号。就是这个容易搞混,所以做个笔记,以备查用。 1. 二维旋转公式(算法) 而(此文只针对二维)旋转则是表示某一坐标点 ( x

算法复杂度 —— 数据结构前言、算法效率、时间复杂度、空间复杂度、常见复杂度对比、复杂度算法题(旋转数组)

目录 一、数据结构前言 1、数据结构 2、算法 3、学习方法 二、 算法效率 引入概念:算法复杂度  三、时间复杂度 1、大O的渐进表示法 2、时间复杂度计算示例  四、空间复杂度 计算示例:空间复杂度 五、常见复杂度对比 六、复杂度算法题(旋转数组) 1、思路1 2、思路2 3、思路3 一、数据结构前言 1、数据结构         数据结构(D

百度之星初赛1006(计算几何:能包含凸包的最小矩形面积)

矩形面积    Accepts: 717    Submissions: 1619  Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些

计算几何之向量旋转

实际做题中我们可能会遇到很多有关及计算几何的问题,其中有一类问题就是向量的旋转问题,下面我们来具体探讨一下有关旋转的问题。 首先我们先把问题简化一下,我们先研究一个点绕另一个点旋转一定角度的问题。已知A点坐标(x1,y1),B点坐标(x2,y2),我们需要求得A点绕着B点旋转θ度后的位置。 A点绕B点旋转θ角度后得到的点,问题是我们要如何才能得到A' 点的坐标。(向逆时针方向旋转角度正,

红黑树的旋转

红黑树的基本性质 红黑树与普通的二叉搜索树不同,它在每个节点上附加了一个额外的属性——颜色,该颜色可以是红色或黑色。通过引入这些颜色,红黑树能够维持以下 5 个基本性质,以确保树的平衡性: 每个节点是红色或黑色。根节点是黑色。所有叶子节点(NIL 节点)是黑色。如果一个节点是红色的,那么它的两个子节点都是黑色的(即,红色节点不能有红色子节点)。从任一节点到其每个叶子节点的所有路径上都包含相同数

NYOJ 16 矩形嵌套

OJ题目 : http://acm.nyist.net/JudgeOnline/problem.php?pid=16 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除