poj1408(求线段交点)
求出所有线段的交点,然后利用叉乘求四边形面积即可。
//
// main.cpp
// poj1408
//
// Created by 陈加寿 on 15/12/31.
// Copyright (c) 2015年 chenhuan001. All rights reserved.
// #include <iostream>
#include <cmath>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std; #define MAX_N 110 ///////////////////////////////////////////////////////////////////
//常量区
const double INF = 1e10; // 无穷大
const double EPS = 1e-; // 计算精度
const double PI = acos(-1.0);// PI
const int PINXING = ; // 平行
const int XIANGJIAO = ; // 相交
const int XIANGLI = ; // 相离
const int GONGXIAN = ; // 共线
const int CHONGDIE = -; // 重叠 /////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
//类型定义区
struct Point { // 二维点或矢量
double x, y;
double angle, dis;
Point() {}
Point(double x0, double y0): x(x0), y(y0) {}
};
struct Point3D { //三维点或矢量
double x, y, z;
Point3D() {}
Point3D(double x0, double y0, double z0): x(x0), y(y0), z(z0) {}
};
struct Line { // 二维的直线或线段
Point p1, p2;
Line() {}
Line(Point p10, Point p20): p1(p10), p2(p20) {}
};
struct Line3D { // 三维的直线或线段
Point3D p1, p2;
Line3D() {}
Line3D(Point3D p10, Point3D p20): p1(p10), p2(p20) {}
};
struct Rect { // 用长宽表示矩形的方法 w, h分别表示宽度和高度
double w, h;
Rect() {}
Rect(double _w,double _h) : w(_w),h(_h) {}
};
struct Rect_2 { // 表示矩形,左下角坐标是(xl, yl),右上角坐标是(xh, yh)
double xl, yl, xh, yh;
Rect_2() {}
Rect_2(double _xl,double _yl,double _xh,double _yh) : xl(_xl),yl(_yl),xh(_xh),yh(_yh) {}
};
struct Circle { //圆
Point c;
double r;
Circle() {}
Circle(Point _c,double _r) :c(_c),r(_r) {}
}; typedef vector<Point> Polygon; // 二维多边形
typedef vector<Point> Points; // 二维点集 /////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
//基本函数区
inline double max(double x,double y)
{
return x > y ? x : y;
}
inline double min(double x, double y)
{
return x > y ? y : x;
}
inline bool ZERO(double x) // x == 0
{
return (fabs(x) < EPS);
}
inline bool ZERO(Point p) // p == 0
{
return (ZERO(p.x) && ZERO(p.y));
}
inline bool ZERO(Point3D p) // p == 0
{
return (ZERO(p.x) && ZERO(p.y) && ZERO(p.z));
}
inline bool EQ(double x, double y) // eqaul, x == y
{
return (fabs(x - y) < EPS);
}
inline bool NEQ(double x, double y) // not equal, x != y
{
return (fabs(x - y) >= EPS);
}
inline bool LT(double x, double y) // less than, x < y
{
return ( NEQ(x, y) && (x < y) );
}
inline bool GT(double x, double y) // greater than, x > y
{
return ( NEQ(x, y) && (x > y) );
}
inline bool LEQ(double x, double y) // less equal, x <= y
{
return ( EQ(x, y) || (x < y) );
}
inline bool GEQ(double x, double y) // greater equal, x >= y
{
return ( EQ(x, y) || (x > y) );
}
// 注意!!!
// 如果是一个很小的负的浮点数
// 保留有效位数输出的时候会出现-0.000这样的形式,
// 前面多了一个负号
// 这就会导致错误!!!!!!
// 因此在输出浮点数之前,一定要调用次函数进行修正!
inline double FIX(double x)
{
return (fabs(x) < EPS) ? : x;
}
////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
//二维矢量运算重载
bool operator==(Point p1, Point p2)
{
return ( EQ(p1.x, p2.x) && EQ(p1.y, p2.y) );
}
bool operator!=(Point p1, Point p2)
{
return ( NEQ(p1.x, p2.x) || NEQ(p1.y, p2.y) );
}
bool operator<(Point p1, Point p2)
{
if (NEQ(p1.x, p2.x)) {
return (p1.x < p2.x);
} else {
return (p1.y < p2.y);
}
}
Point operator+(Point p1, Point p2)
{
return Point(p1.x + p2.x, p1.y + p2.y);
}
Point operator-(Point p1, Point p2)
{
return Point(p1.x - p2.x, p1.y - p2.y);
}
double operator*(Point p1, Point p2) // 计算叉乘 p1 × p2
{
return (p1.x * p2.y - p2.x * p1.y);
}
double operator&(Point p1, Point p2) { // 计算点积 p1·p2
return (p1.x * p2.x + p1.y * p2.y);
}
double Norm(Point p) // 计算矢量p的模
{
return sqrt(p.x * p.x + p.y * p.y);
} /*-------------------基本函数区------------------*/ // 把矢量p旋转角度angle (弧度表示)
// angle > 0表示逆时针旋转
// angle < 0表示顺时针旋转
Point Rotate(Point p, double angle)
{
Point result;
result.x = p.x * cos(angle) - p.y * sin(angle);
result.y = p.x * sin(angle) + p.y * cos(angle);
return result;
} // 判断二维平面上点是否在线段上
// 输入:任意点p,和任意直线L
// 输出:p在直线上返回1,否则返回0
bool OnSeg(Point p, Line L)
{
return ( ZERO( (L.p1 - p) * (L.p2 - p) ) &&
LEQ((p.x - L.p1.x)*(p.x - L.p2.x), ) &&
LEQ((p.y - L.p1.y)*(p.y - L.p2.y), ) );
} //求两条直线之间的关系(二维)
//输入:两条不为点的直线
//输出:相交返回XIANGJIAO和点p,平行返回PINGXING,共线返回GONGXIAN
int LineAndLine(Line L1,Line L2,Point &p)
{
Point px,py;
px = L1.p1 - L1.p2;
py = L2.p1 - L2.p2;
if( EQ(px*py,) )//平行或者共线
{
if( ZERO( (L2.p1-L1.p1)*py ) ) //共线
{
return GONGXIAN;
}
return PINXING;
} double xa,xb,xc,ya,yb,yc;
xa=(L1.p2.y-L1.p1.y); xb=(L1.p1.x-L1.p2.x); xc=(L1.p1.y*L1.p2.x-L1.p1.x*L1.p2.y);
ya=(L2.p2.y-L2.p1.y); yb=(L2.p1.x-L2.p2.x); yc=(L2.p1.y*L2.p2.x-L2.p1.x*L2.p2.y); p.y = (xa*yc-xc*ya)/(xb*ya-xa*yb);
p.x = (xb*yc-xc*yb)/(xa*yb-xb*ya); return XIANGJIAO;
} /*---------------------代码区---------------------------*/ int SegAndSeg(Line L1,Line L2,Point &p)
{ double signx,signy; //跨立实验
if( LEQ(signx=( ((L1.p2-L1.p1)*(L1.p1-L2.p1))*((L1.p2-L1.p1)*(L1.p1-L2.p2)) ),) &&
LEQ(signy=( ((L2.p2-L2.p1)*(L2.p1-L1.p1))*((L2.p2-L2.p1)*(L2.p1-L1.p2)) ),) )
{
if( ZERO(signx) && ZERO(signy) )
{
//线段共线
signx = min( max(L1.p1.x,L1.p2.x),max(L2.p1.x,L2.p2.x) )-
max( min(L1.p1.x,L1.p2.x),min(L2.p1.x,L2.p2.x) ); signy = min( max(L1.p1.y,L1.p2.y),max(L2.p1.y,L2.p2.y) )-
max( min(L1.p1.y,L1.p2.y),min(L2.p1.y,L2.p2.y) ); if( ZERO(signx) && ZERO(signy) ) //说明共线,且相交一点
{
if(L1.p1==L2.p1||L1.p1==L2.p2) p=L1.p1;
if(L1.p2==L2.p1||L1.p2==L2.p2) p=L1.p2;
return XIANGJIAO;
}
else if( GEQ(signx, ) && GEQ(signy, ) )
{
return CHONGDIE;
}
else
{
return XIANGLI;
}
}
return LineAndLine(L1, L2, p);
}
return XIANGLI;
} int main(int argc, const char * argv[]) {
/*
Line a,b;
while(cin>>a.p1.x>>a.p1.y>>a.p2.x>>a.p2.y)
{
cin>>b.p1.x>>b.p1.y>>b.p2.x>>b.p2.y;
Point p;
int sign=SegAndSeg(a, b, p);
if(sign==XIANGJIAO)
{
printf("相交:(%lf,%lf)\n",p.x,p.y);
}
else if(sign==CHONGDIE) printf("重叠\n");
else if(sign==XIANGLI) printf("相离\n");
}
*/
int n;
Line ls[],ls1[];
Point ps[][];
while(scanf("%d",&n) && n)
{
ps[][].x=;
ps[][].y=;
for(int i=;i<n;i++)
{
scanf("%lf",&ls[i].p1.x);
ls[i].p1.y=; ps[][i+].x = ls[i].p1.x;
ps[][i+].y = ;
}
ps[][n+].x=;
ps[][n+].y=; for(int i=;i<n;i++)
{
scanf("%lf",&ls[i].p2.x);
ls[i].p2.y=;
}
for(int i=;i<n;i++)
{
scanf("%lf",&ls1[i].p1.y);
ls1[i].p1.x=;
}
for(int i=;i<n;i++)
{
scanf("%lf",&ls1[i].p2.y);
ls1[i].p2.x=;
} ls1[n].p1.x=; ls1[n].p1.y=;
ls1[n].p2.x=; ls1[n].p2.y=; int a=,b=;
double mi = -;
for(int i=;i<=n;i++)
{
ps[b][] = ls1[i].p1;
for(int j=;j<n;j++)
{
SegAndSeg(ls1[i], ls[j], ps[b][j+]);
}
ps[b][n+] = ls1[i].p2; for(int j=;j<=n;j++)
{
double tmp = fabs( (ps[b][j]-ps[b][j+])*(ps[a][j+]-ps[b][j+]) )/+
fabs( (ps[b][j]-ps[a][j])*(ps[a][j+]-ps[a][j]) )/;
mi=max(tmp,mi);
}
swap(a,b);
} printf("%.6lf\n",mi);
}
return ;
}
poj1408(求线段交点)的更多相关文章
- 谈谈"求线段交点"的几种算法(js实现,完整版)
"求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法总结一下, 希望对大家有所帮助. ...
- nyoj-1132-promise me a medal(求线段交点)
题目链接 /* Name:nyoj-1132-promise me a medal Copyright: Author: Date: 2018/4/26 20:26:22 Description: 向 ...
- hdu 2857:Mirror and Light(计算几何,点关于直线的对称点,求两线段交点坐标)
Mirror and Light Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 2528:Area(计算几何,求线段与直线交点 + 求多边形面积)
Area Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 【计算几何初步-线段相交】【HDU1089】线段交点
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- js判断向量叉点 并求出交点坐标
代码如下可以直接运行,判断向量相交并求出交点坐标 <!DOCTYPE html> <html> <head> <meta http-equiv=" ...
- UVa 11437:Triangle Fun(计算几何综合应用,求直线交点,向量运算,求三角形面积)
Problem ATriangle Fun Input: Standard Input Output: Standard Output In the picture below you can see ...
- POJ_1269_Intersecting Lines_求直线交点
POJ_1269_Intersecting Lines_求直线交点 Description We all know that a pair of distinct points on a plane ...
- sgu 129 Inheritance 凸包,线段交点,计算几何 难度:2
129. Inheritance time limit per test: 0.25 sec. memory limit per test: 4096 KB The old King decided ...
随机推荐
- bitcoin-qt忘记密码
客户端有钱包加密功能,输入密码可以增强安全性. 但是,如果你把钱包文件弄丢了,那即使设了密码,币也会丢. 关闭bitcoin-qt,把钱包文件wallet.dat 剪到其他地方(但不要删除),然后重新 ...
- 2017.4.26 慕课网--Java 高并发秒杀API(一)
Java高并发秒杀API系列(一) -----------------业务分析及Dao层 第一章 课程介绍 1.1 内容介绍及业务分析 (1)课程内容 SSM框架的整合使用 秒杀类系统需求理解和实现 ...
- Android之WebView的使用样例——WebSetting、WebViewClient、WebChromeClient
点击查看原文 代码直接下载http://download.csdn.net/detail/metis100/8514837 第一步,xml Manifest中要设置网络权限,否则会出先 webpage ...
- 新Android工程src和layout目录为空的问题
问题症状:eclipse创建的新Android工程,发现src下为空,res\layout目录下也为空. 原因:升级了SDK,新版本sdk与ADT冲突.具体冲突的版本号为ADT 23.X与SDK22. ...
- oc 之中的 汉字字符串转化成为拼音 汉字字符串的排序
在oc 之中的字符串为汉字的时候,我们经常要进行字符串比較,可是汉字不能比較,所以就要将汉字转化成为拼音,详细步骤例如以下: //可变字符串 必须是可变字符串. NSMutableString ...
- nodeJs-autoBulid
/** * Created by Administrator on 2016/1/16. */ var projectData = { 'name' : 'autobulid', 'fileData' ...
- Codeforces548E:Mike and Foam
Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a special shelf. There are n ...
- 浅谈EntityFramework框架的使用
第一步,建立一个类库,并且安装好EntityFramework框架还有CodingFirstUsingFluentApi安装包 第二步 : 第三步:配置好你的数据库连接信息,还有你需要操作的数据库,在 ...
- CentOS修改IP地址及关闭/打开防火墙
1.CentOS修改IP地址: # ifconfig eth0 192.168.1.80 这样就把IP地址修改为192.168.1.80(如果发现上不了网 了,那么你可能需要把网关和DNS也改一下,后 ...
- 解决ubuntukylin 13.10安装wine时无法解决软件包依赖问题
在ubuntukylin 13.10中,无论是在软件中心安装wine还是通过apt-get install安装wine都会出现软件包依赖问题且无法解决. 问题重现 在软件中心安装wine报错例如以下: ...