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
【應用C】C語言實現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-學生出勤紀錄 I(Student 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