您的位置:首页 > 其它

计算几何模板

2012-10-11 11:18 302 查看
今天整理资料,发现了一些比较好的计算几何模板。
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#define MAX_N 100
using namespace std;
//常量区
const double INF = 1e10; // 无穷大
const double EPS = 1e-15; // 计算精度
const int LEFT = 0; // 点在直线左边
const int RIGHT = 1; // 点在直线右边
const int ONLINE = 2; // 点在直线上
const int CROSS = 0; // 两直线相交
const int COLINE = 1; // 两直线共线
const int PARALLEL = 2; // 两直线平行
const int NOTCOPLANAR = 3; // 两直线不共面
const int INSIDE = 1; // 点在图形内部
const int OUTSIDE = 2; // 点在图形外部
const int BORDER = 3; // 点在图形边界
const int BAOHAN = 1; // 大圆包含小圆
const int NEIQIE = 2; // 内切
const int XIANJIAO = 3; // 相交
const int WAIQIE = 4; // 外切
const int XIANLI = 5; // 相离
//类型定义区
typedef vector<Point> Polygon; // 二维多边形
typedef vector<Point> Points; // 二维点集
typedef vector<Point3D> Points3D; // 三维点集
//基本函数区
inline double max(double x,double y)
inline double min(double x, double y)
inline bool ZERO(double x) // x == 0
inline bool ZERO(Point p) // p == 0
inline bool ZERO(Point3D p) // p == 0
inline bool EQ(double x, double y) // eqaul, x == y
inline bool NEQ(double x, double y) // not equal, x != y
inline bool LT(double x, double y) // less than, x < y
inline bool GT(double x, double y) // greater than, x > y
inline bool LEQ(double x, double y) // less equal, x <= y
inline bool GEQ(double x, double y) // greater equal, x >= y
// 注意!!!
// 如果是一个很小的负的浮点数
// 保留有效位数输出的时候会出现-0.000这样的形式,
// 前面多了一个负号
// 这就会导致错误!!!!!!
// 因此在输出浮点数之前,一定要调用次函数进行修正!
inline double FIX(double x)
//二维矢量运算
bool operator==(Point p1, Point p2)
bool operator!=(Point p1, Point p2)
bool operator<(Point p1, Point p2)
Point operator+(Point p1, Point p2)
Point operator-(Point p1, Point p2)
double operator*(Point p1, Point p2) // 计算叉乘 p1 × p2
double Norm(Point p) // 计算矢量p的模
// 把矢量p旋转角度angle (弧度表示)
// angle > 0表示逆时针旋转
// angle < 0表示顺时针旋转
Point Rotate(Point p, double angle)
//三维矢量运算
bool operator==(Point3D p1, Point3D p2)
bool operator<(Point3D p1, Point3D p2)
Point3D operator+(Point3D p1, Point3D p2)
Point3D operator-(Point3D p1, Point3D p2)
Point3D operator*(Point3D p1, Point3D p2) // 计算叉乘 p1 x p2
double Norm(Point3D p) // 计算矢量p的模

//几何题面积计算
//
// 根据三个顶点坐标计算三角形面积
// 面积的正负按照右手旋规则确定
double Area(Point A, Point B, Point C) //三角形面积
// 根据三条边长计算三角形面积
double Area(double a, double b, double c) //三角形面积
double Area(const Circle & C)
// 计算多边形面积
// 面积的正负按照右手旋规则确定
double Area(const Polygon& poly) //多边形面积
//点.线段.直线问题
//
double Distance(Point p1, Point p2) //2点间的距离
double Distance(Point3D p1, Point3D p2) //2点间的距离,三维
double Distance(Point p, Line L) // 求二维平面上点到直线的距离
double Distance(Point3D p, Line3D L)// 求三维空间中点到直线的距离
bool OnLine(Point p, Line L) // 判断二维平面上点p是否在直线L上
bool OnLine(Point3D p, Line3D L) // 判断三维空间中点p是否在直线L上
int Relation(Point p, Line L) // 计算点p与直线L的相对关系 ,返回ONLINE,LEFT,RIGHT
bool SameSide(Point p1, Point p2, Line L) // 判断点p1, p2是否在直线L的同侧
bool OnLineSeg(Point p, Line L) // 判断二维平面上点p是否在线段l上
bool OnLineSeg(Point3D p, Line3D L) // 判断三维空间中点p是否在线段l上
Point SymPoint(Point p, Line L) // 求二维平面上点p关于直线L的对称点
bool Coplanar(Points3D points) // 判断一个点集中的点是否全部共面
bool LineIntersect(Line L1, Line L2) // 判断二维的两直线是否相交
bool LineIntersect(Line3D L1, Line3D L2) // 判断三维的两直线是否相交
bool LineSegIntersect(Line L1, Line L2) // 判断二维的两条线段是否相交
bool LineSegIntersect(Line3D L1, Line3D L2) // 判断三维的两条线段是否相交
// 计算两条二维直线的交点,结果在参数P中返回
// 返回值说明了两条直线的位置关系: COLINE -- 共线 PARALLEL -- 平行 CROSS -- 相交
int CalCrossPoint(Line L1, Line L2, Point& P)
// 计算两条三维直线的交点,结果在参数P中返回
// 返回值说明了两条直线的位置关系 COLINE -- 共线 PARALLEL -- 平行 CROSS -- 相交 NONCOPLANAR -- 不公面
int CalCrossPoint(Line3D L1, Line3D L2, Point3D& P)
// 计算点P到直线L的最近点
Point NearestPointToLine(Point P, Line L)
// 计算点P到线段L的最近点
Point NearestPointToLineSeg(Point P, Line L)
// 计算险段L1到线段L2的最短距离
double MinDistance(Line L1, Line L2)
// 求二维两直线的夹角,
// 返回值是0~Pi之间的弧度
double Inclination(Line L1, Line L2)
// 求三维两直线的夹角,
// 返回值是0~Pi之间的弧度
double Inclination(Line3D L1, Line3D L2)
//多边行问题:
//
// 判断点p是否在凸多边形poly内
// poly的顶点数目要大于等于3
// 返回值为:
// INSIDE -- 点在poly内
// BORDER -- 点在poly边界上
// OUTSIDE -- 点在poly外
int InsideConvex(Point p, const Polygon& poly) // 判断点p是否在凸多边形poly内

// 判断多边形poly是否是凸的
bool IsConvex(const Polygon& poly) // 判断多边形poly是否是凸的
// 判断点p是否在简单多边形poly内, 多边形可以是凸的或凹的
// poly的顶点数目要大于等于3
// 返回值为:
// INSIDE -- 点在poly内
// BORDER -- 点在poly边界上
// OUTSIDE -- 点在poly外
int InsidePolygon(const Polygon& poly, Point p) // 判断点p是否在简单多边形poly内, 多边形可以是凸的或凹的
// 判断线段是否在多边形内 (线段的点可能在多边形上)
// 多边形可以是任意简单多边形
bool InsidePolygon(const Polygon& poly, Line L) // 判断线段是否在多边形内 (线段的点可能在多边形上)
// 寻找凸包 graham 扫描法
// 生成的多边形顶点按逆时针方向排列
bool GrahamComp(const Point& left, const Point& right)

void GrahamScan(Points& points, Polygon& result)
// 用有向直线line切割凸多边形,
// result[LEFT]和result[RIGHT]分别保存被切割后line的左边和右边部分
// result[ONLINE]没有用到,只是用来作为辅助空间
// 返回值是切割多边形的切口的长度,
// 如果返回值是0 则说明未作切割。
// 当未作切割时,如果多边形在该直线的右侧,则result[RIGHT]等于该多边形,否则result[LEFT]等于该多边形
// 注意:被切割的多边形一定要是凸多边形,顶点按照逆时针排列
// 可利用这个函数来求多边形的核,初始的核设为一个很大的矩形,然后依次用多边形的每条边去割
double CutConvex(const Polygon& poly, const Line& line, Polygon result[3])
// 求多边形的重心,适用于凸的或凹的简单多边形
// 该算法可以一边读入多边性的顶点一边计算重心
Point CenterOfPolygon(const Polygon& poly)
// 判断两个矩形是否相交
// 如果相邻不算相交
bool Intersect(Rect_2 r1, Rect_2 r2)
// 判断矩形r2是否可以放置在矩形r1内
// r2可以任意地旋转
//发现原来的给出的方法过不了OJ上的无归之室这题,
//所以用了自己的代码
bool IsContain(Rect r1, Rect r2) //矩形的w>h
//圆
Point Center(const Circle & C) //圆心

double CommonArea(const Circle & A, const Circle & B) //两个圆的公共面积

bool IsInCircle(const Circle & C, const Rect_2 & rect)//判断圆是否在矩形内(不允许相切)

//判断2圆的位置关系
//返回:
//BAOHAN = 1; // 大圆包含小圆
//NEIQIE = 2; // 内切
//XIANJIAO = 3; // 相交
//WAIQIE = 4; // 外切
//XIANLI = 5; // 相离
int CirCir(const Circle &c1, const Circle &c2)//判断2圆的位置关系
{
double dis = Distance(c1.c,c2.c);
if(LT(dis,fabs(c1.r-c2.r))) return BAOHAN;
if(EQ(dis,fabs(c1.r-c2.r))) return NEIQIE;
if(LT(dis,c1.r+c2.r) && GT(dis,fabs(c1.r-c2.r))) return XIANJIAO;
if(EQ(dis,c1.r+c2.r)) return WAIQIE;
return XIANLI;
}
////////////////////////////////////////////////////////////////////////
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: