VectorVisualizer Version 1.2
by Kevin Seib and Pascal Glaeser
Loading...
Searching...
No Matches
VektorPlotForm3D.cs
Go to the documentation of this file.
1using System;
2using System.Drawing;
3using System.Windows.Forms;
4using System.Windows.Forms.Integration;
5using System.Windows.Media.Media3D;
6using HelixToolkit.Wpf;
7
9{
10 public partial class VektorPlotForm3D : Form
11 {
13 double[][,,] vectorField, // [0]=Fx, [1]=Fy, [2]=Fz
14 double xMin, double xMax,
15 double yMin, double yMax,
16 double zMin, double zMax,
17 double[,,]? divergence = null,
18 double[][,,]? curl = null, // [0]=CurlX, [1]=CurlY, [2]=CurlZ
19 double? px = null, double? py = null, double? pz = null)
20 {
21 InitializeComponent();
22
23 this.Text = "3D-Vektorfeld Visualisierung";
24 this.Size = new Size(900, 700);
25 this.BackColor = Color.FromArgb(33, 33, 33);
26
27 // 3D-Host
28 var host = new ElementHost { Dock = DockStyle.Fill };
29 var viewPort = new HelixViewport3D
30 {
31 Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(25, 25, 25)), // fast schwarz
32 ZoomExtentsWhenLoaded = true
33 };
34 host.Child = viewPort;
35 // === Orientierungsgitter hinzufügen ===
36 var fillColor = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(160, 160, 160));
37 // XY-Ebene (Boden)
38 var gridXY = new GridLinesVisual3D
39 {
40 Width = 10,
41 Length = 10,
42 MinorDistance = 1,
43 Thickness = 0.04,
44 Center = new Point3D(0, 0, 0),
45 Normal = new Vector3D(0, 0, 1),
46 Fill = fillColor
47 };
48 viewPort.Children.Add(gridXY);
49
50 // XZ-Ebene (Rückwand)
51 var gridXZ = new GridLinesVisual3D
52 {
53 Width = 10,
54 Length = 10,
55 MinorDistance = 1,
56 Thickness = 0.04,
57 Center = new Point3D(0, 0, 0),
58 Normal = new Vector3D(0, 1, 0),
59 Fill = fillColor
60 };
61 viewPort.Children.Add(gridXZ);
62
63 // YZ-Ebene (Seitenwand)
64 var gridYZ = new GridLinesVisual3D
65 {
66 Width = 10,
67 Length = 10,
68 MinorDistance = 1,
69 Thickness = 0.04,
70 Center = new Point3D(0, 0, 0),
71 Normal = new Vector3D(1, 0, 0),
72 Fill = fillColor
73 };
74 viewPort.Children.Add(gridYZ);
75 // X-Achse-Beschriftung
76 var labelX = new BillboardTextVisual3D
77 {
78 Text = "x",
79 Position = new Point3D(5.5, 0, 0),
80 Foreground = System.Windows.Media.Brushes.White,
81 Background = System.Windows.Media.Brushes.Transparent
82 };
83 viewPort.Children.Add(labelX);
84
85 // Y-Achse-Beschriftung
86 var labelY = new BillboardTextVisual3D
87 {
88 Text = "y",
89 Position = new Point3D(0, 5.5, 0),
90 Foreground = System.Windows.Media.Brushes.White,
91 Background = System.Windows.Media.Brushes.Transparent
92 };
93 viewPort.Children.Add(labelY);
94
95 // Z-Achse-Beschriftung
96 var labelZ = new BillboardTextVisual3D
97 {
98 Text = "z",
99 Position = new Point3D(0, 0, 5.5),
100 Foreground = System.Windows.Media.Brushes.White,
101 Background = System.Windows.Media.Brushes.Transparent
102 };
103 viewPort.Children.Add(labelZ);
104
105 viewPort.Children.Add(new DefaultLights());
106
107 int sizeX = vectorField[0].GetLength(0);
108 int sizeY = vectorField[0].GetLength(1);
109 int sizeZ = vectorField[0].GetLength(2);
110
111 double stepX = (xMax - xMin) / sizeX;
112 double stepY = (yMax - yMin) / sizeY;
113 double stepZ = (zMax - zMin) / sizeZ;
114
115 // Pfeile zeichnen
116 for (int i = 0; i < sizeX; i++)
117 {
118 for (int j = 0; j < sizeY; j++)
119 {
120 for (int k = 0; k < sizeZ; k++)
121 {
122 double x = xMin + i * stepX;
123 double y = yMin + j * stepY;
124 double z = zMin + k * stepZ;
125
126 double fx = vectorField[0][i, j, k];
127 double fy = vectorField[1][i, j, k];
128 double fz = vectorField[2][i, j, k];
129
130 if (double.IsFinite(fx) && double.IsFinite(fy) && double.IsFinite(fz))
131 {
132 var arrow = new ArrowVisual3D
133 {
134 Point1 = new Point3D(x, y, z),
135 Point2 = new Point3D(x + fx * 0.2, y + fy * 0.2, z + fz * 0.2),
136 Diameter = 0.05,
137 Fill = System.Windows.Media.Brushes.White
138 };
139 viewPort.Children.Add(arrow);
140 }
141 }
142 }
143 }
144
145 // Info-Panel links
146 Panel? leftPanel = null;
147
148 if ((divergence != null || curl != null) && px.HasValue && py.HasValue && pz.HasValue)
149 {
150 string infoText = "";
151
152 int i = (int)((px.Value - xMin) / (xMax - xMin) * sizeX);
153 int j = (int)((py.Value - yMin) / (yMax - yMin) * sizeY);
154 int k = (int)((pz.Value - zMin) / (zMax - zMin) * sizeZ);
155
156 i = Math.Clamp(i, 0, sizeX - 1);
157 j = Math.Clamp(j, 0, sizeY - 1);
158 k = Math.Clamp(k, 0, sizeZ - 1);
159
160 if (divergence != null)
161 {
162 double divVal = divergence[i, j, k];
163 infoText += $"Divergenz: ∇·F(x, y, z):\n {Math.Round(divVal, 4)}\n\n";
164 }
165
166 if (curl != null)
167 {
168 double cx = curl[0][i, j, k];
169 double cy = curl[1][i, j, k];
170 double cz = curl[2][i, j, k];
171 infoText += $"Rotation:∇×F:\n ({Math.Round(cx, 4)}, {Math.Round(cy, 4)}, {Math.Round(cz, 4)})";
172 }
173
174 var label = new Label
175 {
176 Text = infoText,
177 ForeColor = Color.White,
178 AutoSize = true,
179 Location = new Point(10, 20),
180 BackColor = Color.FromArgb(33, 33, 33)
181 };
182
183 leftPanel = new Panel
184 {
185 Width = 220,
186 Dock = DockStyle.Fill,
187 BackColor = Color.FromArgb(33, 33, 33)
188 };
189 leftPanel.Controls.Add(label);
190 }
191
192
193 if ((divergence != null || curl != null) && px.HasValue && py.HasValue && pz.HasValue)
194 {
195 string infoText = "";
196
197 int i = (int)((px.Value - xMin) / (xMax - xMin) * sizeX);
198 int j = (int)((py.Value - yMin) / (yMax - yMin) * sizeY);
199 int k = (int)((pz.Value - zMin) / (zMax - zMin) * sizeZ);
200
201 i = Math.Clamp(i, 0, sizeX - 1);
202 j = Math.Clamp(j, 0, sizeY - 1);
203 k = Math.Clamp(k, 0, sizeZ - 1);
204
205 if (divergence != null)
206 {
207 double divVal = divergence[i, j, k];
208 infoText += $"Divergenz:\n∇·F(x, y, z) = {Math.Round(divVal, 4)}\n\n";
209 }
210
211 if (curl != null)
212 {
213 double cx = curl[0][i, j, k];
214 double cy = curl[1][i, j, k];
215 double cz = curl[2][i, j, k];
216 infoText += $"Rotation:\n∇×F = ({Math.Round(cx, 4)}, {Math.Round(cy, 4)}, {Math.Round(cz, 4)})";
217 }
218
219 var label = new Label
220 {
221 Text = infoText,
222 ForeColor = Color.White,
223 AutoSize = true,
224 Location = new Point(10, 20),
225 BackColor = Color.FromArgb(33, 33, 33)
226 };
227 leftPanel.Controls.Add(label);
228 }
229
230 // Layout
231 var layout = new TableLayoutPanel
232 {
233 Dock = DockStyle.Fill,
234 ColumnCount = 2,
235 RowCount = 1
236 };
237
238 if (leftPanel != null)
239 {
240 layout.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 220));
241 layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
242 layout.Controls.Add(leftPanel, 0, 0);
243 layout.Controls.Add(host, 1, 0);
244 }
245 else
246 {
247 layout.ColumnCount = 1;
248 layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
249 layout.Controls.Add(host, 0, 0);
250 }
251
252 this.Controls.Add(layout);
253
254 }
255 }
256}
VektorPlotForm3D(double[][,,] vectorField, double xMin, double xMax, double yMin, double yMax, double zMin, double zMax, double[,,]? divergence=null, double[][,,]? curl=null, double? px=null, double? py=null, double? pz=null)