计算几何基础
来源:互联网 发布:手机库存软件 编辑:程序博客网 时间:2024/04/29 04:03
1.多边形面积计算
double S(Point p[],int n){ double ans = 0; p[n] = p[0]; for(int i=1;i<n;i++) ans += cross(p[0],p[i],p[i+1]); if(ans < 0) ans = -ans; return ans / 2.0;}
2.求凸包
bool cmp(Point A,Point B){ double k = cross(MinA,A,B); if(k<0) return 0; if(k>0) return 1; return dist(MinA,A)<dist(MinA,B);}void Graham(Point p[],int n){ for(int i=1;i<n;i++) if(p[i].y<p[0].y || (p[i].y == p[0].y && p[i].x < p[0].x)) swap(p[i],p[0]); MinA = p[0]; p[n] = p[0]; sort(p+1,p+n,cmp); stack[0] = p[0]; stack[1] = p[1]; top = 2; for(int i=2;i<n;i++) { while(top >= 2 && cross(stack[top-2],stack[top-1],p[i])<=0) top--; stack[top++] = p[i]; }}
3.任意多边形求重心
Point Gravity(Point p[],int n){ Point O,t; O.x = O.y = 0; t.x = t.y = 0; p[n] = p[0]; double A = 0; for(int i=0; i<n; i++) A += cross(O,p[i],p[i+1]); A /= 2.0; for(int i=0; i<n; i++) { t.x += (p[i].x + p[i+1].x) * cross(O,p[i],p[i+1]); t.y += (p[i].y + p[i+1].y) * cross(O,p[i],p[i+1]); } t.x /= 6*A; t.y /= 6*A; return t;}
4.求线段交点的坐标
bool Segment_crossing(Segment u,Segment v) /** 判断线段是否相交 */{ return((max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&& (max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&& (max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&& (max(v.a.y,v.b.y)>=min(u.a.y,u.b.y))&& (cross(v.a,u.b,u.a)*cross(u.b,v.b,u.a)>=0)&& (cross(u.a,v.b,v.a)*cross(v.b,u.b,v.a)>=0));}/**求直线交点的坐标,如果没有交点返回NULL,否则返回交点p的地址*/Point* CrossPoint(Segment u,Segment v){ Point p; if(Segment_crossing(u,v)) { p.x=(cross(v.b,u.b,u.a)*v.a.x-cross(v.a,u.b,u.a)*v.b.x)/(cross(v.b,u.b,u.a)-cross(v.a,u.b,u.a)); p.y=(cross(v.b,u.b,u.a)*v.a.y-cross(v.a,u.b,u.a)*v.b.y)/(cross(v.b,u.b,u.a)-cross(v.a,u.b,u.a)); return &p; } return NULL;}
5.三角形外接圆的半径与圆心
Point Circle_Point(Point A,Point B,Point C){ double a=dist(B,C); double b=dist(A,C); double c=dist(A,B); double p=(a+b+c)/2.0; double S=sqrt(p*(p-a)*(p-b)*(p-c)); R=(a*b*c)/(4*S); //三角形外接圆的半径为R double t1=(A.x*A.x+A.y*A.y-B.x*B.x-B.y*B.y)/2; double t2=(A.x*A.x+A.y*A.y-C.x*C.x-C.y*C.y)/2; Point center; center.x=(t1*(A.y-C.y)-t2*(A.y-B.y))/((A.x-B.x)*(A.y-C.y)-(A.x-C.x)*(A.y-B.y)); center.y=(t1*(A.x-C.x)-t2*(A.x-B.x))/((A.y-B.y)*(A.x-C.x)-(A.y-C.y)*(A.x-B.x)); return center;}
6.旋转卡壳求凸包的直径,也就是平面最远点对,p[]为凸包的点集
double rotating_calipers(Point p[],int n){ int k = 1; double ans = 0; p[n] = p[0]; for(int i=0;i<n;i++) { while(fabs(cross(p[i],p[i+1],p[k])) < fabs(cross(p[i],p[i+1],p[k+1]))) k = (k+1) % n; ans = max(ans, max(dist(p[i],p[k]),dist(p[i+1],p[k]))); } return ans;}
7.求凸包的宽度
double rotating_calipers(Point p[],int n){ int k = 1; double ans = 0x7FFFFFFF; p[n] = p[0]; for(int i=0;i<n;i++) { while(fabs(cross(p[i],p[i+1],p[k])) < fabs(cross(p[i],p[i+1],p[k+1]))) k = (k+1) % n; double tmp = fabs(cross(p[i],p[i+1],p[k])); double d = dist(p[i],p[i+1]); ans = min(ans,tmp/d); } return ans;}
8. 求线段与圆的交点
#include <iostream>#include <stdio.h>#include <vector>#include <math.h>using namespace std;const double eps = 1e-8;struct Point{ double x, y;};struct Segment{ Point s, t;};struct Circle{ Point c; double r;};vector<Point> LineToCircle(Segment line, Circle circle){ vector<Point> v; v.clear(); double fd = sqrt((line.s.x - line.t.x) * (line.s.x - line.t.x) + (line.s.y - line.t.y) * (line.s.y - line.t.y)); Point d; d.x = (line.t.x - line.s.x) / fd; d.y = (line.t.y - line.s.y) / fd; Point e; e.x = circle.c.x - line.s.x; e.y = circle.c.y - line.s.y; double a = e.x * d.x + e.y * d.y; double a2 = a * a; double e2 = e.x * e.x + e.y * e.y; double r2 = circle.r * circle.r; v.push_back(line.s); if(r2 - e2 + a2 > -eps) { double f = sqrt(r2 - e2 + a2); double t = a - f; if((t > -eps) && (t - fd) < eps) { Point tmp; tmp.x = line.s.x + t * d.x; tmp.y = line.s.y + t * d.y; v.push_back(tmp); } t = a + f; if((t > -eps) && (t - fd) < eps) { Point tmp; tmp.x = line.s.x + t * d.x; tmp.y = line.s.y + t * d.y; v.push_back(tmp); } } v.push_back(line.t); return v;}int main(){ Segment line; Circle circle; line.s.x = -1.0; line.s.y = -1.0; line.t.x = 1.0; line.t.y = 1.0; circle.c.x = 0.0; circle.c.y = 0.0; circle.r = 2.0; vector<Point> p = LineToCircle(line, circle); for(int i = 0; i < p.size(); i++) printf("%lf %lf\n", p[i].x, p[i].y); return 0;}
现在有这样一个问题,平面上给定n个点,确定一对平行线,使得所有的点都在平行线之间,求这对平行线的最近距
离。这个问题实际上就是求点集的凸包宽度。
- 计算几何基础
- [基础]计算几何
- 计算几何基础
- 计算几何 基础
- 基础算法--计算几何
- 计算几何基础
- 计算几何基础
- 计算几何-基础篇
- 计算几何基础
- 计算几何基础题目
- 基础算法--计算几何
- Segments(计算几何基础)
- 二维计算几何基础
- 二维计算几何基础
- (7)计算几何基础
- Training:计算几何基础
- 计算几何基础
- 专题:基础计算几何
- 发点小牢骚!
- Box2D C++教程-介绍
- 弹出窗体大全
- JPA
- 我在南大的七年
- 计算几何基础
- .net导出Excel设置颜色font.ColorIndex 各颜色编号
- Box2D C++教程-配置环境(windows)
- 成功法则 --
- 让每一个人在大变革的潮流中奋勇直追
- 第七章 09_Map_1
- no Qt version assigned to this project for platform Win32
- POJ 2992 Divisors
- jdk环境变量配置