java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

2020-06-22 每日經典一文

測試沒問題,我用的是原始坐標;要注意的是坐標轉換問題,要看當前是屬於什麼坐標系

  1. 經緯度與GCS(Geographic Coordinate System, 地理坐標系統)
  2. 平面坐標與PCS(Projection Coordinate System, 投影坐標系統)
  3. GCS和PCS的轉化問題(三參數與七參數問題)
  4. 火星坐標問題

1. 經緯度與GCS

天氣預報也好,火箭發射也罷,地震、火山等事故發生時,電視臺總會說東經XX度,北緯YY度。這個經緯度中學地理就學過了,我就不細說了。

我從如何描述地球說起。

1.1 凹凸不平的地球

誰都知道地球表面不平坦,它甚至大概形狀都不是一個正球體,是一個南北兩極稍扁赤道略胖的胖子,胖度大概是20km,在外太空幾乎看不出來的,這也可能和星球長期受到潮汐引力、太陽引力以及自身旋轉的向心力有關。這裡不是地球科學,就不再深究了。

為了能讓地球出現在數學家的公式裡,我們曾經走過了2個階段:用平靜的海面描述地球——用虛擬的旋轉橢球面描述地球表面。

這裡也不是地圖學,再深入下去其實還有似大地水準面等概念。就挑重點講。

「假設地球表面都是水,當海平面風平浪靜沒有波瀾起伏時,這個面就是大地水準面。」大家應該知道,在太空失重的環境下,水相對靜止狀態是個正球體,那麼肯定很多人就認為,大地水準面就是個正球面。不是的,還需要考慮一個問題:地球各處的引力不同。引力不同,就會那兒高一些,這兒低一些,儘管這些微小的差距肉眼難以觀測出來,可能隔了好幾千米才會相差幾釐米。所以,在局部可能看起來是個球面,但是整體卻不是。顯然,用大地水準面來進行數學計算,顯然是不合適的,至少在數學家眼中,認為這不可靠。

所以找到一個旋轉橢球面就成了地理學家和數學家的問題。(注意區分橢球面和旋轉橢球面這兩個數學概念,在GCS中都是旋轉橢球面)

給出旋轉橢球面的標準方程:

(x2+y2)/a2+z2/b2=1

其中x和y的參數相同,均為a,這就代表一個繞z軸旋轉的橢圓形成的橢球體。不妨設z軸是地球自轉軸,那麼這個方程就如下圖是一個橢球體,其中赤道是個圓。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

這樣,有了標準的數學表達式,把數據代入公式計算也就不是什麼難事了。

由此我們可以下定義,GIS坐標系中的橢球,如果加上高程系,在其內涵上就是GCS(地理坐標系統)。其度量單位就是度分秒。

描述一個旋轉橢球面所需的參數是方程中的a和b,a即赤道半徑,b即極半徑,f=(a-b)/a稱為扁率。

與之對應的還有一個問題:就是坐標中心的問題。(地球的中心在哪裡?)

【注】十九世紀發現赤道也是一個橢圓,故地球實際應以普通橢球面表示,但是由於各種原因以及可以忽略的精度內,一直沿用旋轉橢球體作為GCS。

1.2 參心坐標系、地心坐標系

上過中學物理的人知道,物體均有其質心,處處密度相等的物體的質心在其幾何中心。所以,地球只有一個質心,只是測不測的精確的問題而已。由地球的唯一性和客觀存在,以地球質心為旋轉橢球面的中心的坐標系,叫地心坐標系,且唯一。當然,由於a、b兩個值的不同,就有多種表達方式,例如,CGCS2000系,WGS84系等,這些後面再談。

【注】地心坐標系又名協議地球坐標系,與GPS中的瞬時地球坐標系要對應起來。

但是又有一個問題——政治問題,地圖是給一個國家服務的,那麼這地圖就要儘可能描述準確這個國家的地形地貌,儘量減小誤差,至於別國就無所謂。

所以,就可以人為的把地球的質心「移走」,將局部的表面「貼到」該國的國土,使之高程誤差儘量減小到最小。

這個時候,就出現了所謂的「參心坐標系」。即橢球中心不在地球質心的坐標系。如下圖:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

綠色的球就是為了貼合赤道某個地方而產生了平移的參心系(這裡只是個例子,而且畫的有點誇張)。

我國常用的參心系及對應橢球:

  • 北京54坐標系:克拉索夫斯基橢球體
  • 西安80坐標系:IAG75橢球體

我國常用的地心系及對應橢球:

  • WGS84坐標系:WGS84橢球體(GPS星曆的坐標系,全球統一使用,最新版於2002年修正)
  • CGCS2000坐標系:CGCS2000橢球體(事實上,CGCS2000橢球和WGS84橢球極為相似,偏差僅有0.11mm,完全可以兼容使用)

為什麼CGCS2000和WGS84要略微有些偏差?這是因為WGS84系是GPS的坐標系,而我國北鬥定位則是需要自己的坐標系,就搞了一波CGCS2000。

這幾個坐標系的介紹放在下一節,而這些橢球體的轉換將在第三部分介紹(主要就是數學中,空間直角坐標系旋轉的問題)。

1.3 我國常見GCS

藉助以下4個常見坐標系及橢球體,就可以推及到世界各地不同的GCS及橢球體,完成數據的轉化問題。

1.3.1 北京54坐標系(參心)

新中國成立以後,我國大地測量進入了全面發展時期,再全國範圍內開展了正規的,全面的大地測量和測圖工作,迫切需要建立一個參心大地坐標系。由於當時的「一邊倒」政治趨向,故我國採用了前蘇聯的克拉索夫斯基橢球參數,並與前蘇聯1942年坐標系進行聯測,通過計算建立了我國大地坐標系,定名為1954年北京坐標系。因此,1954年北京坐標系可以認為是前蘇聯1942年坐標系的延伸。它的原點不在北京而是在前蘇聯的普爾科沃。

1.3.2 西安80坐標系(參心)

改革開放啦,國家商量要搞一個更符合國用的坐標系——西安80坐標系,該坐標系的大地原點設在我國中部的陝西省涇陽縣永樂鎮,位於西安市西北方向約60公裡。

1.3.3 WGS84坐標系(地心)

全稱World Geodetic System - 1984,是為了解決GPS定位而產生的全球統一的一個坐標系。

1.3.4 CGCS2000坐標系(地心)

2000國家大地坐標系是全球地心坐標系在我國的具體體現,其全稱為China Geodetic Coordinate System 2000,其原點為包括海洋和大氣的整個地球的質量中心。

【注】CGCS2000的定義與WGS84實質一樣。採用的參考橢球非常接近。扁率差異引起橢球面上的緯度和高度變化最大達0.1mm。當前測量精度範圍內,可以忽略這點差異。可以說兩者相容至cm級水平

最後一張表總結一下:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

有趣的是,在ArcGIS的GCS文件夾下,找到了一個「新北京54坐標系」,這是為了使54和80之間方便轉化而產生的一個過渡坐標系。

2. 平面坐標與PCS

說完了以經緯度為計量單位的GCS,那麼我再來說說以平面(空間)直角坐標係為度量衡的投影坐標系(PCS,Projection Coordinate System)。

說一個具體的問題以解釋為什麼要用PCS。

如何用經緯度表達一塊地的面積?

這沒辦法吧?經緯度本身不帶單位,度分秒僅僅是一個進位。

而且同樣是1度經度,在不同的緯度時代表的弧段長是不一樣的。

這就給一些地理問題帶來了困惑:如何建立一個新的坐標系使得地圖分析、空間分析得以定量計算?

PCS——投影坐標系就誕生了。

我要著重介紹一下我國的6種常用投影方式:

很多課本、博客都寫的很詳細了,我想從3D的圖形來描述一下他們是怎麼個投影的。

2.1 從投影說起

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

如上圖。光線打到物體上,使得物體產生的陰影形狀,就叫它的投影。這個不難理解。

這裡我想問一個問題:既然投影物體,是不變的,那麼我把投影的平面改為曲面呢?

這就產生了不同的投影,比如投射到一個圓錐面上,一個圓柱面上,一個平面上...等等。

不同的投影方式有不同的用途,也有了不同的投影名稱。

但是,PCS是基於存在的GCS的,這個直接規定。沒有GCS,就無從談PCS,PCS是GCS上的地物投射到具體投影面的一種結果。

即:

PCS=GCS+投影方式

2.2 我國常見投影

2.2.1 高斯克呂格投影/橫軸墨卡託投影

英文名Gauss Kruger。在一些奇奇怪怪的原因中,又名橫軸墨卡託投影,英文名Transverse Mercator。

它的投影面是橢圓柱面,假設橢圓柱躺著,和地軸垂直,而且投影面與之相切,就是橫軸墨卡託了。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

中央那條黑線就是投影中心線,與橢圓柱面相切。這條線逢360°的因數就可以取,一般多用3度帶、6度帶。

就是說,這個投影橢圓柱面可以繼續繞著地軸繼續轉,圖中還有一條經線,兩條相差6度。

橢圓柱面旋轉6度,繼續投影,直到360/6=60個投影帶投影完畢。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

注意3度帶和6度帶的起算經線不同,以及Y方向(赤道方向)前需要加投影帶號。

高斯克呂格已經廣為熟知了,我就不作具體介紹,大家可以找比我解釋的更好的,我只是擺個圖希望大家看的更仔細。

這個投影的特點是,等角/橫/切橢圓柱/投影。

即適用比例尺:1:2.5萬~1:100萬等使用6度分帶法;1:5000~1:10000使用3度分帶法。

【注】在ArcGIS中,不同的GCS的PCS是不同的,以CGCS2000、西安80和北京54為例:

CGCS2000_3_Degree_GK_CM_111E:CGCS2000的GCS下,使用高斯克呂格3度分帶法,以中央經線為東經111度的投影帶的投影坐標系

CGCS2000_3_Degree_GK_Zone_30:CGCS2000的GCS下,使用高斯克呂格3度分帶法,第30個投影帶的投影坐標系

Beijing_1954_3_Degree_GK_CM_111E:北京54的GCS下,使用高斯克呂格3度分帶法,以中央經線為東經111度的投影帶的投影坐標系

Beijing_1954_3_Degree_GK_Zone_35:北京54的GCS下,使用高斯克呂格3度分帶法,第35個投影帶的投影坐標系

Xian_1980_3_Degree_GK_CM_111E:西安80的GCS下,使用高斯克呂格3度分帶法,以中央經線為東經111度的投影帶的投影坐標系

Xian_1980_3_Degree_GK_Zone_34:西安80的GCS下,使用高斯克呂格3度分帶法,第34個投影帶的投影坐標系

不難發現,都是以GCS起頭的命名法。

2.2.2 墨卡託投影

英文名Mercator投影。

數學上,投影面是一個橢圓柱面,並且與地軸(地球自轉軸)方向一致,故名:「正軸等角切/割圓柱投影」。

既可以切圓柱,也可以割圓柱。

其實就是高斯克呂格的圓柱面豎起來。

2.2.3 通用橫軸墨卡託投影(UTM投影)

英文全稱Universal Transverse Mercator。是一種「橫軸等角割圓柱投影」

和高斯克呂格類似,高斯克呂格的投影面是與橢球面相切的,這貨與橢球面相割。

實質上其餘性質都和高斯克呂格投影一樣。

割於緯度80°S和84°N。中央經線投影后,是原長度的0.9996倍。

不過,起算投影帶是180°經線,174°W則是第二個投影帶的起算經線。

由於有以上優點,UTM投影被許多國家和地區採用,作為大地測量和地形測量的投影基礎。

【注】UTM投影是我國各種遙感影像的常用投影。

【注2】UTM投影在ArcGIS中的定義

例如:

WGS_1984_UTM_Zone_50N,就代表WGS1984的GCS下,進行UTM投影,投影帶是50N.

WGS_1984_Complex_UTM_Zone_25N,就代表WGS1984的GCS下,進行3度分帶UTM投影,投影帶是25N.

2.2.4 Lambert投影

中文名蘭伯特投影、蘭博特投影。

我國地形圖常用投影,比如1:400萬基礎數據:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

(GCS是北京54)可以看到授權是自定義,說明這個投影是自定義的,沒有被官方收錄。等到第三部分再說怎麼自定義投影。

我國的基本比例尺地形圖(1:5千,1:1萬,1:2.5萬,1:5萬,1:10萬,1:25萬,1:50萬,1:100萬)中,1:100萬地形圖、大部分省區圖以及大多數這一比例尺的地圖多採用Lambert投影。

蘭伯特投影是一種「等角圓錐投影」。

ArcGIS中的投影系一般帶有Lambert_Conformal_Conic等字樣,國際上用此投影編制1∶100萬地形圖和航空圖。

它就像是一個漏鬥罩在桌球上:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

更標準的畫法,見下圖,有切和割兩種。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

它沒有角度變形。

這個漏鬥的傾斜程度,就有三種:正軸、橫軸、斜軸。就是圓錐的方向和地軸的方向的問題。

2.2.5 Albers投影

中文名阿伯斯投影。又名「正軸等積割圓錐投影」,常用於我國各省市的投影。

和上一個蘭伯特圖形類似,就是一個圓錐與橢球面切割,進行等積投影。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

給了官方WKID:102025.

與Lambert投影的區別大概就在一個等角,一個等積投影了。

2.2.6 Web墨卡託(WebMercator投影)

這是一個由Google提出的、為了自家GoogleMap而專門定義的一種投影,是墨卡託投影的一種變種。

主要是將地球橢球面當作正球面來投影,這就會導致一定的誤差。

直接看看ArcGIS中的定義:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

給了WKID:3857,名字是WGS_1984_Web_Mercator_Auxiliary_Sphere,意思就是在WGS84的GCS下進行web墨卡託投影。

現在,經常被百度地圖等網絡地圖採用,估計是Web程式設計師想省事吧。

3. GCS與PCS的轉換問題(ArcGIS實現)

3.1 GCS轉GCS

這就是屬於空間解析幾何裡的空間直角坐標系的移動、轉換問題,還有個更高級的說法——仿射變換。

我們知道,空間直角坐標系發生旋轉移動縮放,在線性代數裡再常見不過了。在攝影測量學中,旋轉矩陣就是連接像空間輔助坐標系與像空間坐標系的轉換參數(好像不是這倆坐標系,忘了)

欲將一個空間直角坐標系仿射到另一個坐標系的轉換,需要進行平移、旋轉、縮放三步,可以無序進行。

而平移、旋轉又有三個方向上的量,即平移向量=(dx,dy,dz)和旋轉角度(A,B,C),加上縮放比例s,完成一個不同的坐標系轉換,就需要7參數。

我們知道,地心坐標系是唯一的,即原點唯一,就說明平移向量是0向量,如果縮放比例是1,那麼旋轉角度(A,B,C)就是唯一的仿射參數,即3參數。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

上圖左圖為坐標系平移,右圖為坐標系旋轉。縮放可以在任意階段進行。

——————以上為理論預備——————

說了這麼多理論,如何進行GCS轉換呢?假設一個數據源已經有了GCS,我們需要做的操作只有一個:

打開如下工具:數據管理工具/投影和變換/投影,設置界面如下(以WGS1984轉西安80為例):

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

別選錯了,這裡輸入輸出都是GCS。然後出現以下警告:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

這就告訴你,需要參數轉換。在這裡,WGS84轉西安80,是屬於7參數轉換(地心轉參心),但是缺少7參數,就需要自己去測繪局買或者自己粗略算。

那麼如何定義一個地理坐標變換呢?

使用投影的旁邊的工具:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

即可。見下圖:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

使用Position_Vector方法(即7參數法)即可輸入7參數。我就不輸入了,各位有數據的可以繼續做。

關於3參數和7參數,在ArcGIS幫助文檔裡都寫有的,目錄如下:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

3.2 GCS進行投影

這個就更簡單了。

隨便挑個GCS,喜歡什麼用什麼,如西安80投影到UTM投影,都可以的。

仍然是上節提及的「投影工具」:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

這樣就可以了,這裡是以WGS84的GCS投影到UTM的第50分度帶上。

如果是進行柵格數據的投影,就用「柵格」文件夾下的「投影柵格」工具。

如果所需投影系沒有自己需要的GCS,就自定義一個:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

這個窗口在Catalog浮動窗或者Catalog軟體裡打開某個數據的屬性,找到XY坐標系的選項卡,就可以新建。

【注】如果在數據的屬性頁的XY坐標系選項卡,或者圖層數據框的XY坐標系選項卡中修改GCS,這僅僅是改個名,坐標值還是原來的坐標系上的,這代表老坐標值並沒有轉換到新坐標繫上。形象說,就是換湯不換藥,這是不對的。我這裡說的用投影的方法,才是真正的坐標仿射變換到新的坐標系,使之更改數值,形成在新的坐標系下的新坐標值。

3.3 PCS轉PCS(重投影)

最常見的就是下載了谷歌影像圖,是Web墨卡託的投影,但是實際又需要高斯投影,那麼基於WGS84這個GCS,就可以進行重投影。

在這裡,我就以UTM投影轉Web墨卡託投影為例:

這次是用「柵格」文件夾下的「投影柵格」工具:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

一般選好紅框的三個參數即可。

如果仍然提示需要地理坐標變換的警告,說明不是一個GCS的數據,需要3參數或者7參數轉換。

柵格數據類似,使用「投影工具」。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

工具定位。

3.4 定義投影

這不是定義一個投影坐標系,而是給有坐標值的矢量或者柵格數據添加一個投影坐標系而已。

使用「定義投影」工具即可,既可以定義GCS,也可以定義PCS(這軟體的中文翻譯有點毛病)。

3.5 地理配準與空間校正

這個就不多說了,地理配準就是使屏幕坐標系的掃描地圖仿射、二次三次變換到真正投影坐標系的過程,自動加上目標數據的PCS。有了PCS後就會自動加上GCS。

地理配準主要是針對柵格數據。

空間校正則是針對矢量數據進行仿射、二次、三次變換。

3.6 可能出現的錯誤

3.6.1 顯示幾十萬位數字的「經緯度」

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

如上圖。

這是有了PCS後,在Catalog的數據屬性頁的XY坐標系選項卡裡,選中GCS,然後應用的結果。

原本是方裡網的數字,變成了GCS才有的度分秒。

解決方法:Catalog屬性頁將GCS改回原來的PCS即可。

3.6.2 顯示三位數、兩位數的「米」

這個暫時沒找到案例,曾經見過。

3.6.3 顯示一個幾乎是0,一個又很大很大位數的數字

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

如上圖。

這個屬於數據本身有GCS,但是在Catalog的XY坐標系選項卡裡給它添加PCS然後應用後,可能會出現的錯誤。

解決方法:在Catalog屬性頁的XY坐標系選項卡裡,選中原來的GCS然後應用即可。

如果數據本身沒有PCS,應該做的是投影操作。

3.6.4 大範圍的數據給了小範圍的投影

例如,整個中國地圖理應跨越好幾個投影帶,卻給了某一個投影帶的投影坐標系,這就會出現負值。如下圖,紅框箭頭是滑鼠的位置。

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

這個按理說應該用蘭伯特投影,但是卻給了一個UTM第49區的PCS,所以在中央經線靠左很多的位置會出現負值。

解決方法:這個直接做重投影即可。

以上四種錯誤比較常見,但是手頭沒有案例,以後遇到再發上來吧。

總結一下:

java 判斷一個地理坐標是否在電子圍欄 圓、矩形、多邊形區域內

4. 火星坐標

火星坐標這個東西很常見,出現在網際網路地圖上。例如百度、騰訊、谷歌等地圖。

出於保密等政治因素,地圖的GCS坐標值,會被一種特殊的數學函數加密一次,會偏離真實坐標數百米的距離,但是反饋到用戶端的卻是正確的位置信息(也就是說你拿到GCS坐標也沒用,拿GPS到實地跑跟拿著地圖定位,可能會偏出幾十米甚至一百米的距離)。

火星坐標系原名國測局坐標系(GCJ-02),有篇文章比我寫的透徹多了,甚至給出了還原代碼,我放到參考資料了,有興趣的可以看看。

已JAVA語言為例,說明如何判斷一個坐標點位是否在規定的電子圍欄裡面

/** * 地球半徑 */ private static double EARTH_RADIUS = 6378138.0; private static double rad(double d) { return d * Math.PI / 180.0; }

   /** * 計算是否在圓上(單位/千米) * * @Title: GetDistance * @Description: TODO() * @param radius 半徑 * @param lat1 緯度 * @param lng1 經度 * @return * @return double * @throws */ public static boolean isInCircle(double radius,double lat1, double lng1, double lat2, double lng2) { double radLat1 = rad(lat1); double radLat2 = rad(lat2); double a = radLat1 - radLat2; double b = rad(lng1) - rad(lng2); double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) + Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2))); s = s * EARTH_RADIUS; s = Math.round(s * 10000) / 10000; if(s > radius) {//不在圓上 return false; }else { return true; } }

/** * 是否在矩形區域內 * @Title: isInArea * @Description: TODO() * @param lat 測試點經度 * @param lng 測試點緯度 * @param minLat 緯度範圍限制1 * @param maxLat 緯度範圍限制2 * @param minLng 經度限制範圍1 * @param maxLng 經度範圍限制2 * @return * @return boolean * @throws */ public static boolean isInRectangleArea(double lat,double lng,double minLat, double maxLat,double minLng,double maxLng){ if(isInRange(lat, minLat, maxLat)){//如果在緯度的範圍內 if(minLng*maxLng>0){ if(isInRange(lng, minLng, maxLng)){ return true; }else { return false; } }else { if(Math.abs(minLng)+Math.abs(maxLng)<180){ if(isInRange(lng, minLng, maxLng)){ return true; }else { return false; } }else{ double left = Math.max(minLng, maxLng); double right = Math.min(minLng, maxLng); if(isInRange(lng, left, 180)||isInRange(lng, right,-180)){ return true; }else { return false; } } } }else{ return false; } }

/** * 判斷是否在經緯度範圍內 * @Title: isInRange * @Description: TODO() * @param point * @param left * @param right * @return * @return boolean * @throws */ public static boolean isInRange(double point, double left,double right){ if(point>=Math.min(left, right)&&point<=Math.max(left, right)){ return true; }else { return false; } }

/** * 判斷點是否在多邊形內 * @Title: IsPointInPoly * @Description: TODO() * @param point 測試點 * @param pts 多邊形的點 * @return * @return boolean * @throws */ public static boolean isInPolygon(Point2D.Double point, List<Point2D.Double> pts){ int N = pts.size(); boolean boundOrVertex = true; int intersectCount = 0;//交叉點數量 double precision = 2e-10; //浮點類型計算時候與0比較時候的容差 Point2D.Double p1, p2;//臨近頂點 Point2D.Double p = point; //當前點 p1 = pts.get(0); for(int i = 1; i <= N; ++i){ if(p.equals(p1)){ return boundOrVertex; } p2 = pts.get(i % N); if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){ p1 = p2; continue; } //射線穿過算法 if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){ if(p.y <= Math.max(p1.y, p2.y)){ if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){ return boundOrVertex; } if(p1.y == p2.y){ if(p1.y == p.y){ return boundOrVertex; }else{ ++intersectCount; } }else{ double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y; if(Math.abs(p.y - xinters) < precision){ return boundOrVertex; } if(p.y < xinters){ ++intersectCount; } } } }else{ if(p.x == p2.x && p.y <= p2.y){ Point2D.Double p3 = pts.get((i+1) % N); if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){ ++intersectCount; }else{ intersectCount += 2; } } } p1 = p2; } if(intersectCount % 2 == 0){//偶數在多邊形外 return false; } else { //奇數在多邊形內 return true; } }

相關焦點

  • 使用Python OpenCV處理圖像之詳解直線、圓、矩形及文字的繪製
    Python使用tkinter製作一個簡易的繪圖程序一(Python GUI編程))中講到的繪製基本的直線、圓、橢圓、矩形、多邊形、文字等。我們要開始了【內容】直線、圓、橢圓、矩形、多邊形、文字的繪製方法通過基礎知識的學習,我們繪製一個OpenCV的logo圖像並顯示保存【基本圖形繪製】
  • 車載GPS定位器的「電子圍欄」功能怎麼使用?
    這裡就拿GPS定位器的電子圍欄功能跟大家詳細說一說。電子圍欄,就是通過GPS定位後臺設置一個範圍,形成一個圍欄式警戒區域。在斯沃德的立即定位平臺,這個區域可設置成規則狀,如圓形、矩形;也可以設置成其他的不規則形狀。當目標車輛進入該區域或者離開該區域時,後臺就會接到報警信息。管理人員可以立即鎖定該車輛,進行下一步的處理操作。
  • 從正多邊形到圓
    知道了,正三角形的特性以後,其實畫一個正三角形就很簡單了。如上,幾個簡單的積木就能畫出一個正三角形。「那如果要畫正五邊形怎麼畫呢?」 我問京京。正五邊形也就是5條邊長都相等,5個內角也相等,難就難在不知道正5邊形的內角和是多少度。「那正四邊形是什麼呢?」 京京補充問著。
  • 幫你判斷地理坐標的神奇口訣
    根據搜救人員估計,飛機失聯地點大約在北緯6°55′15",東經103°34′43",依據這個地理坐標全球立刻展開了聯合搜救行動。馬航失聯客機航線及失聯地點示意圖 鳳凰網提供失聯地點的地理坐標北緯6°55′15",東經103°34′43",它是怎樣得到的呢?這就需要方格狀經緯網來幫助我們判斷點的地理坐標。
  • 科普| 電子圍欄系統基礎知識問答
    根據運行原理的不同,市場上的電子圍欄產品主要分為脈衝型電子圍欄和張力式電子圍欄兩種。 脈衝電子圍欄系統:由脈衝電子圍欄主機和脈衝電子圍欄前端兩部分組成,脈衝電子圍欄主機發出安全的高壓脈衝電,並輸送到脈衝電子圍欄前端(合金線),脈衝電子圍欄主機通過監測脈衝電流是否有短路或斷路的情況,來判斷是否發生入侵。
  • 2019初三數學知識點:正多邊形與圓
    1、正多邊形與圓有著密切的關係: 1)把一個圓的圓周分成n等份,順次連接各分點所得圖形,即為圓的內接正n邊形,這個圓叫做這個正n邊形的外接圓。 2)正多邊形的相關概念:正多邊形的中心——是正多邊外接圓的圓心。正多邊形的半徑——是正多邊形內切圓半徑。(rn)正多邊形的中心角——是正多邊形的邊所對的外接圓的圓心角。
  • 邊界安防:電子圍欄發展及分類選擇
    電子圍欄最早起源於澳洲的流動牧場,是牧人們最先利用通有直流電的導線圈定所圈養牲畜的活動範圍。由於這種簡單的「電子圍欄」的電流對內可以管控牲畜的行動,對外又可以防止大型野生動物或食肉猛獸的侵襲,並且安裝便捷移動簡單,對當時的牧業廣泛發展起到了極大的促進作用。
  • 如何用java判斷一個數是不是質數?
    哈嘍大家好,這是java小白成長記!昨天分享了怎麼判斷一個數是不是迴文數,目的是為了鞏固一下if選擇語句和求餘數運算符,今天分享一下怎麼判斷一個數是不是質數,可以鞏固for循環、if選擇語句、還有沒怎麼使用過的基本數據類型Boolean。
  • 中國三角形5——多邊形分割圓的面
    而且有結論:n邊形的面の數= (這裡說的面の數是指在對角線分割之下)今天我們來講多邊形分割之下圓的面數和中國三角形的關係它和上文的結論有很大的關係,而且會引出一道網上的錯題這道錯題在很多教育學習網站上都有,是一道高三的考試題但是出錯了,先給大家貼一張這道題的圖片OK,現在我們先看一下多邊形分割之下圓的面數①三邊形,4個面②四邊形,8個面
  • 掌上微課堂|「圓」來如此之圓內接四邊形
    知識點1圓的內接多邊形如果多邊形的所有頂點都在一個圓上,那麼這個多邊形叫做圓內接多邊形,這個圓叫做多邊形的外接圓.針對這一概念,這裡或許你有很多疑問:(1)三角形都有外接圓嗎?老師回答你,三角形三邊垂直平分線交於一點,這點到三個頂點距離相等,這點叫做三角形外接圓的圓心.三角形一定有外接圓.
  • 中考數學——相似形、相似多邊形、比例線段的定義及例題解析
    2.相似多邊形(1)相似多邊形的定義:一般地,兩個邊數相同的多邊形,如果他們的對應角相等,對應邊長度的比相等,那麼這兩個多邊形叫做相似多邊形。(2)相似多邊形對應邊長度的比叫做相似比或相似係數。注意:相似多邊形定義的作用:(1)判定作用:如果兩個多邊形滿足兩個條件:對應角相等;對應邊長度的比相等,那麼這兩個多邊形相似。(2)性質作用:如果已知兩個多邊形相似,那麼這兩個多邊形的對應角相等,對應邊長度的比相等。
  • Mobject類:坐標系、特殊矩形、函數、數字
    一個AnimatedBoundary的例子渲染效果:AnimatedBoundary包含兩個方法full_family_become_partial;update_boundary_copies;一個TracedPath的例子渲染效果坐標系【coordinate_systems】代表坐標系的Mobjects
  • 詳解Java表達式與運算符
    通過本課的學習你將掌握運用表達式和運算符完成變量賦值、條件判斷、數學運算、邏輯運算等功能操作】在講述課程內容之前,先看一個求圓面積的問題。求圓面積的公式為;其中S為圓面積,π為圓周率,r為半徑。第一種比較方式是判斷兩個操作數是否相等,用運算符「==」進行運算,如果兩個操作數相等,比較結果返回true,否則返回false。第二種比較方式是判斷兩個操作數是否不相等,用運算符「!=」進行運算,如果兩個操作數不相等,比較結果返回true,否則返回false。
  • 正多邊形與圓的關係——那些數學大牛是咋算出圓周率的?
    科普中國——科學原理一點通    知識點:圓內接正多邊形有這樣的特點:隨著正多邊形邊數的增加,它會越來越貼近圓的邊。
  • 中考數學專題複習:第24講 圓的有關計算
    ①圓與相似三角形結合的計算;②圓與三角函數結合的計算;③圓與勾股定理結合的計算。2、基本方法圓與其他圖形結合時,注意勾股定理方程的運用、相似三角形與圓結合的常見模型、轉化三角函數方法等。類型三 圓與正多邊形的計算【解後感悟】本題是正六邊形的有關計算,運用正六邊形的性質將正六邊形轉化為直角三角形或等邊三角形是解題的關鍵.