首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 3D 幾何體建模完全指南:MeshGeometry3D 核心屬性與算法生成圓柱體

     編輯:關於.NET

前言:WPF 3D 的基本單元是三角形

WPF 3D (System.Windows.Media.Media3D) 沒有線條、曲線、矩形,**所有物體皆由三角形組成**。三角形唯一確定一個平面,三角形集合可逼近任意立體。核心類 MeshGeometry3D 通過四個屬性定義幾何體:

屬性類型含義
PositionsPoint3DCollection所有頂點座標 (X,Y,Z),右手座標系:X右、Y上、Z向外
TriangleIndicesInt32Collection三個一組的索引,引用 Positions 中頂點,定義三角形。逆時針順序為正面
TextureCoordinatesPointCollection每個頂點對應的 2D 材質座標 (U,V∈[0,1]),(0,0)左上、(1,1)右下
NormalsVector3DCollection每個頂點法向量,決定光照反射。未提供時自動計算相鄰三角形平均法線

Hello3D 範例解析


<MeshGeometry3D
    Positions="-2 1 -1, 0 2 0, 2 1 -1, -2 -1 -1, 0 -2 0, 2 -1 -1"
    TriangleIndices="0 3 1, 1 3 4, 1 5 2, 1 4 5"
    TextureCoordinates="0 0, 0.5 0, 1 0, 0 1, 0.5 1, 1 1" />
  • 6 個頂點:前 3 個頂部,後 3 個底部,中心 Z=0 突出,邊緣 Z=-1 凹陷,形成「屋頂」狀。
  • 4 個三角形:索引 (0,3,1) 等,按逆時針組裝正面朝外。
  • 材質:DiffuseMaterial 用 VisualBrush 繪製 "Hello, World" 文字,背面紅色純色。

算法生成幾何體:為什麼需要代碼生成?

  • 手寫 MeshGeometry3D 僅適合簡單立方體、金字塔。
  • 曲面 (球體、圓柱、環面) 需大量三角形逼近,必須算法生成頂點/索引。
  • MeshGeometry3D 是 sealed,無法繼承;Geometry3D 有 internal 建構函數,也無法直接繼承。

替代方案:ModelVisual3D 衍生類 + 依賴屬性

為什麼選 ModelVisual3D?

Media3D 命名空間中 唯一非 sealed、非 abstract 的具象類**。繼承它可直接放入 Viewport3D,擁有 Content (Model3D) 屬性,天然支援 XAML 實例化、資料綁定、動畫、樣式。

架構設計


// 基類:統一管理 Geometry、Material、BackMaterial 依賴屬性
public abstract class ModelVisualBase : ModelVisual3D {
    public static readonly DependencyProperty GeometryProperty = ...;
    public static readonly DependencyProperty MaterialProperty = ...;
    public static readonly DependencyProperty BackMaterialProperty = ...;
    // PropertyChanged 回調觸發 RegenerateMesh()
}

// 圓柱體具體實現
public class Cylinder : ModelVisualBase {
    // 幾何參數依賴屬性
    public Point3D Point1 { get; set; } // 底面中心
    public Point3D Point2 { get; set; } // 頂面中心
    public double Radius1 { get; set; } // 底面半徑
    public double Radius2 { get; set; } // 頂面半徑 (為 0 即圓錐)
    public int Slices { get; set; } = 16; // 圓周分段
    public int Stacks { get; set; } = 1;  // 軸向分層
    public enum TextureType { None, Drawing, Image }
    public TextureType TextureType { get; set; }
    public double Fold1 { get; set; } = 0.1; // 材質頂部折疊比例
    public double Fold2 { get; set; } = 0.9; // 材質底部折疊比例

    // 核心生成邏輯
    protected override void RegenerateMesh() { ... }
}

關鍵生成算法細節

1. 避免頻繁記憶體分配 (GC 友好)


void GeneratePositions() {
    var mesh = (MeshGeometry3D)Geometry;
    var points = mesh.Positions; // 重用現有集合
    mesh.Positions = null; // 脫離觸發 Changed 事件
    points.Clear();
    // ... 計算頂點填充 points ...
    mesh.Positions = points; // 重新掛載,單次觸發通知
}
  • 構造函數預先分配集合容量 (new Point3DCollection(capacity)),避免擴容分配。
  • 重用 RotateTransform3D、AxisAngleRotation3D 等轉換物件。

2. 接縫處理與材質映射

  • 接縫位置:固定在 Z 軸負方向 (「背面」),頂點重複以使材質左右邊緣對齊。
  • 直角三角形 vs 等腰三角形:軸向切片用直角三角形 (兩個組成矩形),材質映射無拉伸變形;等腰三角形會導致材質扭曲。
  • TextureType 策略:
    • Drawing (漸變/繪圖刷) → 三角形扇形映射,材質環繞頂底面 (圖 7 風格)。
    • Image (位圖刷) → 矩形展開映射,避免頂底面額外接縫 (圖 8 風格)。
    • None → 不生成 TextureCoordinates,純色/實體刷效能最佳。

3. 法向量計算

  • 側面:徑向向外 (根據 Point1→Point2 軸向旋轉基準向量)。
  • 頂/底面:沿軸向向外/向內。
  • 共用頂點處自動平均,產生平滑陰影;銳利棱邊需拆分頂點 (不共用)。

XAML 使用示例

圖片材質圓柱體 (ImageOnCylinder)


<pmg:Cylinder x:Name="cyl" Slices="32" TextureType="Image" Fold1="0.25" Fold2="0.75">
  <pmg:Cylinder.Material>
    <DiffuseMaterial>
      <DiffuseMaterial.Brush>
        <ImageBrush ImageSource="https://example.com/texture.jpg" />
      </DiffuseMaterial.Brush>
    </DiffuseMaterial>
  </pmg:Cylinder.Material>
  <pmg:Cylinder.Transform>
    <RotateTransform3D>
      <RotateTransform3D.Rotation>
        <AxisAngleRotation3D Axis="0 1 0" Angle="{Binding Value, ElementName=slider}" />
      </RotateTransform3D.Rotation>
    </RotateTransform3D>
  </pmg:Cylinder.Transform>
</pmg:Cylinder>

多圓柱體組裝椅子 (SteelChair)

  • 10 個 Cylinder 精確對齊 Point1/Point2 端點,自動貼合無縫隙。
  • Radius1/Radius2 獨立控制粗細,實現椅腿、椅背、扶手不同粗細。
  • 滾動條控制攝像機旋轉,全方位檢視。

進階擴展:球體、管狀體、任意樣條管道

同樣模式衍生 Sphere、Tube、Pipe:

  • Sphere:參數 Center、Radius、PhiDiv/ThetaDiv,極座標生成。
  • Tube:沿 3D 路徑 (Point3DCollection) 掃掠圓形剖面,需 Frenet 框架計算法向/切向。
  • 統一基類 ModelVisualBase 確保依賴屬性、材質、轉換行為一致。

總結:WPF 3D 幾何體建模最佳實踐

  1. 理解三角形本質:Positions + TriangleIndices 是核心,TextureCoordinates/Normals 服務材質與光照。
  2. 算法生成而非手寫:曲面、參數化物體必須代碼生成。
  3. 繼承 ModelVisual3D:唯一可實例化、可 XAML 直接使用、支援依賴屬性/綁定/動畫的 3D 視覺基類。
  4. 依賴屬性驅動重建:參數變更觸發 RegenerateMesh,重用集合避免 GC 壓力。
  5. 接縫與材質映射策略:根據刷類型選擇映射算法,ImageBrush 避免頂底面接縫,DrawingBrush 環繞無縫。
  6. 參數化設計:Point1/Point2 + Radius1/Radius2 比「單位幾何體+轉換」更直觀、更易動畫控制端點位置。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved