1. 程式人生 > >c# 畫任意多邊形並判斷點是否在多邊形內(計算任意多邊形面積)

c# 畫任意多邊形並判斷點是否在多邊形內(計算任意多邊形面積)

c# winform 中實現計算任意多邊形面積,包括 凹多邊形,線段有交叉的多邊形等。具體形式如下:

凸多邊形凹多邊形線段有交叉多邊形

目標:計算紅色區域的面積
實現的方法:
1、首先能夠在滑鼠點選事件、滑鼠移動事件、和paint事件中實現多邊形的繪製。
2、利用GraphicsPath記錄多邊形頂點座標;System.Drawing.Region 記錄多邊形區域
3、 使用Region 變數中IsVisible方法判斷新的點是否在多邊形區域內。

主要程式碼如下(懶,沒寫註釋,但是都不難理解的)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using
System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace functiontest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private
void button1_Click(object sender, EventArgs e) { } private void Form1_Paint(object sender, PaintEventArgs e) { System.Drawing.Pen pen = new Pen(Color.Red); if(isDrawing==1) { if(drawpaths.Count>=1) { foreach
(List<PointF> drawpath in drawpaths) { if (drawpath.Count >= 2) { e.Graphics.DrawLines(pen, drawpath.ToArray()); if (continues.Equals(PointF.Empty) == false) { e.Graphics.DrawLine(pen, start, continues); } } else { if(continues.Equals(PointF.Empty)==false) { e.Graphics.DrawLine(pen, start, continues); } } } } if (drawpathtemp.Count >= 2) { e.Graphics.DrawLines(pen, drawpathtemp.ToArray()); if (continues.Equals(PointF.Empty) == false) { e.Graphics.DrawLine(pen, start, continues); } } else { if (continues.Equals(PointF.Empty) == false) { e.Graphics.DrawLine(pen, start, continues); } } } else if(isDrawing==0) { foreach (List<PointF> drawpath in drawpaths) { if (drawpath.Count >= 2) { e.Graphics.DrawLines(pen, drawpath.ToArray()); } } } } Region r = new System.Drawing.Region(); PointF start = PointF.Empty; PointF continues = PointF.Empty; PointF end = PointF.Empty; int isDrawing = 0; List<List<PointF>> drawpaths = new List<List<PointF>>(); List<PointF> drawpathtemp = new List<PointF>(); private void Form1_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (isDrawing==0) { start = e.Location; isDrawing = 1; drawpathtemp.Add(start); } else if(isDrawing==1) { start = e.Location; drawpathtemp.Add(start); } else if(isDrawing==2) { } this.Refresh(); } if (e.Button == MouseButtons.Right) { if (r.IsVisible(e.Location)) { MessageBox.Show("在選中區域內"); } else { MessageBox.Show("不在選中區域內"); } } } private void Form1_MouseMove(object sender, MouseEventArgs e) { if(isDrawing==1) { continues = e.Location; this.Refresh(); } } private void Form1_KeyDown(object sender, KeyEventArgs e) { switch(e.KeyCode) { case Keys.Escape: drawpathtemp.Add(drawpathtemp.ElementAt(0)); List<PointF> temp = new List<PointF>(); if(drawpathtemp.Count>2) { temp = drawpathtemp.GetRange(0, drawpathtemp.Count); drawpaths.Add(temp); } drawpathtemp.Clear(); start = PointF.Empty; end = PointF.Empty; continues = PointF.Empty; isDrawing = 0; GraphicsPath gp = new GraphicsPath(); gp.Reset(); foreach (List<PointF> item in drawpaths) { gp.AddPolygon(item.ToArray()); r.MakeEmpty(); r.Union(gp); } this.Refresh(); break; default: break; } } } }

操作說明:
1、新建專案,拷貝程式碼,編譯成功後執行。
2、滑鼠左鍵單擊視窗開始畫多邊形,按esc鍵結束,同時最後一個點座標與第一個點座標連線。形成封閉的多邊形。
3、可以畫多個多邊形,可以自己嘗試。
4、判斷點是否在區域內:滑鼠右鍵,即會彈出框所點選的座標是否在多邊形內。

程式碼僅供參考,因為是自己寫的demo測試程式,還沒移植到我自己的工程中,所以有點亂。

相關推薦

c# 任意多邊形判斷是否在多邊形計算任意多邊形面積

c# winform 中實現計算任意多邊形面積,包括 凹多邊形,線段有交叉的多邊形等。具體形式如下: 目標:計算紅色區域的面積 實現的方法: 1、首先能夠在滑鼠點選事件、滑鼠移動事件、和paint事件中實現多邊形的繪製。 2、利用GraphicsPa

c#實現 改進弧長法判斷多邊形裡面

一、開發環境:     VS2017,C# winform視窗程式 二、不同點      和網上的介紹不同,我也 不清楚是為什麼,我去實現別的部落格的思路,始終是在象限相差為2的地方會判斷不正確,所以我自己思考了一種方法來進行這個地方的處理。 三、演算法思路解釋 1

cornerSubPixel亞素角檢測原始碼分析最小二乘法

OpenCV的中有cornerSubPixel()這個API函式用來針對初始的整數角點座標進行亞畫素精度的優化,該函式原型如下: C++: void cornerSubPix(InputArray image, InputOutputArray corners, Siz

POJ 1410 Intersection 判斷線段交和在矩形計算幾何】

Intersection Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9996 Accepted: 2632 Description You are to

【應用CC語言實現HashSet模仿Java機制和語法+原始碼

文章目錄 01 - HashSet 02 - HashCode 02 - 模仿Java機制和語法 2.1 - 模仿泛型 2.2 - 模仿自動擴容 2.3 - 模仿迭代器 03 - 結果測

Android 自己定義圓圈進度顯示百分比例控件純代碼實現

edate gif reset attr oval auth attrs pan 我們 首先,感謝公司能給我閑暇的時間,來穩固我的技術,讓我不斷的去探索研究,在此不勝感激。 先不說實現功能,上圖看看效果 這個是續上一次水平變色進度條的有一個全新的控件,理論實現原理 1.

angular2^ typescript 將 文件和Json數據 合發送到服務器1.客戶端處理

src ica div .html web ready 進行 form med 首先介紹下框架基本流程 (web > webservice 【前端架構】 ) > (nodejs 【 數據中轉站 】) >(api 【後臺接口】) --web (htm

java發之線程同步synchronized和鎖機制

blog 是否 can return nbsp jvm 環境 imp ava 使用synchronized實現同步方法 使用非依賴屬性實現同步 在同步塊中使用條件(wait(),notify(),notifyAll()) 使用鎖實現同步 使用讀寫鎖實現同步數據訪問 修改

原生js解決圖片擊左右切換簡單輪播圖

邏輯關系 element logs 內容 點擊切換 osi 圖片 width eight 想寫一個綜合性的小案例,主要會運用到數組和判斷以及我前面幾篇博客所復習到的js的知識。今天案例想要實現的效果圖如下圖所示: 效果是:點擊“循環切換”按鈕,那麽“一號”位置的文案就要

零基礎掌握百度地圖興趣獲取POI爬蟲python語言爬取基礎篇

region map 基礎 輸入 filter put mark page -h 實現目的:爬取昆明市範圍內的全部中學數據,包括名稱、坐標。 先進入基礎篇,本篇主要講原理方面,並實現步驟分解,為python代碼編寫打基礎。 因為是0基礎開始,所以講得會比較詳細。 如實現目的

shell 腳本創建虛擬機 配置網卡ip地址兩個腳本

kvm#######################腳本1:創建虛擬機kvm##########################!/bin/bashqcow2_dir=/var/lib/libvirt/imagesread -p "請輸入虛擬機號碼:" num #主機號if [ $n

讀取word文檔提取和寫入數據基於python 3.6

number import utf-8 for 文本 pre ext 3.6 war #!/usr/bin/python3# -*- coding: utf-8 -*-# @File : delete_file# @Author : moucong# @Date

jq自定義下拉菜單,當用戶擊非自身元素下拉菜單本身時關閉下拉菜單

info alt one === 下拉 AS 菜單 com code jq自定義下拉菜單,當用戶點擊非自身元素(下拉菜單)本身時關閉下拉菜單 截圖: 代碼如下: //關閉用戶菜單 $(document).mousedown(function(e){

有關素數判斷的一些算法總結&&對比

stat names 最小 csdn fread AR 目前 ike new 素性測試是數論題中比較常用的一個技巧。它可以很基礎,也可以很高級(哲學)。這次主要要介紹一下有關素數判斷的奇技淫巧 素數的判斷主要分為兩種:範圍篩選型&&單個判斷型 我們先從範圍篩

C#實踐問題:日期格式轉換以及日期比較日期函式使用大全

轉自:https://www.cnblogs.com/zpq521/archive/2008/07/09/1238905.html   C#日期函式使用大全 DateTime dt = DateTime.Now;dt.ToString();//20

C#LeetCode刷題之#657-機器人能否返回原點Robot Return to Origin

問題 在二維平面上,有一個機器人從原點 (0, 0) 開始。給出它的移動順序,判斷這個機器人在完成移動後是否在 (0, 0) 處結束。 移動順序由字串表示。字元 move[i] 表示其第 i 次移動。機器人的有效動作有 R(右),L(左),U(上)和 D(下)。如果機器人在完成所有動作後

C#LeetCode刷題之#551-學生出勤紀錄 IStudent Attendance Record I

問題 給定一個字串來代表一個學生的出勤紀錄,這個紀錄僅包含以下三個字元: 'A' : Absent,缺勤 'L' : Late,遲到 'P' : Present,到場 如果一個學生的出勤紀錄中不超過一個'A'(缺勤)並且不超過兩個連續的'L'(遲到),那麼這個學生會被獎賞。 你需要根

C#LeetCode刷題之#521-最長特殊序列 ⅠLongest Uncommon Subsequence I

問題 給定兩個字串,你需要從這兩個字串中找出最長的特殊序列。最長特殊序列定義如下:該序列為某字串獨有的最長子序列(即不能是其他字串的子序列)。 子序列可以通過刪去字串中的某些字元實現,但不能改變剩餘字元的相對順序。空序列為所有字串的子序列,任何字串為其自身的子序列。 輸入為兩個字串,

C++】int轉換為string的兩種方法to_string、字串流轉載

int轉換成string的兩種方法 第一種是to_string函式,這是C++11新增的,使用非常方便,簡單查了下:C++11標準增加了全域性函式std::to_string,以及std::stoi/stol/stoll等等函式(這幾個就是string轉int,long,以及long lo

C++遍歷資料夾下所有的wav檔案支援windows和Linux

直接上程式碼: #include <iostream> #include <string> #include <vector> #include <fstream> #include <string.h> #includ