zoukankan      html  css  js  c++  java
  • 向量叉积问题(凸包)

    学凸包时不太理解叉积判断,学完后就整理了一下,希望对大家有点帮助


    • 向量叉积:

    向量A×B(叉积)的代数定义:(A.x-B.y)* (A.y-B.x)

    若A×B的值为正,A在B的顺时针方向;反之亦然(值为0共线)

    “顺时针方向”(此处31在21的顺时针方向):

    RTAaQg.png

    • cross函数:

    此函数计算:线段ab×线段cb(将b看作原点)

    double cross(point a,point b,point c){return (a.x-b.x)*(c.y-b.y)-(a.y-b.y)*(c.x-b.x);}
    
    • 单调栈维护弹出点:

    以上图为例,线段21在线段31的逆时针方向,弹出21,

    RTZ4mQ.png

    for(int i=1;i<=n;++i){
    	while(num>1&&cross(s[num],s[num-1],a[i])<=0) --num;//s[num]在a[i]的逆时针方向 
    	s[++num]=a[i];
    }
    
    • andrew构建凸包模板:

    dalao的andrew构建凸包详解

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int maxn=10003;
    int n,num;
    struct point{double x,y;}a[maxn],s[maxn];
    double dis(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
    bool cmp(point a,point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    double cross(point a,point b,point c){return (a.x-b.x)*(c.y-b.y)-(a.y-b.y)*(c.x-b.x);}//a叉c 
    void andrew(){
    	sort(a+1,a+n+1,cmp);
    	for(int i=1;i<=n;++i){
    		while(num>1&&cross(s[num],s[num-1],a[i])<=0) --num;//a在c的逆时针方向 
    		s[++num]=a[i];
    	}
    	for(int i=n-1,tmp=num;i;--i){
    		while(num>tmp&&cross(s[num],s[num-1],a[i])<=0) --num;
    		s[++num]=a[i];
    	}
    	if(n>1) --num;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) scanf("%lf %lf",&a[i].x,&a[i].y);
    	andrew();
    	double ans=dis(s[num],s[1]);
    	for(int i=1;i<num;++i) ans+=dis(s[i],s[i+1]);
    	printf("%.2lf",ans);
    	return 0;
    }
    
  • 相关阅读:
    爬虫--urllib,requests模块
    ADO.NET实用经验汇总
    MVC框架的优点-老外的原文翻译
    ASP.NET MVC 3: Razor的@:和语法
    html做表格只显示表格的外边框
    ASP.NET 页生命周期概述
    Asp.Net母版页元素ID不一致的体现
    Asp.Net套用母版页后元素ID不一致之个人总结
    ASP.NET 4.0配置文件中的ClientIDMode属性
    Asp.Net母版页和内容页运行机制
  • 原文地址:https://www.cnblogs.com/wuwendongxi/p/14978045.html
Copyright © 2011-2022 走看看