c语言两个矩形位置随机,【算法】计算机图形学的一些经典小题:判断点在多边形内,随机生成三角形内的点,判断两个矩形是否相交等...

本文总结了计算机图形学中的几个经典问题:1.如何判断点在多边形内,包括凸多边形和任意多边形;2.如何在三角形内随机生成点,避免采样错误;3.如何判断圆和矩形是否相交;4.计算两个矩形相交的面积。文章介绍了各种算法的实现细节和易错点,并提供了优化思路。
摘要由CSDN通过智能技术生成

前几天面试的时候被问到了,如何随机在三角形内生成点,我按照我的想法回答了一遍,但觉得回答的不够好。最后面试官说了一个最优的方法。觉得不错,顺带总结一下最近看到的一些关于计算机图形学方面的经典小题,知乎上看到的还有Leetcode上的

1.判断一个点是否在多边形内

首先先说一下输入的内容,多边形的顶点是一个数组输入进来,其中每个相邻点之间对应着多边形上有边相连

POINT p1=ptPolygon[i];

POINT p2 = ptPolygon[(i + 1) % nCount];

即上面两个点之间存在边相连

判断是否在凸多边形内部

这个方法我记得是在编程之美上看到的,即计算该点与多边形点之间向量的叉积,如果叉积同向则说明在内部,如果有反向则说明在外部。

810d97a6ce632abaae28c9a4f00b1cc9.png

比如上面这个图,分别计算PA→,PB→ 的叉积 PB,PC→ 的叉积 PC→,PA→的叉积

如果其都是同向的,则说明其在内部,如果不是同向的,则说明在外部。

这个算法复杂度是O(n)的,n是多边的顶点数

判断是否在任意多边形内部

一个经典的算法是射线法

从该点P出发向任意方向射出一条射线, 如果与多边形的边相交的数量为奇数个,则说明其在内部,如果相交个数为偶数个则在内部

一般为了计算方便就选择从P点向x轴向右方向上的射线,而判断相交只用求出交点的横坐标看起是否大于P.x的坐标就好

具体的算法实现见这个判断点是否在多边形内的算法和C语言程序

2.随机生成三角形内的点

这个是被面试官问到的题目,我的做法是先将三角形的外围用一个矩形给括起来,然后对矩形内的点进行随机采样,采样出来的点用上面1中的方法判断是否在三角形内。如果不在则继续采样。

面试官对此不是很满意,后来我想出来可以通过左边轴变换的方式进行,但是回答的也不好

最后面试官说了自己的方法:

734fbb75b43ea9169bf30a3d5b7c6cdc.png

网上找了一个图将就着看吧

其实这个方法也是坐标轴转换的思想,我之前想到的已经比较接近了,只不过没有往向量这块去考虑。

即由之前的xy坐标系转换为以三角形的两条边为基底的坐标系,如上图所示转换为OA→,OB→作为坐标的表示,所以OP→=tOA→+kOB→如果0

一个非常容易的易错点

这道题一个非常经典的易错思路是:比如上面的方法先随机生成t,然后再在(0,1-t)的区间内生成k点。

因为这种不随机:

比如假设t生成的结果非常接近于1,如果按照原始的方法则会出现大概率出现采样超过原来三角形的情况,而在这种采样的方式之下,必然会采样成功。

3.判断一个圆形和矩形是否相交

这道题是今天知乎上看到的:

怎样判断平面上一个矩形和一个圆形是否有重叠?

具体的算法也非常简单易懂,但是非常的巧妙。

我总结一下巧妙的地方在于:

先通过一个变换,将圆形变到了矩形的右上角,

通过向量,外加取最大值来巧妙的求得了圆形到矩形的最短距离【所以这个题目的简化版本可以用来求解圆形到矩形的最短距离】

4.判断两个矩形是否相交并求相交部分面积

Leetcode上有这道题:

223. Rectangle Area

我一开始的思路是,类比与上面那道题,将第二个矩形换到第一个矩形右上角,然后判断以第一个矩形右顶点为坐标原点时,第二个矩形的左下角是否落在了第三象限。这样用来判断是否相交还是不错的,但是求面积就不行了,比如如下的图

5a9ae684b5db71b3b9f12af25b2900d7.png

然后翻Leecode的discuss,底下最高票答案给的方法一时没看明白

int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {

int left = max(A,E), right = max(min(C,G), left);

int bottom = max(B,F), top = max(min(D,H), bottom);

return (C-A)*(D-B) - (right-left)*(top-bottom) + (G-E)*(H-F);

}

后来查到了另外一个人的博客,我觉得它讲的挺明白的: 判断两矩形是否相交

这道题本质上相当于求两个矩形相交区域的横纵坐标

int left = max(A,E);

int bottom = max(B,F);

这个是求得相交区域左下角的坐标的。如果不相交也是没有问题的

这个可以这么看,即两个矩形的左边和下面两条边做直线延长,然后得到的相交区域一定是一个矩形,然后上面求得的坐标就是这个矩形的右上角

同理,右边和上面四条边所在直线相交点的左下角为:

int right = min(C,G);

int top = min(D,H);

在判断一下以上两个坐标点的相对位置,如果第一个在第二个左下角的话,则能够构成矩形,如果不是这种情况则不能构成矩形。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值