国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

判斷點在多邊形內算法的C++實現(xiàn)

這篇具有很好參考價值的文章主要介紹了判斷點在多邊形內算法的C++實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本篇博客介紹了使用射線法判斷點在多邊形內部還是外部的算法,并通過C++做了具體實現(xiàn)

1. 算法思路

判斷平面內點是否在多邊形內有多種算法,其中射線法是其中比較好理解的一種,而且能夠支持凹多邊形的情況。該算法的思路很簡單,就是從目標點出發(fā)引一條射線,看這條射線和多邊形所有邊的交點數目。如果有奇數個交點,則說明在內部,如果有偶數個交點,則說明在外部。

如下圖所示:射線和多邊形一共有5個交點,為奇數,所以點在多邊形內

c++ 判斷點在多邊形內,判斷點在多邊形內外,判斷點在多邊形內部外部,射線法

2. 算法步驟

? 2.1 已知點point(x,y)和多邊形Polygon的點有序集合(x1,y1;x2,y2;….xn,yn;);
以point為起點,以無窮遠為終點作平行于X軸的射線line(x,y; -∞,y);循環(huán)取得多邊形的每一條邊side(xi,yi;xi+1,yi+1):
? 2.2. 判斷point(x,y)是否在side上,如果是,則返回true。
? 2.3. 判斷l(xiāng)ine與side是否有交點,如果有則count++。判斷交點的總數count,如果為奇數則返回true,偶數則返回false。

2.4?判斷交點的總數count,如果為奇數則返回true,偶數則返回false。

極端情況需要注意:當射線line經過的是多邊形的頂點時,判斷就會出現(xiàn)異常情況。針對這個問題,由于多邊形的每一個頂點都在兩個線段上,可以根據線段的兩個端點的y坐標做上下判斷,y值較大的頂點稱為上端點,y值較小是下端點。如果射線經過上端點,count加1,如果經過下端點,則count不必加1,如下圖

第一個圖,交叉點為X,先計算線段(p1,p2),由于經過的是p2,即下端點,count值不加;再計算線段(p2,p3),由于經過的是p2,也是下端點,count值還是不加,總結:射線和 多邊形一共有1個交點,為奇數,所以A在多邊形內

第二個圖,交叉點為X,先計算線段(p1,p2),由于經過的是p2,即上端點,count值加1;再計算線段(p2,p3),由于經過的是p2,也是上端點,count值加1,總結:射線和 多邊形一共有3個交點,為奇數,所以A在多邊形內

c++ 判斷點在多邊形內,判斷點在多邊形內外,判斷點在多邊形內部外部,射線法

?3. 實現(xiàn)代碼

#include<iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

// 浮點數最小精度
#define EPSILON 0.000001

// 向量(也可用來表點)
struct  Vec2d
{
	double x, y;

	Vec2d()
	{
		x = 0.0;
		y = 0.0;
	}
	Vec2d(double dx, double dy)
	{
		x = dx;
		y = dy;
	}
	void Set(double dx, double dy)
	{
		x = dx;
		y = dy;
	}
};

// 判斷點在線段上
// (px0, py0)	:	點坐標
// (px1, py1)	:	邊的第一個點
// (px2,py2)	:	邊的第二個點
bool IsPointOnLine(double px0, double py0, double px1, double py1, double px2, double py2)
{
	bool flag = false;
	double d1 = (px1 - px0) * (py2 - py0) - (px2 - px0) * (py1 - py0);
	if ((abs(d1) < EPSILON) && ((px0 - px1) * (px0 - px2) <= 0) && ((py0 - py1) * (py0 - py2) <= 0))
	{
		flag = true;
	}
	return flag;
}

// 判斷兩線段相交
// (px1, py1)	:	第一邊的第一個點
// (px2, py2)	:	第一邊的第二個點
// (px3, py3)	:	第二邊的第一個點
// (px4, py4)	:	第二邊的第二個點
bool IsIntersect(double px1, double py1, double px2, double py2, double px3, double py3, double px4, double py4)
{
	bool flag = false;
	double d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
	if (d != 0)
	{
		double r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3)) / d;
		double s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1)) / d;
		if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1))
		{
			flag = true;
		}
	}
	return flag;
}

// 判斷點是否在多邊形內(點在多邊形的邊上也算在內部)
// (x, y)	:	點坐標
// POL		:	多邊形的各個點(需連續(xù),順時針/逆時針皆可)
bool Point_In_Polygon_2D(double x, double y, const vector<Vec2d>& POL)
{
	bool isInside = false;
	int  count    = 0;

	// 求出多邊形的最小X
	double minX = DBL_MAX;
	for (int i=0; i<POL.size(); i++)
	{
		minX = std::min(minX, POL[i].x);
	}

	double px = x;
	double py = y;

	// 負X方向的水平射線,(x,y)做起點,(minX, y)做終點
	double linePoint1x = x;
	double linePoint1y = y;
	double linePoint2x = minX - 10;			
	double linePoint2y = y;

	// 遍歷每一條邊
	for (int i = 0; i < POL.size()-1; i++)
	{
		double cx1 = POL[i].x;	// 多邊形的第i個點
		double cy1 = POL[i].y;		
		double cx2 = POL[i+1].x;// 多邊形的第i+1個點
		double cy2 = POL[i+1].y;

		// 點在多邊形上,算是在內部
		if (IsPointOnLine(px, py, cx1, cy1, cx2, cy2))
		{
			return true;
		}

		// X方向水平的邊,不用計算,肯定不會和射線相交
		if (fabs(cy2 - cy1) < EPSILON)
		{
			continue;
		}

		// 多邊形的一個頂點在射線上,且該頂點是上頂點(y值較高),算一個交點
		if (IsPointOnLine(cx1, cy1, linePoint1x, linePoint1y, linePoint2x, linePoint2y))
		{
			if (cy1 > cy2)
			{
				count++;
			}
		}
		// 多邊形的一個頂點在射線上,且該頂點是上頂點(y值較高),算一個交點
		else if (IsPointOnLine(cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y))
		{
			if (cy2 > cy1)
			{
				count++;
			}
		}
		// 已經排除平行的情況,其他相交的都算一個交點
		else if (IsIntersect(cx1, cy1, cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y))   
		{
			count++;
		}
	}

	// 交點數為奇數,則在多邊形內,反之在多邊形外
	if (count % 2 == 1)
	{
		isInside = true;
	}

	return isInside;
}


int main()
{
	//定義一個多邊形(六邊形)
	vector<Vec2d> POL;
	POL.push_back(Vec2d(268.28, 784.75));
	POL.push_back(Vec2d(153.98, 600.60));
	POL.push_back(Vec2d(274.63, 336.02));
	POL.push_back(Vec2d(623.88, 401.64));
	POL.push_back(Vec2d(676.80, 634.47));
	POL.push_back(Vec2d(530.75, 822.85));
	POL.push_back(Vec2d(268.28, 784.75));				//將起始點放入尾部,方便遍歷每一條邊

	//
	if (Point_In_Polygon_2D(407.98, 579.43, POL))
	{
		cout << "點(407.98, 579.43)在多邊形內" << endl;
	}
	else
	{
		cout << "點(407.98, 579.43)在多邊形外" << endl;
	}

	//
	if (Point_In_Polygon_2D(678.92, 482.07, POL))
	{
		cout << "點(678.92, 482.07)在多邊形內" << endl;
	}
	else
	{
		cout << "點(678.92, 482.07)在多邊形外" << endl;
	}

	system("pause");
	return 0;
}

4. 執(zhí)行結果

c++ 判斷點在多邊形內,判斷點在多邊形內外,判斷點在多邊形內部外部,射線法文章來源地址http://www.zghlxwxcb.cn/news/detail-660772.html

到了這里,關于判斷點在多邊形內算法的C++實現(xiàn)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 如何判斷兩個多邊形是否相交?——多邊形相交判定算法詳解

    如何判斷兩個多邊形是否相交?——多邊形相交判定算法詳解 在計算機圖形學中,判斷兩個多邊形是否相交是一項很重要的任務。這涉及到各種應用場景,如碰撞檢測、模擬物理效果等。在本篇文章中,我們將會介紹多邊形相交判定算法的相關知識和實現(xiàn)方式。 首先,我們

    2024年02月14日
    瀏覽(87)
  • 基于C++ 的OpenCV繪制多邊形,多邊形多條邊用不用的顏色繪制

    使用基于C++的OpenCV庫來繪制多邊形,并且為多邊形的不同邊使用不同的顏色,可以按照以下步驟進行操作: 首先,確保你已經安裝了OpenCV庫并配置好了你的開發(fā)環(huán)境。 導入必要的頭文件: 創(chuàng)建一個空白的圖像,然后繪制多邊形,并為每條邊選擇不同的顏色: 在這個示例中,

    2024年02月13日
    瀏覽(89)
  • [C++] opencv - approxPolyDP(多邊形擬合)函數介紹和使用場景

    [C++] opencv - approxPolyDP(多邊形擬合)函數介紹和使用場景

    OpenCV中的 approxPolyDP() 函數用于對形狀進行逼近,以減少多邊形的頂點數,可以用于對圖像輪廓點進行多邊形擬合。 函數原型如下: 其中, curve 是輸入的點集,類型為 InputArray, 可以是 Mat 、 vectorPoint 等; approxCurve是輸出的點集,類型為 OutputArray, 也是 Mat 類型; epsilon 是精

    2024年03月14日
    瀏覽(91)
  • [C++] opencv - fillPoly(填充多邊形)函數介紹和使用場景

    [C++] opencv - fillPoly(填充多邊形)函數介紹和使用場景

    fillPoly() 函數是OpenCV中用于繪制填充多邊形的函數。函數原型如下: fillPoly() 函數適用于需要繪制填充多邊形的場景,例如在圖像上繪制一個封閉的圖形、制作一個簡單的遮罩等。 ? fillPoly() 函數是OpenCV中用于繪制填充多邊形的函數??梢杂脕砝L制實心三角形,實心矩形,實

    2024年02月19日
    瀏覽(575)
  • mysql如何實現(xiàn)根據經緯度判斷某一個坐標是否在一個多邊形區(qū)域范圍內

    mysql如何實現(xiàn)根據經緯度判斷某一個坐標是否在一個多邊形區(qū)域范圍內

    要根據經緯度判斷一個坐標是否在一個多邊形區(qū)域內,MySQL提供了幾種函數來處理地理空間數據,其中包括用于處理多邊形區(qū)域的函數。 首先,創(chuàng)建一個表來存儲多邊形區(qū)域??梢允褂?ST_GeomFromText 函數將多邊形的坐標轉換為地理空間對象。我們給他插入兩條數據,默認id第一

    2024年02月08日
    瀏覽(135)
  • Opencv(C++)筆記--繪制直線、矩形、橢圓、圓、填充多邊形、繪制字體和隨機產生坐標點

    Opencv(C++)筆記--繪制直線、矩形、橢圓、圓、填充多邊形、繪制字體和隨機產生坐標點

    目錄 1--cv::line()繪制直線 2--cv::Rect()繪制矩形 3--cv::ellipse()繪制橢圓 4--cv::circle()繪制圓 5--cv::fillPoly()填充多邊形 6--cv::putText()繪制字體 6--cv::RNG隨機產生坐標點 使用 cv::Point p1 定義坐標點; 使用 cv::line() 繪制直線,傳入的參數依次為:背景圖、兩個點的坐標、直線的顏色、直線

    2024年02月14日
    瀏覽(117)
  • 如何判斷一個點是否在凸多邊形內 - golang

    如何判斷一個點是否在凸多邊形內 - golang

    判斷一個點是否在凸多邊形內的方法很多,此處僅給出使用 向量叉積法 判斷點是否在凸多邊形內的方法。 以下圖為例說明問題: 原理: 1. 將多邊形的第 i 條邊的第一個頂點指向點 P 得到向量 v1,然后將從第一個頂點指向第二個頂點得到向量 v2,叉乘這兩個向量。 2. 如果叉

    2024年02月07日
    瀏覽(23)
  • 百度地圖API:JavaScript開源庫幾何運算判斷點是否在多邊形內(電子圍欄)

    百度地圖API:JavaScript開源庫幾何運算判斷點是否在多邊形內(電子圍欄)

    漏刻有時百度地圖API實戰(zhàn)開發(fā)(1)華為手機無法使用addEventListener click 的兼容解決方案 漏刻有時百度地圖API實戰(zhàn)開發(fā)(2)文本標簽顯示和隱藏的切換開關 漏刻有時百度地圖API實戰(zhàn)開發(fā)(3)自動獲取地圖多邊形中心點坐標 漏刻有時百度地圖API實戰(zhàn)開發(fā)(4)顯示指定區(qū)域在移動端異常的

    2024年02月07日
    瀏覽(49)
  • 計算機圖形學實驗——利用MFC對話框實現(xiàn)多邊形繪制與填充(掃描線填充算法)附源碼

    計算機圖形學實驗——利用MFC對話框實現(xiàn)多邊形繪制與填充(掃描線填充算法)附源碼

    內容概括: 利用基于對話框的MFC項目 實現(xiàn)鼠標點擊繪制多邊形 實現(xiàn)掃描線算法填充多邊形 源碼見Yushan-Ji/ComputerGraphics: ECNU2023秋 計算機圖形學課程實驗代碼 (github.com) 通過鼠標交互輸入多邊形 對各種多邊形進行填充,包括邊界自交的情況 利用 OnLButtonDown 和 OnRButtonDown 函數,

    2024年02月04日
    瀏覽(175)
  • 【Weiler-Atherton算法】 計算機圖形學多邊形裁剪算法

    【Weiler-Atherton算法】 計算機圖形學多邊形裁剪算法

    源代碼: https://github.com/ricar0/Weiler-Atherton-Alogrithm/tree/master 通常來說就是利用多邊形來裁剪多邊形的一種方法,一般情況下是利用矩形來裁剪凹凸多邊形 凸多邊形 凹多邊形 上面紅色劃線部分就是裁剪出的部分 OPENGL基礎語法 基本上就是一些畫線和畫多邊形的操作,難度較低

    2023年04月09日
    瀏覽(90)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包