计算几何--二维几何基础练习

内容参考书籍——《算法竞赛入门经典训练指南》

例题1 题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2119

  莫利定理(Morley‘s theorem),也称为莫雷角三分线定理。将三角形的三个内角三等分,靠近某边的两条三分角线相交得到一个交点,则这样的三个交点可以构成一个正三角形。这个三角形常被称作莫利正三角形。

本题无算法可言,暴力求解即可(根据夹角根据旋转三角形的边,求出交点即为答案)。

代码如下:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 struct Point
  4 {
  5     double x,y;
  6     Point(double x=0, double y=0):x(x),y(y) {}//构造函数,方便编写代码
  7 };
  8 typedef Point Vector;//别名
  9 //向量+向量=向量,点+向量=点
 10 Vector operator + (Vector A, Vector B){return Vector(A.x+B.x,A.y+B.y);}
 11 //点-点=向量
 12 Vector operator - (Vector A, Vector B){return Vector(A.x-B.x,A.y-B.y);}
 13 //向量*数=向量
 14 Vector operator * (Vector A, double p){return Vector(A.x*p,A.y*p);}
 15 //向量/数=向量
 16 Vector operator / (Vector A, double p){return Vector(A.x/p,A.y/p);}
 17
 18 bool operator < (const Point& a, const Point& b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
 19
 20 const double eps = 1e-10;
 21 int dcmp(double x)
 22 {
 23     if (fabs(x) < eps) return 0;
 24     else return x < 0 ? -1 : 1;
 25 }
 26
 27 bool operator == (const Point& a, const Point &b){return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;}
 28
 29 //计算点积、向量长度、夹角函数
 30 double Dot(Vector A, Vector B){return A.x*B.x+A.y*B.y;}
 31 double Length(Vector A){return sqrt(Dot(A,A));}
 32 double Angle(Vector A, Vector B){return acos(Dot(A,B)/Length(A)/Length(B));}
 33
 34 //计算叉积
 35 double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}
 36 double Area2(Point A, Point B, Point C){return Cross(B-A,C-A);}
 37
 38 //计算旋转和单位法向量
 39 //rad为弧度
 40 Vector Rotate(Vector A, double rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}
 41 Vector Normal(Vector A)
 42 {
 43     double L =Length(A);
 44     return Vector(-A.y/L,A.x/L);
 45 }
 46
 47 //交点,注意精度问题
 48 //调用该函数前请确保两条直线P+tv和Q+tw有唯一交点。当且仅当Cross(v,w)非0
 49 Point GetLineIntersection(Point P, Vector v, Point Q, Vector w)
 50 {
 51     Vector u = P-Q;
 52     double t = Cross(w,u) / Cross(v,w);
 53     return P+v*t;
 54 }
 55 //点到直线的距离。用叉积计算。平行四边形的面积除以底
 56 double DistanceToLine(Point P, Point A, Point B)
 57 {
 58     Vector v1 = B-A,v2= P-A;
 59     return fabs(Cross(v1,v2)) / Length(v1);
 60 }
 61 //点到线段的距离
 62 double DistanceToSegment(Point P, Point A, Point B)
 63 {
 64     if (A==B) return Length(P-A);
 65     Vector v1 = B-A,v2 = P-A,v3=P-B;
 66     if (dcmp(Dot(v1,v2))<0) return Length(v2);
 67     else if (dcmp(Dot(v1,v3))>0) return Length(v3);
 68     else return fabs(Cross(v1,v2)) / Length(v1);
 69 }
 70 //计算投影点
 71 Point GetLineProjection(Point P, Point A, Point B)
 72 {
 73     Vector v = B-A;
 74     return A+v*(Dot(v,P-A) / Dot(v,v));
 75 }
 76 //按“相交规范”判断相交
 77 bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
 78 {
 79     double c1 = Cross(a2-a1,b1-a1),c2 = Cross(a2-a1,b2-a1),
 80     c3 = Cross(b2-b1,a1-b1),c4 = Cross(b2-b1,a2-b1);
 81     return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
 82 }
 83 //允许在端点处相交,判断是否发生加入下面一段判断一个点是否在一条线段上的代码
 84 bool OnSegment(Point P,Point a1, Point a2)
 85 {
 86     return dcmp(Cross(a1-P,a2-P)) == 0 && dcmp(Dot(a1-P,a2-P))<0;
 87 }
 88 //多边形的有向面积
 89 double PolygonArea(Point* p, int n)
 90 {
 91     double area = 0;
 92     for (int i = 1; i < n-1; ++i)
 93     {
 94         area +=Cross(p[i]-p[0],p[i+1]-p[0]);
 95     }
 96     return area/2;
 97 }
 98 Point GetDaan(Point A,Point B,Point C)
 99 {
100     //bc逆时针转
101     Vector v1 = C-B;//直线方向向量
102     double a1=Angle(A-B,v1);
103     v1 = Rotate(v1,a1/3);
104     //bc顺时针转
105     Vector v2 = B-C;
106     double a2=Angle(A-C,v2);
107     v2 = Rotate(v2,-a2/3);//负数表示顺时针旋转
108
109     return GetLineIntersection(B,v1,C,v2);
110 }
111 int main(int argc, char const *argv[])
112 {
113     int t;
114     cin>>t;
115     while(t--)
116     {
117         Vector a,b,c;
118         Vector d,e,f;//答案
119         cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y;
120         d=GetDaan(a,b,c);
121         e=GetDaan(b,c,a);
122         f=GetDaan(c,a,b);
123         printf("%.6f %.6f %.6f %.6f %.6f %.6f\n",d.x,d.y,e.x,e.y,f.x,f.y);
124     }
125     return 0;
126 }

例题2题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=submit_problem&problemid=2896&category=0

  已知两狗以恒定速度奔跑但速度未知,同时出发同时达到,已知各自起点折线跑过程中的拐点和终点,求狗距。狗距=(奔跑过程中的最大距离减去最小距离)。

  首先,我们考虑两条狗直线奔跑,那么我们可以认为一条狗不动,另外一条狗相对于这条狗奔跑。即问题转化为,求一个点到一条线段的最短距离和最大距离。

  现在我们来模拟整个过程,用pa和pb来记录当前两条狗的位置,sa和sb为各自拐点的编号,每一次我们计算这两条狗谁先到达下一个拐点,那么在他到达下一个拐点的这段时间里便是上面说的直线奔跑的情况,不断跟新pa,pb,sa,sb,以及狗距最后的的结果便是答案。

代码如下(待更新)

原文地址:https://www.cnblogs.com/125418a/p/11595262.html

时间: 2024-10-03 22:29:54

计算几何--二维几何基础练习的相关文章

计算几何 二维凸包问题 Andrew算法

凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把所有点排序,按照第一关键字x第二关键字y从小到大排序,删除重复点后得到点序列P1...Pn. 1)把P1,P2放入凸包中,凸包中的点使用栈存储 2)从p3开始,当下一个点在凸包当前前进方向(即直线p1p2)左边的时候继续: 3)否则依次删除最近加入凸包的点,直到新点在左边. 如图,新点P18在当前前进方向P10P15的右边(使用叉积判断),因此需要从凸包上删除点P15和P10

二维几何基础

1. 点.线.凸边形 1 /******************************************************* 2 二维几何基础 3 [注意]数组下标从1开始. 4 *******************************************************/ 5 6 #include <iostream> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cma

计算几何--二维几何常用算法

内容参考书籍——<算法竞赛入门经典训练指南> 在程序中,用顶点数组表示多边形,其中各个顶点按照逆时针顺序排列. 判断点是否在多边形内.采用转角法,基本思想是计算多边形相对于判定点转了多少度,具体来说,将多边形每条边的转角加起来,如果是360°,说明在多边形内:如果是0°,说明在多边形如果是180°则在多边形边界上.该方法在处理一些弧形多边形时丝毫不受影响,只需要每一段的终点到起点的转角累加起来即可.另外这个三角形甚至可以不是简单多边形(即可以自交). 然而,直接计算会使用大量的反三角函数,不仅

二维向量的叉积是标量还是向量?

今天学习了一下<计算几何>,里面讲了一下关于判断一个点是否在某个三角形内的问题(在二维平面上).其中有一个算法是“同向法”,主要是用叉积来判断两个点是否在某条线段的同一侧,如图(1)所示.关于“同向法”再次不做具体介绍,感兴趣的同学可以百度之,或者关注本人后面更新的博文.关于<计算几何>系列的博文,我会继续学习,总结并发布到博客上. 图1 好了,言归正传,我们只知道在二维平面中,两个向量的叉乘其结果(叉积)是一个确切的值.例如向量A(x1,y1)和向量B(x2,y2)叉乘:A(x1

【题解】二维凸包

[题解]二维凸包 呵呵呵复习一下这个东西免得做到计算几何连暴力都不会嘤嘤嘤 免得到时候写斜率优化结果凸包不会了嘤嘤嘤 数学走起: \[ \vec{a}=(x_1,y_1),\vec{b}=(x_2,y_2) \shadow_{|\vec{a} \times\vec{b}|}=x_1y_2-x_2y_1 \] 根据右手螺旋定则.\(shadow\)是我乱搞的符号,虽然我搞不懂为什么是这样,但是这个应该和\(\sin(0.5\pi)=1,\sin0=0\)有关,就不纠结了,也比较好记. 遵循\(an

二维码扫码积分系统定制开发

微信积分系统 二维码扫码积分系统定制开发找丽姐[158.1816.6626/电微]二维码营销模式系统定制开发 微信扫二维码营销系统开发 扫码领积分系统开发 一.如何实现扫二维码领红包功能? 1.使用扫描二维码领取红包对活动进行设置,包括红包数量.红包金额.促销地区.中奖概率等. 2.将生成的二维码赋到商品上面并赋涂层,一方面可以起到保证二维码的一次性,另一方面也可以引起消费者的好奇心. 3.通过手机微信打开扫一扫,扫码商品二维码关注公众号并领取红包,如果参与分享还可以获得抽奖的机会. 二.微信扫

微信生成二维码 只需一个网址即刻 还有jquery生成二维码

<div class="orderDetails-info"> <img src="http://qr.topscan.com/api.php?text=http://123.net/index.php?s=/Home/Index/yanzheng/mai/{$dange.id}" style="width: 5rem; margin-bottom: 1rem;" > </div> http://qr.tops

家电二维码售后服务平台系统开发

家电二维码售后服务平台系统开发,家电二维码售后系统开发,小吴183.2071.6434微电,家电二维码售后软件开发,家电二维码售后平台开发. 互联网平台的节点有两大类型:第一基数节点,也就是弱连接的节点,其规模要大,越大越好,互联网的价值与节点数的平比成正比.第二活跃节点,也就是强连接的节点,其能量要强,越强越好,互联网的价值与其强度成正比. 一.家电维修行业"维修黑幕"层出不穷 记者从一位从事家电维修人士那里了解到,目前行业公认当前家电维修行业有陷阱,"维修黑幕"

微信小程序(4)--二维码窗口

微信小程序二维码窗口: <view class="btn" bindtap="powerDrawer" data-statu="open">button</view> <!--mask--> <view class="drawer_screen" bindtap="powerDrawer" data-statu="close" wx:if=&qu