UVA - 378 Intersecting Lines【基础计算几何】

本文探讨了如何利用代数知识来确定两直线在平面上的相交方式和位置,包括无交点、共线或交于一点的情况,并提供了一个算法实现的例子。

【题目描述】
We all know that a pair of distinct points on a plane defines a line and that a pair of lines on a plane
will intersect in one of three ways: 1) no intersection because they are parallel, 2) intersect in a line
because they are on top of one another (i.e. they are the same line), 3) intersect in a point. In this
problem you will use your algebraic knowledge to create a program that determines how and where two lines intersect.
我们都知道,平面上的一对不同的点定义了一条线,平面上的一对线将以三种方式之一相交:(1)没有交叉,因为它们是平行的,2)在一条线上相交,因为它们是相交的(他们是同一条直线)。(3)点相交。在这个问题中,您将使用您的代数知识来创建一个程序,该程序确定两行交叉的方式和位置。
Your program will repeatedly read in four points that define two lines in the x-y plane and determine how and where the lines intersect. All numbers required by this problem will be reasonable, say between -1000 and 1000.
您的程序将重复读取四个点,这些点定义了x-y平面上的两行,并确定了这些线是如何和在何处相交的。这个问题所要求的所有数字都是合理的,比如说-1000到1000之间。

【输入】
The first line contains an integer N between 1 and 10 describing how many pairs of lines are represented.The next N lines will each contain eight integers. These integers represent the coordinates of four points on the plane in the order x1 y1 x2 y2 x3 y3 x4 y4. Thus each of these input lines represents two lines on the plane: the line through (x1, y1) and (x2, y2) and the line through (x3, y3) and (x4, y4). The point (x1, y1) is always distinct from (x2, y2). Likewise with (x3, y3) and (x4, y4).
第一行包含介于1到10之间的整数N,描述代表了多少对行。接下来的N行将包含8个整数。这些整数以x1y1x2y2x3y3x4y4的顺序表示平面上四个点的坐标。因此,这些输入线中的每一行代表平面上的两条线:穿过(x1,y1)和(x2,y2)的线和穿过(x3,y3)和(x4,y4)的线。点(x1,y1)总是与(x2,y2)不同。(x3,y3)和(x4,y4)也是如此。

【输出】
There should be N + 2 lines of output. The first line of output should read ‘INTERSECTING LINES
OUTPUT’. There will then be one line of output for each pair of planar lines represented by a line of
input, describing how the lines intersect: none, line, or point. If the intersection is a point then your
program should output the x and y coordinates of the point, correct to two decimal places. The final
line of output should read ‘END OF OUTPUT’.
有N+2行输出。第一行输出‘INTERSECTING LINES OUTPUT’。然后,每一对由输入线表示的平面线将有一行输出,描述这些线是如何相交的:无、线或点。如果交点是一个点,那么程序应该输出点的x和y坐标,精确到小数点后两位。最后一行输出‘END OF OUTPUT’。

【样例输入】
5
0 0 4 4 0 4 4 0
5 0 7 6 1 0 2 3
5 0 7 6 3 -6 4 -3
2 0 2 27 1 5 18 5
0 3 4 0 1 2 2 5

【样例输出】
INTERSECTING LINES OUTPUT
POINT 2.00 2.00
NONE
LINE
POINT 2.00 5.00
POINT 1.07 2.20
END OF OUTPUT

题目链接:https://cn.vjudge.net/problem/UVA-378

基础计算几何,判断两直线关系

代码如下:

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
static const double EPS=1e-8;
int sgn(double x)
{
    if(fabs(x)<EPS) return 0;
    if(x<0) return -1;
    else return 1;
}
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y):x(_x),y(_y){}
    void input() { cin>>x>>y; }
    void output() { cout<<fixed<<setprecision(2)<<x<<" "<<y<<endl; }
    Point operator - (const Point &b) const { return Point(x-b.x,y-b.y); }
    double operator ^ (const Point &b) const { return x*b.y-y*b.x; }
    double operator * (const Point &b) const { return x*b.x+y*b.y; }
};
struct Line{
    Point s,e;
    Line(){}
    Line(Point _s,Point _e):s(_s),e(_e){}
    void input() { s.input(); e.input(); }
    bool parallel(Line v) { return sgn((e-s)^(v.e-v.s))==0; }
    int relation(Point p) {
        int c=sgn((p-s)^(e-s));
        if(c<0) return 1;
        else if(c>0) return 2;
        else return 3;
    }
    int linecrossline(Line v) {
        if((*this).parallel(v))
            return v.relation(s)==3;
        return 2;
    }
    Point crosspoint(Line v) {
        double a1=(v.e-v.s)^(s-v.s),a2=(v.e-v.s)^(e-v.s);
        return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
    }
};
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0),cout.tie(0);
    int T;
    cin>>T;
    cout<<"INTERSECTING LINES OUTPUT"<<endl;
    while(T--)
    {
        Line line1,line2;
        line1.input(),line2.input();
        if(line1.linecrossline(line2)==0)
            cout<<"NONE"<<endl;
        else if(line1.linecrossline(line2)==1)
            cout<<"LINE"<<endl;
        else
        {
            cout<<"POINT ";
            Point p=line1.crosspoint(line2);
            p.output();
        }
    }
    cout<<"END OF OUTPUT"<<endl;
    return 0;
}
### 自相交区域的概念及其算法处理 #### 定义与背景 在计算机图形学和几何算法领域,自相交区域(self-intersecting regions)是指一个多边形或多面体的边界与其自身的其他部分发生交叉的情况。这种现象通常发生在复杂形状中,例如星型多边形或某些非凸多边形[^1]。 当考虑平面图(planar graph)中的自相交情况时,可以利用三角不等式定理来计算内部和外部区域的面积。具体方法是通过分析所有起始于特定顶点并终止于另一顶点的边的行为。 #### 解决方案概述 对于检测线段集合中的自相交问题,一种常见的策略是对每一对可能形成交叉的顶点进行枚举,并逐一验证是否存在实际的交叉点。这种方法结合分区(partitioning)技术能够显著提高效率,从而实现快速运行的算法[^2]。 以下是基于上述理论的一个简单伪代码示例: ```python def detect_self_intersection(edges): intersections = [] for i in range(len(edges)): for j in range(i + 1, len(edges)): edge1 = edges[i] edge2 = edges[j] # Check if these two edges intersect if do_edges_intersect(edge1, edge2): intersection_point = find_intersection_point(edge1, edge2) intersections.append(intersection_point) return intersections def do_edges_intersect(e1, e2): """Check whether two line segments intersect.""" p1, q1 = e1 p2, q2 = e2 o1 = orientation(p1, q1, p2) o2 = orientation(p1, q1, q2) o3 = orientation(p2, q2, p1) o4 = orientation(p2, q2, q1) if o1 != o2 and o3 != o4: return True # Special cases handling omitted here... return False def orientation(p, q, r): val = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]) if val == 0: return 0 # colinear elif val > 0: return 1 # clockwise else: return 2 # counterclockwise ``` 此代码片段展示了如何判断两条线段是否相交以及找到它们的具体交点位置。 #### 扩展到三维空间的应用 如果进一步扩展至三维场景,则需要额外的信息支持——即特征在其二维投影图像中的相对位置关系。这涉及到从多个视角获取数据以便推断物体的真实三维坐标[^3]。 此外,在涉及连续变化监测的任务中(比如土地覆盖动态监控),也可以借鉴类似的思路设计解决方案。这类工作往往依赖云计算平台的强大算力完成大规模数据分析任务[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值