主頁 > 軟體工程 > 關于凹多邊形的三角剖分,在VB6.0里如何實作?

關于凹多邊形的三角剖分,在VB6.0里如何實作?

2020-09-12 01:16:58 軟體工程

最近正在學習VB語言,在CAD二次開發中想要對多邊形進行質心的計算,論壇上查看了很多資訊,大部分的建議是先對多邊形進行三角剖分,然后根據三角形重心求得多邊形重心,因此關于任意多邊形的三角剖分在VB中的實作存在困難,希望各位大神指點。

uj5u.com熱心網友回復:

對于凸多邊形,很簡單,N邊型任意一個頂點依次和其他頂點相連就分隔出來N-1個三角形(三點共線的問題特殊處理)
對于凹多邊形,在凹陷處沿著凹陷處的一條邊延長分隔,再繼續檢查分隔后的多邊形是不是凹多邊形,是的話繼續按照這個規則分隔,于是最終可以遞回將一個凹多邊形分隔成若干個凸多邊形。

接下來的問題就是如何判定一個多邊形是凸多邊形?

凸多邊形的一個特征以任意一條邊延長畫一條直線,那么其他所有頂點都在這條直線的一側。
凹多邊形就總能找到至少兩條邊的延長直線,其他頂點不全分布在這條直線的一邊。



那么解決的思路就是遍歷所有邊逐一畫延長線,逐一判斷這條邊兩個頂點以外其他頂點是否在這條直線的一側。
遍歷不用多說,回圈解決。
一條邊畫直線問題,這個是初中知識:已知兩點坐標,求經過兩點的直線方程f(x,y)=0
哎,為了后面好描述,算了寫出來吧,(y-y2)/(y1-y2) - (x-x2)/(x1-x2) = 0 
這個式子的意思就是把一個點的坐標x,y帶入這個方程,成立就在這條直線上,不成立就不在這條直線上。

線搞定了,現在如何判斷其他頂點是否在這條直線同一端呢?
其他頂點肯定不在這條直線上嘛,x,y代入以后結果鐵定不為0嘛。在直線一側的點,代入結果都為正,另一側代入結果都為負(具體原因自己回憶初中知識)

那么識別突多邊形的問題就分解成
1、遍歷多邊形的所有邊
   1.1 取邊的兩個頂點坐標,確定直線方程
   1.2 宣告一個臨時變數tmp1,遍歷多邊形所有其他非該邊的其他頂點
       1.2.1 將頂點坐標代入1.1所確定的直線方程,若所得結果為負則tmp1 = tmp1 -1 否則 tmp1 = tmp1 +1
   1.3 如果abs(tmp1) = 多邊形頂點數-1 那么就是凸多邊形,否則就是凹多邊形。

識別到凹多邊型以后就是看怎么分割了
你自己畫圖試試你的最佳分割方案是啥?是不是從第一個凹陷的邊延長到多邊形另一端和一條邊相交,最簡單?那么如何判定哪條邊會和這條直線相交?還是上面那個思路,把每條邊的兩個頂點代入直線方程,如果兩個點都在直線的一邊,那么就不向交,兩個端點一邊一個,那必然相交。
相交于哪個點呢?初中知識:已知兩條直線的方程,求交點坐標。后面的事情就是把頂點和新增的這個焦點分兩撥,充新建立各條邊的向量,就完成一次分割了。

但這就完了?no! 這還是舉的最簡單的例子。對于那些歪七扭八的形狀,情況會復雜很多


對于這個形狀,要分割成多個凸多邊形方案,按上面的基本演算法,也能分出來但不是都最優。

哇啦哇啦講半天,這玩意實作復雜和具體哪個語言有關系么?為啥說在VB中實作存在困難,說得好像用C就兩句話的事情似的。

uj5u.com熱心網友回復:

Emmm……………………
剛才突然有一個想法,想借用三角形右手法則的法向量來判斷凹陷處。試了一下,好像可行,但是有一些bug需要改改。
這會兒要下班了,有空再弄,弄對了驗證沒錯了再貼出來。


uj5u.com熱心網友回復:


一個表單,兩個按鈕,拷貝下面的代碼
command2 點一下初始化
然后command1每點一下多分出一個三角形并顯示。
如果想要點擊一次直接輸出,那么把41行的 >= 改成 = 
多邊形頂點初始化在89行,約定一下,頂點輸入按照順時針或者逆時針依次錄入坐標,這個很重要。

主要是數學問題,涉及求三角形法向量、已知兩點求直線、判斷點在已知直線的哪一側、已知三點坐標求三角形面積,判斷一個點是否在三個點所組成的三角形內




Option Explicit
    Private Type TypTriangle
        A As Variant
        B As Variant
        C As Variant
    End Type
    Dim colPolygon As New Collection  '多邊形頂點集合 約定,按順時針羅列頂點
    Dim colTriangles As New Collection
    
Private Sub Command1_Click()
    Dim i As Long
    
    '開始處理
    Dim A, B, C
    Dim Normal2D As Double
    Dim lastPolyCount As Long
    Dim TmpTriangle(2, 1) As Double '用一個二維陣列來存盤三角形三個頂點坐標
    Do

        For i = 1 To colPolygon.Count - 2
            '按順序取出三個點
            A = colPolygon(i): B = colPolygon(i + 1): C = colPolygon(i + 2)
            '按右手法則獲取這三個點的法向量,由于這只是一個平面上的三角形,所以我們只取Z軸向量
            '正值為指向螢屏內,負值為指向平面外
            Normal2D = (B(0) - A(0)) * (C(1) - A(1)) - (B(1) - A(1)) * (C(0) - A(0))
            '如果向量大于0,且AC直線一側只有一個B點 那么B點是一個突出點
            If Normal2D > 0 And isOnlyOneSide(i) Then
                
                TmpTriangle(0, 0) = A(0): TmpTriangle(0, 1) = A(1)
                TmpTriangle(1, 0) = B(0): TmpTriangle(1, 1) = B(1)
                TmpTriangle(2, 0) = C(0): TmpTriangle(2, 1) = C(1)
                '確認這三個點是一個分割出來的三角形
                colTriangles.Add TmpTriangle
                '同時把B點從多邊形頂點集合中刪掉
                colPolygon.Remove i + 1
                '重新再來觀察這個多邊形
                Exit For
            End If
        Next
    DoEvents
    Loop Until colPolygon.Count >= 2

    '把三角形們畫出來
    For i = 1 To colTriangles.Count
        Me.Line (colTriangles(i)(0, 0), colTriangles(i)(0, 1))-(colTriangles(i)(1, 0), colTriangles(i)(1, 1)), vbRed
        Me.Line (colTriangles(i)(1, 0), colTriangles(i)(1, 1))-(colTriangles(i)(2, 0), colTriangles(i)(2, 1)), vbRed
        Me.Line (colTriangles(i)(2, 0), colTriangles(i)(2, 1))-(colTriangles(i)(0, 0), colTriangles(i)(0, 1)), vbRed
    Next
    
End Sub

'判斷一個點是不是獨立的突出點
Private Function isOnlyOneSide(StartPoint As Long) As Boolean
    Dim i As Long
    Dim A, B, C, X
    Dim SngB As Double, sngtmp As Double
    
    isOnlyOneSide = True
    'Exit Function
    A = colPolygon(StartPoint): B = colPolygon(StartPoint + 1): C = colPolygon(StartPoint + 2)
    '首先確認B點AC直線的哪一側:把需要檢測的點和直線兩點的坐標代入(y-y2)/(y1-y2) - (x-x2)/(x1-x2)
    SngB = Sgn((B(1) - C(1)) / (A(1) - C(1)) - (B(0) - C(0)) / (A(0) - C(0)))
    '然后取其他點在BC直線的哪一側,只要有一個符號和B點代入的結果一致就是false
    For i = 1 To colPolygon.Count
        If i < StartPoint Or i > StartPoint + 2 Then
            X = colPolygon(i)
            '判斷有頂點和B點在同一測
            If SngB = Sgn((X(1) - C(1)) / (A(1) - C(1)) - (X(0) - C(0)) / (A(0) - C(0))) Then
                '判斷這個點是不是在三角形ABC內
                If isPointInTheTri(A, B, C, X) Then
                    isOnlyOneSide = False
                    Exit Function
                End If
            End If
        End If
    Next
End Function
'判斷X點是否在三角形ABC內
Private Function isPointInTheTri(A, B, C, X) As Boolean
    '用面積法 (X1 * Y2 + X2 * Y3 + X3 * Y1 - X1 * Y3 - X2 * Y1 - X3 * Y2)
    Dim S1 As Double, S2 As Double, S3 As Double, S As Double
    S = Abs(A(0) * B(1) + B(0) * C(1) + C(0) * A(1) - A(0) * C(1) - B(0) * A(1) - C(0) * B(1))
    S1 = Abs(X(0) * B(1) + B(0) * C(1) + C(0) * X(1) - X(0) * C(1) - B(0) * X(1) - C(0) * B(1))
    S2 = Abs(A(0) * X(1) + X(0) * C(1) + C(0) * A(1) - A(0) * C(1) - X(0) * A(1) - C(0) * X(1))
    S3 = Abs(A(0) * B(1) + B(0) * X(1) + X(0) * A(1) - A(0) * X(1) - B(0) * A(1) - X(0) * B(1))
    isPointInTheTri = S >= (S1 + S2 + S3)
End Function

Private Sub Init()
    '初始化多邊形頂點
    Dim tmp(1) As Double
    tmp(0) = 250: tmp(1) = 105: colPolygon.Add tmp
    tmp(0) = 310: tmp(1) = 120: colPolygon.Add tmp
    tmp(0) = 380: tmp(1) = 56: colPolygon.Add tmp
    tmp(0) = 409: tmp(1) = 85: colPolygon.Add tmp
    tmp(0) = 387: tmp(1) = 111: colPolygon.Add tmp
    tmp(0) = 293: tmp(1) = 133: colPolygon.Add tmp
    tmp(0) = 372: tmp(1) = 161: colPolygon.Add tmp
    tmp(0) = 308: tmp(1) = 191: colPolygon.Add tmp
    tmp(0) = 393: tmp(1) = 210: colPolygon.Add tmp
    tmp(0) = 261: tmp(1) = 231: colPolygon.Add tmp
    tmp(0) = 320: tmp(1) = 162: colPolygon.Add tmp
End Sub

Private Sub Command2_Click()
    Me.ScaleMode = 3
    Dim i As Long
    '初始化多邊形,約定按照順時針
    Call Init
    
    '畫出多邊形
    For i = 1 To colPolygon.Count - 1
        Me.Line (colPolygon(i)(0), colPolygon(i)(1))-(colPolygon(i + 1)(0), colPolygon(i + 1)(1)), vbBlack
    Next
    Me.Line (colPolygon(i)(0), colPolygon(i)(1))-(colPolygon(1)(0), colPolygon(1)(1)), vbBlack
End Sub

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/8910.html

標籤:VBA

上一篇:物件參考無法識別

下一篇:WriteProcessMemory引數中myItem(i)里面有值嗎?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more