?? 叉乘,向量是否有交點,點在線的哪側.cpp
字號:
#include<stdio.h>
//計算幾何模板 ~ alpc02
const double PRECISION = 1e-8;
struct Point {
double x, y;
5};
6int dblcmp(double d) {
7 return (fabs(d) < PRECISION) ? 0:(d>0 ? 1:-1);
8} //三叉口函數,避免精度誤差
9double length(double x, double y) {
10 return sqrt(x*x + y*y);
11} //向量長度
double dotdet(double x1, double y1, double x2, double y2) {
return x1*x2 + y1*y2;
} //點積,AB * CD = |AB| * |CD| * cos(a)
double det(double x1, double y1, double x2, double y2) {
return x1*y2 - x2*y1;
} //叉積,AB×CD = |AB| * |CD| * sin(a)
int cross(const Point &a, const Point &c, const Point &d) {
return dblcmp( det(a.x-c.x, a.y-c.y, d.x-c.x, d.y-c.y) );
} //右手螺旋定則,1——a在cd右側,-1——a在cd左側,0——三點共線;逆時針為正方向
bool between(const Point &a, const Point &c, const Point &d) {
return dblcmp( dotdet(c.x-a.x, c.y-a.y, d.x-a.x, d.y-a.y) ) != 1;
} //在cross(a,c,d)==0的基礎上,可判斷點a是否在cd內部
int segIntersect(const Point &a, const Point &b, const Point &c, const Point &d) {
int a_cd = cross(a,c,d);
if(a_cd == 0 && between(a,c,d)) return 2;
int b_cd = cross(b,c,d);
if(b_cd == 0 && between(b,c,d)) return 2;
int c_ab = cross(c,a,b);
if(c_ab == 0 && between(c,a,b)) return 2;
int d_ab = cross(d,a,b);
if(d_ab == 0 && between(d,a,b)) return 2;
if ((a_cd ^ b_cd) == -2 && (c_ab ^ d_ab) == -2)
return 1;
return 0;
} //兩線段相交情況:0——不相交,1——規范相交,2——不規范相交(交于端點或重合)
void intersectPoint(const Point &a, const Point &b, const Point &c, const Point &d, Point &e) {
double sc, sd;
sc = fabs( det(b.x-a.x, b.y-a.y, c.x-a.x, c.y-a.y) );
sd = fabs( det(b.x-a.x, b.y-a.y, d.x-a.x, d.y-a.y) );
e.x = (sc * d.x + sd * c.x) / (sc + sd);
e.y = (sc * d.y + sd * c.y) / (sc + sd);
} //兩線段規范相交時,求交點坐標
int linesegIntersect(const Point &a, const Point &b, const Point &c, const Point &d) {
int c_ab = cross(c,a,b);
if(c_ab == 0) return 2;
int d_ab = cross(d,a,b);
if(d_ab == 0) return 2;
if(c_ab ^ d_ab == -2)
return 1;
return 0;
} //直線ab和線段cd相交情況:0——不相交,1——規范相交,2——不規范相交(交于端點或重合)
int lineIntersect(const Point &a, const Point &b, const Point &c, const Point &d) {
if(dblcmp(det(b.x-a.x, b.y-a.y, d.x-c.x, d.y-c.y)) != 0)
return 1;
if(cross(a,c,d) == 0)
return 2;
return 0;
} //兩直線相交情況:0——平行,1——規范相交,2——不規范相交(重合)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -