1. 程式人生 > >計算幾何問題彙總--點與線的位置關係

計算幾何問題彙總--點與線的位置關係

http://www.infocool.net/kb/Python/201609/191671.html


點與點之間, 線與線之間,點與線之間的位置關係是一類非常重要的問題。它不僅是平面幾何學的基石,也常常應用於LBS(Location Based Service),社交網路,以及資料庫查詢等領域。

本文中,我將給出判斷這些關係的相關演算法,作為參考。需要說明的是,我給出的這些問題的解法,都是建立在二維平面空間之上。有關多維空間的位置關係,大家可以仿照二維空間中問題的思路,做相應的拓展。

語言上,我用的當然還是Python.

點與點之間的距離

先從最簡單的點與點的位置關係說起。一般情況下,我們只關心點與點之間的距離。

1. 點類的定義

為使演算法思路更加清晰,先定義點類 Point,既然是在二維空間上,那麼每個點都應該有兩個屬性:x, y分別代表點的橫縱座標。

class Point(object):
    """Point are two-dimension"""

    def __init__(self, x, y):
        self.x = x
        self.y = y
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

接下來就看看如何計算兩點之間距離:當然可以用初中學的歐氏距離最基本的計算方法。但是考慮到程式碼編寫的效率,以及方便以後向高維空間拓展。我在本文中將盡量使用向量計算。

而為了簡化程式碼,我們使用對於向量運算已經相當成熟的庫numpy

2. 兩點之間距離的計算

顯然,兩點可以構成向量,而向量的長度則是其內積的開方。空間中,點  A  與點  B  的距離可以用向量  AB  的模  |AB|  表示。所以,現在需要做的,就是寫一個函式,以兩點為引數,計算由這兩點構成的向量的模。

為了和本文之後的問題保持編碼風格上一致,同時簡化程式碼編寫。我使用對向量運算已經極為成熟的庫numpy幫助計算。並且定義了一個新的類 Vector

,類 Vector 以向量的起點和終點作為輸入,生成一個只擁有屬性x和y的向量物件。

最後,和前面定義的類放在一起,程式碼如下:

import numpy as np
# numpy help us do some vector calculation


class Point(object):
    """Point are two-dimension"""

    def __init__(self, x, y):
        self.x = x
        self.y = y

class Vector(object):
    """start and end are two points"""

    def __init__(self, start, end):
        self.x = end.x - start.x
        self.y = end.y - start.y

def pointDistance(p1, p2):
    """calculate the distance between point p1 and p2"""

    # v: a Vector object
    v = Vector(p1, p2)

    # translate v to a ndarray object
    t = np.array([v.x, v.y])

    # calculate the inner product of ndarray t
    return float(np.sqrt(t @ t))
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

說明一下,在Python3.5以後的版本中,使用numpy庫時,ndarray物件之間的乘法可以用 @ ,代替之前的 v1.dot(v2) 這樣的形式。

點與線之間的位置關係

1. 線的分類

點與線之間的位置關係就要稍微複雜一些了,複雜之處在於線分線段和直線兩種情況。但是,在定義類的時候我都用兩點來代表線段(直線)的兩個屬性。於是,至少程式碼看上去是沒什麼分別的。

不同之處在於,線段的兩個點事兩個端點,而直線的兩個點是直線上任意兩點。

class Segment(object):
    """the 2 points p1 and p2 are unordered"""

    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2


class Line(object):
    """p1 and p2 are 2 points in straight line"""

    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

需要注意的是,這裡並沒有說線段的兩個點是什麼順序(不一定說左邊的點就是p1,右邊就是p2)

2. 點與線的位置關係

(1) 計算點到直線的距離

如Fig.1(a)所示,現要求點  C  到直到直線  AB  的距離。還是向量法,據向量知識可知:

cosCAB=ACAB|AC||AB|

再由三角形知識可知,線段  AD  的長度為:

|AC|cosCAB

所以,  AD  可以這樣計算:

AD=AB|AB||AD|=AB

相關推薦

1015 - 計算幾何多邊形的關係 - Points Within(ZOJ1081)

傳送門   分析 射線法 雖然這個射線法有很多需要特判的情況,但總的來說還是蠻好用的 判斷點與多邊形的關係,若使用射線法,就是說從這個點往右做一條與 x 軸平行的射線,看它與多邊形相交了幾次 若相交了偶數次,則不在多邊形內部(相當於從這個多邊形中穿過去,沒有留在

1016 - 計算幾何直線的關係 - TOYS(POJ 2318)

傳送門   題意 給你一個這樣的圖 然後隨機給你 m 個點,問落在每一個區域內的點有多少個   分析 入門題入門題 依舊是利用叉積,叉積太強了! 二分尋找並判斷     gsj太厲害了,簡直每次我演算法

計算幾何問題彙總--位置關係

http://www.infocool.net/kb/Python/201609/191671.html 點與點之間, 線與線之間,點與線之間的位置關係是一類非常重要的問題。它不僅是平面幾何學的基石,也常常應用於LBS(Location Based Service),社交網路,以

1015 - 計算幾何之直線直線的關係 - Intersecting Lines(POJ1269)

傳送門   題意 給你兩條直線 若其相交則輸出  交點的座標 若其平行則輸出  NONE 若其重合則輸出  LINE   分析 比較基礎的計算幾何,就是考向量的使用 判斷兩條直線是否平行,就是看其叉積是否為

之間的位置關系

長度 線上 eight strong 根據 .com 技術 最大 需要 (1) 計算點到直線的距離 如圖(a)所示,求點C到直到直線AB的距離。據向量知識可知: 再由三角形知識可知,線段AD的長度為: 所以, 可以這樣計算: 當計算完成之後,可以根據相應的坐標值得到點

POJ-2318 TOYS 計算幾何 判斷在線段的位置

else %s bool const fin cpp cst ade lse 題目鏈接:https://cn.vjudge.net/problem/POJ-2318 題意 在一個矩形內,給出n-1條線段,把矩形分成n快四邊形 問某些點在那個四邊形內 思路 二分+判斷點與位置

計算幾何:直線圓的交點 三角形的內切圓和外接圓(5252: Triangle to Hexagon)

.cn ble long precision using get b- circle tar http://exam.upc.edu.cn/problem.php?id=5252 斜截式表示的直線方程 求三角形的內切圓和外接圓 求直線與直線交點,直線與圓交點 1

1016 - 計算幾何之直線線段的交 - Segments(POJ 3304)

傳送門   題意 雖然題目是給了什麼投影啊,什麼奇奇怪怪的東西 但實際上也就是給你 n 條線段,詢問是否存在一條直線能經過所有的線段 資料範圍:n<=100   分析 這個資料範圍有點友好啊…… 我們先來想一個問題 若存在一條直線

計算幾何基礎——積和叉積

計算幾何是演算法競賽的一大塊,而叉積是計算機和的基礎。 首先叉積是計算說向量之間的叉積,那麼我們可以這樣定義向量,以及向量的運算子過載。 struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {}

Codeforces 32E Hide and Seek [計算幾何 對稱、線段相交]

題目大意:給出兩個點,一個雙面鏡(線段),一面牆(線段),問兩個點能否互相直接或間接地看到對方。 思路:兩個點要麼直接看到對方,這個直接判斷一下兩點連線是否和牆或者鏡子相交就可以了。           &

判斷一個圓的關係

//判斷點和圓的關係。 class Points { private int x; private int y; Points(int x,int y) { this.x=x; this.y=y; } publi

計算幾何定位(線段,三角形,多邊形)

判斷是否點線上段上 1.滿足向量 AC×AB == 0,使C點滿足在AB的直線上 2.滿足C在AB構成的矩形內,使C點排除在AB的延長線和反向延長線上 注意:考慮豎直和水平的情況,橫座標和縱座標都要判斷。 bool dot_line(point a,point b,p

poj2318TOYS【二分+直線位置判斷】

Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away when he

通過C++實現判斷多邊形的關係和兩點之間的距離

1.判斷兩點之間的距離 #include<math.h> //計算兩點之間的距離 double calculateDistence(double* p0,double* p){ double tempx = p[0] - p0[0];

POJ2318 Toys(計算幾何,C++, 叉積判斷線段位置關係,二分法)

目錄 題目描述: Toy Input 演算法實現 優化 具體程式: 題目描述: 出自ACM Toy Description Calculate the number of toys that land in each bin of a par

[計算幾何] 線段的位置 向量法

給出點A、B的座標, 構成線段AB, 再給出一點P的座標, 判斷點P與線段AB的位置關係 如下圖, 點P與AB的關係可分為5種情況 (1) 點P線上段AB的順時針方向 (2) 點P線上段AB的逆時針方向 (3) 點P線上段AB的反向延長線上 (4) 點P線上

計算幾何-、面、形

put strong 玩具 determine 描述 stay 垃圾箱 mom lap 1.TOYS 雙語描述: Calculate the number of toys that land in each bin of a partitioned toy box. 計

初學計算幾何(一)——向量·叉積

前言 計算幾何應該是一個比較複雜的東西吧,它的應用十分廣泛。為此,我花了很長的時間來學習計算幾何。 點與向量 點 點應該還算比較簡單吧!對於平面上的一個座標為(x,y)(x,y)的點

初學計算幾何(二)——、直線、線段的關係

前言 \(NOIP\)結束之後,我下定決心來好好學習一些省選演算法了。 計算幾何應該是一個比較複雜的演算法吧,雖然出現得較少,但還是蠻實用的。 接著上一次學習的點與向量·叉積與點積,我繼續學習了點、直線、線段的關係。 直線與線段 我們可以用這樣子的結構體來表示直線與線段: struct Lin

Intersecting Lines (計算幾何基礎+判斷兩直線的位置關係

題面:DescriptionWe 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 o