PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : WPF3D: Bogen zeichnen


Elemental
2012-02-13, 13:57:38
Hallo zusammen,
ich versuche gerade mit WPF3D einen Bogen zwischen zwei Punkten zu zeichnen.

Das einzige Beispiel, was ich dazu gefunden, welches halbwegs passt,
ist das Zeichnen von Grosskreisbögen auf einer Kugel:
http://www.charlespetzold.com/blog/2010/06/Great-Circle-Arcs-on-the-Sphere.html

Allerdings krieg ich es nicht gebacken seinen Code so umzubauen,
dass einfach ein Bogen zwischen den beiden Punkten gemalt wird, der sich in positiver (oder schaltbar negativer) Z-Richtung wölbt.

Hat jemand schonmal sowas gemacht?


mfG
Elemental

Elemental
2012-02-13, 16:23:24
Versteht jemand die GenerateArc() Methode von Herrn Petzold?


MeshGeometry3D GenerateArc(Point3D center, double radius, double thickness, double latitude1, double longitude1, double latitude2, double longitude2, int slices)
{
Point3DCollection points = new Point3DCollection();
Point3D pt1 = GeographicToCartesian(latitude1, longitude1, radius);
Point3D pt2 = GeographicToCartesian(latitude2, longitude2, radius);

for (int slice = 0; slice <= slices; slice++)
{
Vector3D pt = (slice * (Vector3D)pt1 + (slices - slice) * (Vector3D)pt2) / slices;
pt.Normalize();

points.Add((Point3D)(radius * pt));
}

MeshGeometry3D mesh = new MeshGeometry3D();
Vector3D arcDirection = new Vector3D();

for (int slice = 0; slice <= slices; slice++)
{
if (slice < slices)
arcDirection = points[slice + 1] - points[slice];

Vector3D perp = Vector3D.CrossProduct(arcDirection, (Vector3D)points[slice]);
perp.Normalize();

Vector3D normal = (Vector3D)points[slice] - thickness / 2 * perp;
mesh.Normals.Add(normal);
mesh.Positions.Add(center + normal);

normal = (Vector3D)points[slice] + thickness / 2 * perp;
mesh.Normals.Add(normal);
mesh.Positions.Add(center + normal);
}

for (int slice = 0; slice < slices; slice++)
{
mesh.TriangleIndices.Add(2 * slice + 0);
mesh.TriangleIndices.Add(2 * slice + 1);
mesh.TriangleIndices.Add(2 * slice + 2);

mesh.TriangleIndices.Add(2 * slice + 2);
mesh.TriangleIndices.Add(2 * slice + 1);
mesh.TriangleIndices.Add(2 * slice + 3);
}

return mesh;
}

Point3D GeographicToCartesian(double latitude, double longitude, double radius)
{
return SphericalToCartesian(Math.PI * latitude / 180, Math.PI * (180 - longitude) / 180, radius);
}

Point3D SphericalToCartesian(double phi, double theta, double radius)
{
double y = radius * Math.Sin(phi);
double scale = -radius * Math.Cos(phi);
double x = scale * Math.Sin(theta);
double z = scale * Math.Cos(theta);

return new Point3D(x, y, z);
}

Elemental
2012-02-23, 15:09:22
Irgendwie schon komisch, dass es im ganzen Internet keine Beispile für sowas gibt :rolleyes:

Aber dank einem Beispiel aus Petzolds WPF3D Buch hab ichs jetzt auch hinbekommen.


MeshGeometry3D GenerateArc(double Radius, double TubeRadius)
{
MeshGeometry3D mesh = new MeshGeometry3D();
int Stacks = 32;
int Slices = 18;

// Fill the vertices, normals, and textures collections.
for (int stack = 0; stack <= Stacks; stack++)
{
double phi = stack * Math.PI / Stacks;

double zCenter = Radius * Math.Sin(phi);
double yCenter = Radius * Math.Cos(phi);
Point3D pointCenter = new Point3D(0, yCenter, zCenter);

for (int slice = Slices; slice >= 0; slice--)
{
double theta = slice * 2 * Math.PI / Slices + Math.PI;
double z = (Radius + TubeRadius * Math.Cos(theta)) * Math.Sin(phi);
double y = (Radius + TubeRadius * Math.Cos(theta)) * Math.Cos(phi);
double x = -TubeRadius * Math.Sin(theta);
Point3D point = new Point3D(x, y, z);

mesh.Positions.Add(point);
mesh.Normals.Add(point - pointCenter);
mesh.TextureCoordinates.Add(new Point((double)slice / Slices,
(double)stack / Stacks));
}
}

// Fill the indices collection.
for (int stack = 0; stack < Stacks; stack++)
{
for (int slice = 0; slice < Slices; slice++)
{
mesh.TriangleIndices.Add((stack + 0) * (Slices + 1) + slice);
mesh.TriangleIndices.Add((stack + 1) * (Slices + 1) + slice);
mesh.TriangleIndices.Add((stack + 0) * (Slices + 1) + slice + 1);

mesh.TriangleIndices.Add((stack + 0) * (Slices + 1) + slice + 1);
mesh.TriangleIndices.Add((stack + 1) * (Slices + 1) + slice);
mesh.TriangleIndices.Add((stack + 1) * (Slices + 1) + slice + 1);
}
}

return mesh;
}