算法习题23:用最简单, 最快速的方法计算出下面这个圆形是否和正方形相交

用最简单, 最快速的方法计算出下面这个圆 形是否和正方形相交。"    
3D坐标系 原点(0.0,0.0,0.0)
圆形:
半径r = 3.0
圆心o = (*.*, 0.0,  *.*)

正方形:
4个角坐标;   
1:(*.*, 0.0, *.*)
2:(*.*, 0.0, *.*)
3:(*.*, 0.0, *.*)

4:(*.*, 0.0, *.*)

————————————————————————————————————

这道题网上搜了下,貌似也没有什么答案,不好比较,我就描述下我的做法,有不对的还请指出

首先需要计算出正方形的中心和圆形的中心

这道题可以转换程二维的,所以我下面都是建立在二维上的答案!!!

圆形的中心就是圆心了,没什么好说的,这里计算下正方形的中心:和边长长度

struct Rectangle{
	float rectangleX1;
	float rectangleY1,rectangleX2, rectangleY2,
				rectangleX3, rectangleY3,
				rectangleX4, rectangleY4;

	float centerX, centerY;
	float edge;

	void CalcProperty(){
		centerX = rectangleX1+rectangleX2+rectangleX3+rectangleX4;
		centerX /= 4.0;
		centerY = rectangleY1+rectangleY2+rectangleY3+rectangleY4;
		centerY /= 4.0;
		edge = (rectangleX1-centerX)<0?(-rectangleX1+centerX):(rectangleX1-centerX);
		edge = 2*edge;
	}

};


要知道圆形和矩形有没有相交,其实可以通过判断两个图形的中心,

一开始,很多人会用两中心距离与(r+edge/2)来判断


但是如图所示,(假设相相交了,就是圆形有一点点进入矩形,图示不清出哈),O1O2距离大于了edge/2+r,但是确实相交的,

但是从图中我们发现,O1O2在y轴上的投影却可以得到与(r+edge/2)的比较,如果(r+edge/2)>Y(O1O2)那么这两个确实相交了,但是要注意


这图O1O2在y轴上的距离确实小于(r+edge/2),但是x轴上的距离却大于(r+edge/2),所以这两个轴上的距离都需要判断,并且都小于(r+edge/2)的时候才是相交的!

但是,还有一个特殊点就是斜对角线上的圆形


从上图我们看见,这里XY轴上都小于(r+edge/2)  但是实际上没有相交,所以还需要加上两图形中心距离必须小于(矩形对角线距离/2+r)这是两图形相交最远的距离


所以得出结论:两图形的中心距离在X轴和Y轴距离都小于(r+edge/2)的时候,而且中心距离之和小于矩形对角线/2+r!

我这里枚举了在X Y轴以及对角线上的三种情况来得出结论,可能这是个错误的结论,希望大家能帮忙纠个错,谢谢

//============================================================================
// Name        : JudgeInterception.cpp
// Author      : YLF
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <math.h>
using namespace std;

struct Circle{
	float centerX;
	float centerY;
	float r;
};

struct Rectangle{
	float rectangleX1;
	float rectangleY1,rectangleX2, rectangleY2,
				rectangleX3, rectangleY3,
				rectangleX4, rectangleY4;

	float centerX, centerY;
	float edge;

	void CalcProperty(){
		centerX = rectangleX1+rectangleX2+rectangleX3+rectangleX4;
		centerX /= 4.0;
		centerY = rectangleY1+rectangleY2+rectangleY3+rectangleY4;
		centerY /= 4.0;
		edge = (rectangleX1-centerX)<0?(-rectangleX1+centerX):(rectangleX1-centerX);
		edge = 2*edge;
	}

};

bool JudgeInterception(Circle circle,Rectangle rect);
float getDistance(float pt1X, float pt1Y, float pt2X, float pt2Y);

int main() {

	Circle circle;
	Rectangle rect;
	circle.r = 3.0;
	cin>>circle.centerX>>circle.centerY;
	cin>>rect.rectangleX1>>rect.rectangleY1>>rect.rectangleX2>>rect.rectangleY2
		>>rect.rectangleX3>>rect.rectangleY3>>rect.rectangleX4>>rect.rectangleY4;


	if(JudgeInterception(circle,rect))
		cout<<"intercept!";
	else
		cout<<"not intercept!";
	return 0;
}

bool JudgeInterception(Circle circle,Rectangle rect){
	rect.CalcProperty();
	if(::fabsf(rect.centerX-circle.centerX)<(rect.edge/2+circle.r) &&
			::fabsf(rect.centerY-circle.centerY)<(rect.edge/2+circle.r) &&
			 getDistance(circle.centerX,circle.centerY,rect.centerX,rect.centerY)<
			 (getDistance(rect.centerX,rect.centerY,rect.rectangleX1,rect.rectangleY1)+circle.r))
		return true;
	else
		return false;
}

float getDistance(float pt1X, float pt1Y, float pt2X, float pt2Y){
	float distance = 0.0;
	distance = (pt1X-pt2X)*(pt1X-pt2X)+(pt1Y-pt2Y)*(pt1Y-pt2Y);
	distance = ::sqrtf(distance);
	return distance;
}



给几个测试结

(1)圆心在中点,矩形在其右边相交一点点

0
0
2.9
1.5
5.9
1.5
5.9
-1.5
2.9
-1.5
intercept!


下面我给出对角线的情形3/sqrt(2)差不多等于2.15..

我这里先用2.1就是刚好相交一点点

0
0
5.1
2.1
5.1
5.1
2.1
5.1
2.1
2.1
intercept!

这里用2.2 是差一点就相交

0
0
2.2
2.2
5.2
2.2
5.2
5.2
2.2
5.2
not intercept!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值