zoukankan      html  css  js  c++  java
  • 计算几何基础

    记录点滴。

      1 /*
      2 2015.6    HT
      3 ACM Work_8
      4 
      5 */
      6 
      7 #include <iostream>
      8 #include <cstdio>
      9 using namespace std;
     10 
     11 /*
     12 线段判交--ACM
     13 
     14 1.快速排斥实验
     15 设以线段P1P2和线段Q1Q2为对角线的矩形为M,N;若M,N 不相交,则两个线段显然不相交;
     16 2.跨立实验
     17 如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2,则矢量(P1-Q1)和(P2-Q1)位于矢量(Q2-Q1)的两侧,
     18 即(P1-Q1)×(Q2-Q1)*(P2-Q1)×(Q2-Q1)<0,上式可改写成(P1-Q1)×(Q2-Q1)*(Q2-Q1)×(P2-Q1)>0。
     19 当(P1-Q1)×(Q2-Q1)=0时,说明(P1-Q1)和(Q2-Q1)共线,但是因为已经通过快速排斥试验,所以P1一定在线段Q1Q2上;
     20 同理,(Q2-Q1)×(P2-Q1)=0说明P2一定在线段Q1Q2上。
     21 所以判断P1P2跨立Q1Q2的依据是:(P1-Q1)×(Q2-Q1)*(Q2-Q1)×(P2-Q1)>=0。
     22 
     23 */
     24 
     25 /*
     26 You can Solve a Geometry Problem too
     27 判断两条线段是否相交
     28 
     29 向量 p1*p2 = x1y2 – y1x2 = -p2*p1
     30 */
     31 //struct Line
     32 //{
     33 //    double x1, y1, x2, y2;
     34 //}lines[110];
     35 //
     36 //bool isCross(Line a, Line b)
     37 //{
     38 //    if (((a.x1 - b.x1)*(a.y2 - b.y1) - (a.x2 - b.x1)*(a.y1 - b.y1)) * ((a.x1 - b.x2)*(a.y2 - b.y2) 
     39 //        - (a.x2 - b.x2)*(a.y1 - b.y2))>0)
     40 //        return false;
     41 //    if (((b.x1 - a.x1)*(b.y2 - a.y1) - (b.x2 - a.x1)*(b.y1 - a.y1)) * ((b.x1 - a.x2)*(b.y2 - a.y2) 
     42 //        - (b.x2 - a.x2)*(b.y1 - a.y2))>0)
     43 //        return false;
     44 //    return true;
     45 //}
     46 //
     47 //int main()
     48 //{
     49 //    int n;
     50 //    while (cin >> n && n)
     51 //    {
     52 //        int i;
     53 //        for (i = 0; i < n; ++i)
     54 //        {
     55 //            cin >> lines[i].x1 >> lines[i].y1 >> lines[i].x2 >> lines[i].y2;
     56 //        }
     57 //        int j;
     58 //        int ans = 0;
     59 //        for (i = 0; i < n; ++i)
     60 //        {
     61 //            for (j = i + 1; j < n; ++j)
     62 //            {
     63 //                if (isCross(lines[i], lines[j]) == true)
     64 //                {
     65 //                    ans++;
     66 //                }
     67 //            }
     68 //        }
     69 //        cout << ans << endl;
     70 //    }
     71 //    return 0;
     72 //}
     73 
     74 
     75 
     76 /*
     77 改革春风吹满地
     78 
     79 求多边形面积
     80 s = 1/2 * (求和i=0~(n-1)) { Xi*Y(i+1) - X(i+1)*Yi }
     81 逆时针给出点坐标,值为正
     82 顺时针给出点坐标,值为负
     83 */
     84 //int main()
     85 //{
     86 //    int n;
     87 //    int a[100], b[100], i;
     88 //    double s;
     89 //    while (cin >> n && n)
     90 //    {
     91 //        s = 0;
     92 //        for (i = 0; i < n; i++)
     93 //            cin >> a[i] >> b[i];
     94 //        a[n] = a[0];
     95 //        b[n] = b[0];
     96 //        for (i = 0; i<n; i++)
     97 //            s += (a[i] * b[i + 1] - a[i + 1] * b[i]);
     98 //        printf_s("%.1lf
    ", s / 2);
     99 //    }
    100 //    return 0;
    101 //}
    102 
    103 
    104 
    105 /*
    106 Shape of HDU
    107 
    108 判断该多边形是凸多边形还是凹多边形
    109 */
    110 //struct point
    111 //{
    112 //    int x, y;
    113 //};
    114 //
    115 ///*
    116 //两个向量 a-> (p1.x-p0.x, p1.y-p0.y)  和 b->(p2.x-p1.x, p2.y-p1.y)
    117 //两个向量叉积 (a.x*b.y - a.y*b.x)
    118 //叉积结果 >0 ,则向量 a 在向量 b的顺时针方向; <0则相反; 等于0则在同一直线
    119 //*/
    120 //double cross(point p0, point p1, point p2)
    121 //{
    122 //    return (p1.x - p0.x)*(p2.y - p1.y) - (p1.y - p0.y)*(p2.x - p1.x);
    123 //}
    124 //
    125 //int main()
    126 //{
    127 //    int n;
    128 //    point p[1010];
    129 //    while (scanf_s("%d", &n) && n)
    130 //    {
    131 //        int i, flag = 0;
    132 //        for (i = 0; i<n; i++)
    133 //        {  
    134 //            scanf_s("%d%d", &p[i].x, &p[i].y);
    135 //        }
    136 //        p[n] = p[0];
    137 //        p[n + 1] = p[1]; // 增加两个点代表最开始的两个点,以形成循环 
    138 //        for (i = 2; i <= n + 1; i++)
    139 //        {
    140 //            if (cross(p[i - 2], p[i - 1], p[i])<0) 
    141 //                flag = 1;
    142 //        }
    143 //        if (!flag)
    144 //            printf_s("convex
    ");
    145 //        else 
    146 //            printf_s("concave
    ");
    147 //    }
    148 //    return 0;
    149 //}
    150 
    151 
    152 
    153 /*
    154 Surround the Trees
    155 
    156 */
    157 #define MAXD 110
    158 
    159 typedef struct
    160 {
    161     double x, y;
    162 }point;
    163 point Tree[MAXD], Result[MAXD];
    164 int N, P;
    165 
    166 /*
    167 叉乘
    168 P1 x P2
    169 >0 : P1 is clockwise from P2 with respect to (0,0)
    170 <0 : counterclockwise (即P1在P2左边)
    171 =0 : collinear
    172 */
    173 double cross(double x1, double y1, double x2, double y2)
    174 {
    175     return x1 * y2 - x2 * y1;
    176 }
    177 
    178 // 按 y坐标从低到高排序,若 y相等则按 x坐标排序
    179 int cmp(const void *_p, const void *_q)
    180 {
    181     point *p = (point *)_p, *q = (point *)_q;
    182     if (p->y == q->y)
    183         return p->x < q->x ? -1 : 1;
    184 
    185     return p->y < q->y ? -1 : 1;
    186 }
    187 
    188 double Distance(double x, double y, double x1, double y1)
    189 {
    190     double temp1 = (x - x1)*(x - x1);
    191     double temp2 = (y - y1)*(y - y1);
    192     return sqrt(temp1 + temp2);
    193 }
    194 
    195 double sqr(double x)
    196 {
    197     return x * x;
    198 }
    199 
    200 // 是否删除
    201 int del(int top, int i)
    202 {
    203     if (cross(Result[top].x - Result[top - 1].x, Result[top].y - Result[top - 1].y,
    204         Tree[i].x - Result[top].x, Tree[i].y - Result[top].y) < 0)
    205         return 1;
    206     return 0;
    207 }
    208 
    209 int graham()
    210 {
    211     int i, mint, top = 1;
    212     Result[0] = Tree[0];
    213     Result[1] = Tree[1];
    214     for (i = 2; i < N; i++)
    215     {
    216         while (top && del(top, i))
    217             --top;
    218         Result[++top] = Tree[i];
    219     }
    220     mint = top;
    221     Result[++top] = Tree[N - 2];
    222     for (i = N - 3; i >= 0; i--)
    223     {
    224         while (top != mint && del(top, i))
    225             --top;
    226         Result[++top] = Tree[i];
    227     }
    228     return top;
    229 }
    230 
    231 int main()
    232 {
    233     int i;
    234     double sum;
    235     while (1)
    236     {
    237         cin >> N;
    238         if (!N)
    239             break;
    240 
    241         for (i = 0; i < N; i++)
    242             cin >> Tree[i].x >> Tree[i].y;
    243 
    244         // 快排
    245         qsort(Tree, N, sizeof(Tree[0]), cmp);
    246         sum = 0;
    247 
    248         if (N == 1)
    249             printf_s("0.00
    ");
    250         else if (N == 2)
    251         {
    252             sum = Distance(Tree[0].x, Tree[0].y, Tree[1].x, Tree[1].y);
    253             printf_s("%.2f
    ", sum);
    254         }
    255         else
    256         {
    257             P = graham();
    258             for (i = 0; i < P; i++)
    259                 sum += Distance(Result[i].x, Result[i].y, Result[i + 1].x, Result[i + 1].y);
    260             printf_s("%.2f
    ",sum);
    261         }
    262     }
    263     return 0;
    264 }
  • 相关阅读:
    python3.x学习笔记2018-02-05更新
    网络安全学习资源整理2018-02-02更新
    隔行变色效果
    自制滚动条
    关于ico图标
    CSS实现标题/段落省略效果的三剑客
    第三章(循环) 编程题 2
    第三章(循环) 编程题
    python基础03--基本数据类型(字符串)
    python基础02--运算符与基本数据类型(数字)
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4572802.html
Copyright © 2011-2022 走看看