`
yzmduncan
  • 浏览: 330828 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论
阅读更多

    计算几何是研究几何目标在计算机环境内的数学表示,计算等方面的理论和应用。

    首先必须理解向量的点积和叉积。点积一般用来计算投影,数学证明等。叉积用来判断相对方位,求面积等,叉积的模为平行四边形面积。

    问题1. 如何判断两条线段相交

   通过快速排斥实验和跨立实验。快速排斥实验室看以两条线段作为对角线的矩形是否相交,若不相交,则必定两条线段不相交;跨立实验是看其中一条线段是否跨立另一条线段,可以通过矢量叉积实现。



 

   问题2. 如何判断点在多边形内(ZOJ1081

   一种简单的方法——射线法。从该点引一条水平射线,根据射线与多边形的交点数的奇偶性来判断。注意一些特殊情况。

   问题3. 如何求任意简单多边形面积(凸或者凹)

   根据矢量的叉积求解。按顺时针or逆时针将多边形顶点排序,构造向量pi=(xi,yi),相当于从原点到多边形顶点的向量。将这些向量叉乘,最后取绝对值除以2就是多边形面积。



 

   问题4. 如何求凸包(POJ1113)

   Graham扫描法求凸包:

   a. 选择基点。首先将所有点按y坐标从小到大排序,若y坐标一样,再按x坐标排序。总之,基点就是最下最左的点。

   b. 将其余点和基点构成的向量按极角排序(逆时针),极角一样的,按照距离从小到大排。

   c. 用一个栈保存在凸包的点(顶点or边上的点),将前3个点加入到凸包中,然后判断当前点,设栈顶为p1,栈顶下一个顶点为p2,当前点为p,判断p2p相对于p2p1是不是非向右(p2p1叉乘p2p>=0),若是,则将p加入到栈中;否则p1必定不是凸包的顶点,将p1出栈,继续判断,直到所有点都被访问,栈中的点就包含了凸包上的点。注意,此时栈中的点不全是凸包的顶点,有可能是在凸包的边上。

 

附ZOJ1081和POJ1113的代码

 

ZOJ1081

/**
判断点是否在多边形内
解: 从该点向右发出一条射线,与多边形的交点为奇数则说明点在多边形内,否则在外.
注意特殊情况:
1. 点在多边形上-->根据题目意思确定
2. 多边形边与x轴平行-->不考虑
3. 射线与多边形的顶点相交-->只考虑某条线段的两个顶点中的一个(上点or下点)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
const int MaxN = 105;
const double eps = 1e-6;
int n,m;
struct Point
{
    double x;
    double y;
}p[MaxN];

///p0p1 X p0p2
double multi(const Point& p0, const Point& p1, const Point& p2)
{
    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);
}

bool zero(double a) { return fabs(a)<eps; }

///p0是否在线段[p1,p2]上
bool onSegment(const Point& p0, const Point& p1, const Point& p2)
{
    if( p0.x<=max(p1.x,p2.x)&&p0.x>=min(p1.x,p2.x)
        &&p0.y<=max(p1.y,p2.y)&&p0.y>=min(p1.y,p2.y) && zero(multi(p0,p1,p2)) )
        return true;
    return false;
}

///要判断的点,多边形顶点集(按顺时针or逆时针),顶点个数
bool InPolygon(const Point& p, Point* polygon, int n)
{
    int cnt = 0;
    for(int i = 0; i < n; i++)
    {
        Point p1 = polygon[i%n];
        Point p2 = polygon[(i+1)%n];
        if(onSegment(p,p1,p2))  ///1.是否落在多边形边上
            return true;
        if(p1.y==p2.y)          ///2.水平边(不考虑)
            continue;
        if(p.y>min(p1.y,p2.y)&&p.y<=max(p1.y,p2.y))     ///***3.有交点,若是交在顶点,只考虑上点
        {
            double x = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y) + p1.x;
            if(p.x < x)         ///只考虑右侧(向右的射线)
                cnt++;
        }
    }
    return cnt%2==1;
}

int main()
{
    int i;
    int cases = 0;
    while(true)
    {
        scanf("%d",&n);
        if(n==0) break;
        scanf("%d",&m);
        for(i = 0; i < n; i++)
            scanf("%lf %lf",&p[i].x,&p[i].y);
        if(cases)
            printf("\n");
        printf("Problem %d:\n",++cases);
        for(i = 0; i < m; i++)
        {
            Point pp;
            scanf("%lf %lf",&pp.x,&pp.y);
            if(InPolygon(pp,p,n))
                printf("Within\n");
            else
                printf("Outside\n");
        }
    }
    return 0;
}

 

POJ1113

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int Max = 1100;

struct Point
{
    int x;
    int y;
};
int num;
Point p[Max];   ///原始点集
Point ch[Max];  ///凸包点集
Point ans[Max];
int number;

///p0p1叉乘p0p2
int xmult(const Point& p0, const Point& p1, const Point& p2)
{
    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);
}

double dis(const Point& a, const Point& b)
{
    return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

///逆时针顺序把极角排序
bool cmp(const Point& a, const Point& b)
{
    int ret = xmult(p[0],a,b);
    if(ret>0)
        return true;
    if(ret==0&&dis(p[0],a)<dis(p[0],b))
        return true;
    return false;
}

/**
p: 原始点序列
n: 原始点的个数
ch: 栈,用来保存凸包上的点
top: 凸包上点的个数
*/
void Graham(Point* p, int n, Point* ch, int& top)
{
    int i,k=0;
    for(i=1; i < n; i++)
    {
        if(p[k].y>p[i].y || ((p[k].y==p[i].y)&&p[k].x>p[i].x))
            k = i;
    }
    swap(p[k],p[0]);
    sort(p+1,p+n,cmp);
    top = 0;
    ch[top++] = p[0];
    ch[top++] = p[1];
    ch[top++] = p[2];
    for(i = 3; i < n; ch[top++]=p[i++])
        while(top>=2 && xmult(ch[top-2],ch[top-1],p[i])<0)    ///是否向左
            top--;
}

int main()
{
    int i;
    int n,l;
    while(scanf("%d %d",&n,&l)!=EOF)
    {
        for(i = 0; i < n; i++)
            scanf("%d %d",&p[i].x,&p[i].y);
        Graham(p,n,ch,num);
        double result = acos(-1.0)*l*2;

        number = 1;
        for(ans[0]=ch[0],i=1; i < num; i++)
        {
            if(xmult(ch[i-1],ch[i],ch[(i+1)%num])!=0)
                ans[number++] = ch[i];
        }
        for(i = 0; i < number-1; i++)
            result += dis(ans[i],ans[i+1]);
        result += dis(ans[0],ans[number-1]);
        /*for(i = 0; i < num-1; i++)
            result += dis(ch[i],ch[i+1]);
        result += dis(ch[0],ch[num-1]);*/
        printf("%.0f\n",result);
    }
    return 0;
}

 

  • 大小: 23 KB
  • 大小: 31.2 KB
分享到:
评论

相关推荐

    ACM计算几何基础模板,杭电老学长精心整理.pdf

    标题中的“ACM计算几何基础模板,杭电老学长精心整理”指向了ACM(国际大学生程序设计竞赛)中计算几何领域的一个基础知识点集合。这些知识点是编程竞赛的参赛者在处理几何问题时的基本工具。计算几何是计算机科学的...

    计算几何导论+计算几何基础

    这个资源集合为学习计算几何提供了丰富的材料,尤其是包含了《计算几何导论》和《计算几何基础》这两本经典书籍。 《计算几何导论》通常会涵盖计算几何的基本概念和理论,比如点、线、面的表示,平面内的几何变换,...

    计算几何基础算法,方便计算几何入门

    计算几何基础算法 计算几何是计算机科学和数学交叉领域中的一门学科,它研究如何使用计算机来解决几何问题。在计算几何中,有很多需要注意的细节,如数据类型的选择、精度问题、向量运算等。在本文中,我们将详细...

    (HDUACM201803版_14)计算几何基础 - 副本_不规则多边形_计算几何基础pptx_

    这篇文档"(HDUACM201803版_14)计算几何基础 - 副本_不规则多边形_计算几何基础pptx_"显然是针对参赛者提供的一份关于计算几何基础知识的教程,特别是如何处理不规则多边形的问题。 首先,我们来了解一下计算几何...

    计算几何基础总结.rar

    在"计算几何基础总结.pdf"这个文档中,我们可以期待看到一些关键概念、算法和应用的概述。 1. **基本概念**:计算几何的基础概念包括点、线段、直线、圆、平面等基本几何元素。这些元素在二维和三维空间中的表示...

    8计算几何基础.ppt

    8计算几何基础.ppt

    计算几何基础知识提纲

    "计算几何基础知识提纲" 计算几何是计算机科学和数学的交叉领域,涉及到点、向量、线、面、体等几何对象的计算和处理。计算几何基础知识提纲是计算几何的基础知识,包括向量、坐标系、直线与多边形等内容。 一、...

    acm课件3 计算几何基础

    总结来说,计算几何基础涵盖了线段属性的理解和应用,以及多边形面积的高效计算方法。这些知识对于参与ACM竞赛和解决相关问题至关重要。深入理解和掌握这些内容,将有助于解决实际问题,提升编程竞赛的表现。

    ACM(lecture_05)计算几何基础_20081022

    本讲座的主题是"计算几何基础",由杭州电子科技大学的刘春英教授讲解。 首先,我们关注的是线段的属性。线段是计算几何中最基础的对象之一,它的属性包括起点、终点以及中点等。这里特别强调了三种属性,虽然具体...

    计算几何基础知识

    计算几何基础知识:深入解析与应用 计算几何是计算机科学领域中的一个重要分支,它涉及使用算法来解决几何问题,包括但不限于点、线、多边形等基本几何对象的处理。在现代计算机图形学、地理信息系统(GIS)、...

    计算几何基础知识_陈胤伯.pdf

    《计算几何基础知识_陈胤伯.pdf》这本书可能涵盖了计算几何的基本概念、理论和算法,作者陈胤伯可能是该领域的专家。 计算几何的基础知识主要包括以下几个方面: 1. 几何对象:计算几何中的基本元素包括点、线、...

    (课件6)计算几何基础_20071030

    在ACM程序设计竞赛中,计算几何基础是必不可少的知识,因为它可以帮助解决许多实际问题,如图形学、机器人路径规划、地图匹配等。 在计算几何的基本概念中,线段的属性是非常关键的一环。线段可以有多种属性,例如...

    (lecture_05)计算几何基础_20071030 ppt

    在“(lecture_05)计算几何基础_20071030”这个讲座中,刘春英教授深入讲解了计算几何的基本概念,包括线段属性、多边形面积的计算以及重心的概念。 首先,线段属性是计算几何中的基本元素。线段相交问题是计算...

    计算机几何基础

    学习计算机语言的基础文档,对于思维的培养有很大的好处。

    计算几何基础凸包学习笔记

    计算几何基础凸包学习笔记

    ACM课件!!(lecture_07)计算几何基础_easy

    ACM课件!!(lecture_07)计算几何基础_easy ACM课件!!(lecture_07)计算几何基础_easy hdu acm usa 测试数据 算法

    计算几何基础算法

    文档内有很多计算几何的基础算法,直线、多边形等等的算法的C语言实现,有详细的注释,一目了然。

    (HDUACM201403版_08)计算几何基础

    杭电ACM课件2014版之 (HDUACM201403版_08)计算几何基础

    计算几何 算法几何 程序

    压缩包中的"HDUACM2010版_07)计算几何基础.ppt"很可能是一个讲座或教程的幻灯片,可能涵盖了计算几何的基本概念、核心算法以及一些经典问题的解决方案。对于初学者,这是一个很好的起点,可以深入理解计算几何的...

Global site tag (gtag.js) - Google Analytics