??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
已知4点坐标求体积Q?/span>其中四个点的坐标分别为(x1,y1,z1Q?span lang=EN-US>,Q?span lang=EN-US>x2,y2,z2Q?span lang=EN-US>,Q?span lang=EN-US>x3,y3,z3Q?span lang=EN-US>,Q?span lang=EN-US>x4,y4,z4Q?br>
注意事项Q?br>
1. 注意舍入方式(0.5的舍入方?span lang=EN-US>);防止输出-0.
2. 几何题注意多试不对U数?span lang=EN-US>.
3. 整数几何注意xmult?span lang=EN-US>dmult是否会出?span lang=EN-US>;
W点几何注意eps的?span lang=EN-US>.
4. 避免使用斜率;注意除数是否会ؓ0.
5. 公式一定要化简后再代入.
6. 判断同一?span lang=EN-US>2*PI域内两角度差应该?span lang=EN-US>
abs(a1-a2)<beta||abs(a1-a2)>pi+pi-beta;
相等应该?/span>
abs(a1-a2)<eps||abs(a1-a2)>pi+pi-eps;
7. 需要的话尽量?/span>atan2,注意:atan2(0,0)=0,
atan2(1,0)=pi/2,atan2(-1,0)=-pi/2,atan2(0,1)=0,atan2(0,-1)=pi.
8. cross product = |u|*|v|*sin(a)
dot product = |u|*|v|*cos(a)
9. (P1-P0)x(P2-P0)l果的意?span lang=EN-US>:
?span lang=EN-US>: <P0,P1>?span lang=EN-US><P0,P2>时?span lang=EN-US>(0,pi)?span lang=EN-US>
?span lang=EN-US>: <P0,P1>?span lang=EN-US><P0,P2>逆时?span lang=EN-US>(0,pi)?span lang=EN-US>
0 : <P0,P1>,<P0,P2>q,夹角?span lang=EN-US>0?span lang=EN-US>pi
判断点P是否在多边Ş中是计算几何中一个非常基本但是十分重要的法。以点P为端点,向左方作线LQ由于多边Ş是有界的Q所以射UL的左端一定在多边形外Q考虑沿着L从无I处开始自左向右移动,遇到和多边Ş的第一个交点的时候,q入C多边形的内部Q遇到第二个交点的时候,d了多边ŞQ?#8230;…所以很Ҏ看出当L和多边Ş的交Ҏ目C是奇数的时候,P在多边Ş内,是偶数的话P在多边Ş外?/p>
但是有些Ҏ情况要加以考虑。如图下?a)(b)(c)(d)所C。在?a)中,L和多边Ş的顶点相交,q时候交点只能计一个;在图(b)中,L和多边Ş点的交点不应被计算Q在?c)?d) 中,L和多边Ş的一条边重合Q这条边应该被忽略不计。如果L和多边Ş的一条边重合Q这条边应该被忽略不计?/p>
Zl一赯Q我们在计算线L和多边Ş的交点的时候,1。对于多边Ş的水q不作考虑Q?。对于多边Ş的顶点和L怺的情况,如果该顶Ҏ其所属的边上U坐标较大的点Q则计数Q否则忽略;3。对于P在多边Ş边上的情形,直接可判断P属于多边行。由此得出算法的伪代码如下:
count ← 0;
以P为端点,作从叛_左的线L;
for 多边形的每条边s
do if P在边s?nbsp;
then return true;
if s不是水^?
then if s的一个端点在L?
if 该端Ҏs两端点中U坐标较大的端点
then count ← count+1
else if s和L怺
then count ← count+1;
if count mod 2 = 1
then return true;
else return false;
其中做射UL的方法是Q设P'的纵坐标和P相同Q横坐标为正无穷大(很大的一个正敎ͼQ则P和P'q定了线L?
判断Ҏ否在多边形中的这个算法的旉复杂度ؓO(n)?/p>
另外q有一U算法是用带W号的三角Ş面积之和与多边Ş面积q行比较Q这U算法由于用QҎq算所以会带来一定误差,不推荐大家用?
判断U段是否在多边Ş?/strong>Q?/strong>
U段在多边Ş内的一个必要条件是U段的两个端炚w在多边Ş内,但由于多边Ş可能为凹Q所以这不能成ؓ判断的充分条件。如果线D和多边形的某条边内交(两线D内交是指两U段怺且交点不在两U段的端点)Q因为多边Ş的边的左右两侧分属多边Ş内外不同部分Q所以线D一定会有一部分在多边Ş?见图a)。于是我们得到线D在多边形内的第二个必要条gQ线D和多边形的所有边都不内交?
U段和多边Ş交于U段的两端点q不会媄响线D|否在多边形内Q但是如果多边Ş的某个顶点和U段怺Q还必须判断两相M点之间的U段是否包含于多边Ş内部Q反例见图b)?
因此我们可以先求出所有和U段怺的多边Ş的顶点,然后按照X-Y坐标排序(X坐标的排在前面Q对于X坐标相同的点QY坐标的排在前面Q这U排序准则也是ؓ了保证水q_垂直情况的判断正?Q这Lȝ两个点就是在U段上相ȝ两交点,如果L盔R两点的中点也在多边Ş内,则该U段一定在多边形内?
证明如下Q?/p>
命题1Q?
如果U段和多边Ş的两盔R交点P1 QP2的中点P' 也在多边形内Q则P1, P2之间的所有点都在多边形内?/p>
证明Q?
假设P1,P2之间含有不在多边形内的点Q不妨设该点为QQ在P1, P'之间Q因为多边Ş是闭合曲U,所以其内外部之间有界,而P1属于多边行内部,Q属于多边性外部,P'属于多边性内部,P1-Q-P'完全q箋Q所以P1Q和QP'一定跨多边Ş的边界,因此在P1,P'之间臛_q有两个该线D和多边形的交点Q这和P1P2是相M交点矛盾Q故命题成立。证毕?
由命?直接可得出推论:
推论2Q?
讑֤边Ş和线DPQ的交点依ơؓP1,P2,……PnQ其中Pi和Pi+1是相M交点Q线DPQ在多边Ş内的充要条g是:PQQ在多边Ş内且对于i =1, 2,……, n-1QPi ,Pi+1的中点也在多边Ş内?
在实际编E中Q没有必要计所有的交点Q首先应判断U段和多边Ş的边是否内交Q倘若U段和多边Ş的某条边内交则线D一定在多边形外Q如果线D和多边形的每一条边都不内交Q则U段和多边Ş的交点一定是U段的端Ҏ者多边Ş的顶点,只要判断Ҏ否在U段上就可以了?
x我们得出法如下Q?
if U端PQ的端点不都在多边形内
then return false;
炚wpointSet初始化ؓI?
for 多边形的每条边s
do if U段的某个端点在s?
then 该端点加入pointSet;
else if s的某个端点在U段PQ?
then 该端点加入pointSet;
else if s和线DPQ怺 // q时候已l可以肯定是内交?
then return false;
pointSet中的Ҏ照X-Y坐标排序;
for pointSet中每两个盔R?pointSet[i] , pointSet[ i+1]
do if pointSet[i] , pointSet[ i+1] 的中点不在多边Ş?
then return false;
return true;
q个q程中的排序因ؓ交点数目肯定q小于多边Ş的顶Ҏ目nQ所以最多是常数U的复杂度,几乎可以忽略不计。因此算法的旉复杂度也是O(n)?/p>
设一条线DؓL0 = P1P2Q另一条线D|直线为L1 = Q1Q2 Q要计算的就是L0和L1的交炏V?
1Q?首先判断L0和L1是否怺Q方法已在前文讨Q,如果不相交则没有交点Q否则说明L0和L1一定有交点Q下面就L0和L1都看作直U来考虑?
2Q?如果P1和P2横坐标相同,即L0q于Y?
a) 若L1也^行于Y_
i. 若P1的纵坐标和Q1的纵坐标相同Q说明L0和L1qQ假如L1是直U的话他们有无穷的交点,假如L1是线D늚话可?计算两条qU段的交?的算法求他们的交点(该方法在前文已讨Q;
ii. 否则说明L0和L1qQ他们没有交点;
b) 若L1不^行于Y_则交Ҏ坐标为P1的横坐标Q代入到L1的直U方E中可以计算Z点纵坐标Q?
3Q?如果P1和P2横坐标不同,但是Q1和Q2横坐标相同,即L1q于Y_则交Ҏ坐标为Q1的横坐标Q代入到L0的直U方E中可以计算Z点纵坐标Q?
4Q?如果P1和P2U坐标相同,即L0q于X?
a) 若L1也^行于X_
i. 若P1的横坐标和Q1的横坐标相同Q说明L0和L1qQ假如L1是直U的话他们有无穷的交点,假如L1是线D늚话可?计算两条qU段的交?的算法求他们的交点(该方法在前文已讨Q;
ii. 否则说明L0和L1qQ他们没有交点;
b) 若L1不^行于X_则交点纵坐标为P1的纵坐标Q代入到L1的直U方E中可以计算ZҎ坐标Q?
5Q?如果P1和P2U坐标不同,但是Q1和Q2U坐标相同,即L1q于X_则交点纵坐标为Q1的纵坐标Q代入到L0的直U方E中可以计算ZҎ坐标Q?
6Q?剩下的情况就是L1和L0的斜率均存在且不?的情?
a) 计算出L0的斜率K0QL1的斜率K1 Q?
b) 如果K1 = K2
i. 如果Q1在L0上,则说明L0和L1qQ假如L1是直U的话有无穷交点Q假如L1是线D늚话可?计算两条qU段的交?的算法求他们的交点(该方法在前文已讨Q;
ii. 如果Q1不在L0上,则说明L0和L1qQ他们没有交炏V?
c) 联立两直U的方程l可以解ZҎ
q个法q不复杂Q但是要分情况讨论清楚,其是当两条U段q的情况需要单独考虑Q所以在前文求两条qU段的算法单独写出来。另外,一开始就先利用矢量叉乘判断线D与U段Q或直线Q是否相交,如果l果是相交,那么在后面就可以线D全部看作直U来考虑。需要注意的是,我们可以直U或U段方程改写为ax+by+c=0的Ş式,q样一来上q过E的部分步骤可以合ƈQ羃短了代码长度Q但是由于先要求出参敎ͼq种法花Ҏ多的旉?
讑֜心ؓOQ圆半径为rQ直U(或线D)L上的两点为P1,P2?
1. 如果L是线D且P1QP2都包含在圆O内,则没有交点;否则q行下一步?
2. 如果Lq于Y_
a) 计算圆心到L的距disQ?
b) 如果dis > r 则L和圆没有交点Q?
c) 利用勾股定理Q可以求Z交点坐标Q但要注意考虑L和圆的相切情c?
3. 如果Lq于X_做法与Lq于Y轴的情况cMQ?
4. 如果L既不qX轴也不^行Y_可以求出L的斜率KQ然后列出L的点斜式方程Q和圆方E联立即可求解出L和圆的两个交点;
5. 如果L是线D,对于2Q?Q?中求出的交点q要分别判断是否属于该线D늚范围内?/p>
二?nbsp;U段及直U的基本q算
1. 点与U段的关p?3
2. 求点到线D|在直U垂U的垂 4
3. 点到U段的最q点 4
4. 点到U段所在直U的距离 4
5. 点到折线集的最q距?4
6. 判断圆是否在多边形内 5
7. 求矢量夹角余?5
8. 求线D之间的夹角 5
9. 判断U段是否怺 6
10.判断U段是否怺但不交在端点处(内交Q?6
11.求线D|在直U的方程 6
12.求直U的斜率 7
13.求直U的倾斜?7
14.求点关于某直U的对称?7
15.判断两条直线是否怺及求直线交点 7
16.判断U段是否怺Q如果相交返回交?7
三、多边Ş常用法模块
1. 判断多边形是否简单多边Ş 8
2. 查多边Ş点的凸Ҏ?9
3. 判断多边形是否凸多边?9
4. 求多边Ş面积 9
5. 判断多边形顶点的排列方向Q方法一 10
6. 判断多边形顶点的排列方向Q方法二 10
7. 线法判断点是否在多边Ş?10
8. 判断Ҏ否在凸多边Ş?11
9. L炚w的graham法 12
10.L炚w凸包的卷包裹?13
11.判断U段是否在多边Ş?14
12.求简单多边Ş的重?QHDU1115Q?5
13.求凸多边形的重心 17
14.求肯定在l定多边形内的一个点 17
15.求从多边形外一点出发到该多边Ş的切U?18
16.判断多边形的核是否存?19
四?圆的基本q算
1 .Ҏ否在圆内 20
2 .求不q的三Ҏ定的圆 21
五、矩形的基本q算
1.已知矩Ş三点坐标Q求W?点坐?22
六、常用算法的描述 22
七、补?
1Q两圆关p: 24
2Q判断圆是否在矩形内Q?24
3Q点到^面的距离Q?25
4Q点是否在直U同侧: 25
5Q镜面反线Q?25
6Q矩形包含: 26
7Q两圆交点: 27
8Q两圆公共面U: 28
9. 圆和直线关系Q?29
10. 内切圆: 30
11. 求切点: 31
12. U段的左xQ?31
13Q公式: 32
附上一博客:计算几何法概览
zoj上的计算几何?/span>
Vol I
1010 by pandahyx
1032 by javaman
1037 by Vegetable Bird
1041 by javaman
1081 by Vegetable Bird
1090 by Vegetable Bird
Vol II
1104 by javaman
1123 by javaman
1139 by Vegetable Bird
1165 by javaman
1199 by Vegetable Bird
Vol V
1426 by Vegetable Bird
1439 by Vegetable Bird
1460 by Vegetable Bird
1472 by Vegetable Bird
Vol VI
1597 by Vegetable Bird
Vol VII
1608 by Vegetable Bird
1648 by Vegetable Bird
Vol XII
2102 by pandahyx
2107 by pandahyx
2157 by pandahyx
Vol XIII
2234 by pandahyx
Vol XIV
2318 by ahyangyi
2394 by qherlyt
Vol XV
2403 by Vegetable Bird