|
Surfaces
Übersicht
1. Allgemeines
2. Custom Surface
3. Surface klassen
4. Surfaces und Texturen
5. Bounded Surface
1. Allgemeines
Surfaces sind Abbildungen von R x R |--> R X R x R,
Drawing 3d verwendet als Prameterraum stets [0,1], womit Surfaces
beschränkt sind auf Abbildungen
f: [0, 1] X [0, 1] |--> R X R X R.
Parameterraum (Parameter u und v ) |
Bildraumraum ( Koordinaten x, y, z) |
|
|
Der Grundtyp für alle Surfaces ist die abstrakte Klasse Drawing3d.Surfaces.Surface.
Drei Methoden von Surface sind sehr wichig:
- Value : lieftert für ein Parameterpaar u und v einen dreidimenstionalen Punkt
der Surface.
- uDerivation: liefert die partielle Ableitung nach u.
- vDeriavation : lefert die partielle Ableitung nach v.
Die partiellen Ableitungen sind nötig, da daraus der Normalvektor gebildet wird, der vom
Licht verwendet wird.
2. Custom surface
Der Typ CustomSurface hat die drei Events
- OnGetValue
- OnGetUDerivation
- OnGetVDerivation
Diese drei Events werden wir verwenden, um ein Paraboliod
f : R X R |--> R
f(u,v) =(x² + y²)/2,
als Surface darzustellen.
Wir definieren zuerst ein Object MySurface vom Typ CustomSurface:
CustomSurface MySurface = new CustomSurface();
und ordnen ihm die Events zu in der Loadmethode zu.
Die Loadmethode sieht nun so aus:
private void Form1_Load(object sender, EventArgs e)
{ Device.WinControl = this;
Device.OnPaint += new EventHandler(Device_OnPaint);
Device.Navigate = NavigateKind.ZoomRotateTrans;
MySurface.OnGetValue += new RealFunction2d3d(MySurface_OnGetValue);
Device.BackColor = Color.White;
}
In MySurface_OnGetValue definieren wir die Funktion:
xyz MySurface_OnGetValue(object sender, double u, double v)
{
u = (u - 0.5)*5 ; // map 0,1 --> -2.5,2.5
v = (v - 0.5)*5 ; // map 0,1 --> -2.5,2.5
return new xyz(u,v,(u * u + v * v)/2);
}
Nun haben wir nur noch den entsprechenden Aufruf in der Paintmethode zu machen:
public override void OnPaint()
{
Lighting = false; // Licht wird ausgeschltet, damit wir ein reine schwarze Linien erhalten.
Emision = Color.Black; // Schwrzer Zeichen stift
PolygonMode = PolygonMode.Line; // im Linemodus
MySurface.Paint(this); // Draw it
}
Und erhalten - nach etwas navigieren - das Ergebnis im Drahtgittermodell:
Versuchen wir nun das Paraboloid im Fillmodus zu zeichnen.
Dazu muüssen wir die partiellen Ableitung definieren.
Zuerst aktivieren wir OnGetUDerivation und OnGetVDerivation in der
Loadmethode:
private void Form1_Load(object sender, EventArgs e)
{
...
MySurface.OnGetUDerivation += new RealFunction2d3d(MySurface_OnGetUDerivation);
MySurface.OnGetVDerivation += new RealFunction2d3d(MySurface_OnGetVDerivation);
}
und definieren die beiden Methoden:
xyz MySurface_OnGetVDerivation(object sender, double u, double v)
{
u = (u - 0.5)*5 ; // map 0,1 --> -2.5,2.5
v = (v - 0.5)*5 ; // map 0,1 --> -2.5,2.5
return new xyz(0,1,v);
}
xyz MySurface_OnGetUDerivation(object sender, double u, double v)
{
u = (u - 0.5) * 5; // map 0,1 --> -2.5,2.5
v = (v - 0.5) * 5; // map 0,1 --> -2.5,2.5
return new xyz(1, 0, u);
}
Die Paintmethode müssen wir noch adaptieren und sieht nun einfach so aus
public override void OnPaint()
{
MySurface.Paint(this);
}
Der Sourcecode
Versuch es mal mit Device.Culling = true; Dann siehst du, dass nur der äußere Teil des Paraboloids gezeichnet wird.
Und so siehts aus
3. Surface Klassen
In Drawing 3d sind folgende Surfacetpyen definiert:
- CustomSurface
- Cone
- Cylinder
- PlaneSurface
- Sphere
- Torus
- BezierSurface (Bezier 3D)
- BSplineSurface (BSpline 3D)
- NurbsSurface (Nurbs 3D)
- ArrayExtruder (Flächen die im Grundriss Polygone sind)
- CurveExtruder (Flächen die im Grundriss Kurven sind)
Surface | Programmierung | | Ergebnis |
Cone |
Cone MyCone = new Cone();
MyCone.HalfAngle = System.Math.PI / 6;
MyCone.Radius = 3;
MyCone.Height = MyCone.Radius / System.Math.Tan(MyCone.HalfAngle);
...
MyCone.Paint(this);
| |
|
Cylinder |
Cylinder MyCylinder = new Cylinder();
MyCylinder.Radius = 2;
MyCylinder.Height = 3;
...
MyCylinder.Paint(this);
|
|
|
Plane |
PlaneSurface MyPlaneSurface = new PlaneSurface();
MyPlaneSurface.Width = 5;
MyPlaneSurface.Height = 4;
...
MyPlaneSurface.Paint(this);;
| |
|
Sphere |
Sphere MySphere = new Sphere();
MySphere.Radius = 2;
...
MySphere.Paint(this);;
| |
|
Torus |
Torus MyTorus = new Torus();
MyTorus.InnerRadius = 1;
MyTorus.OuterRadius = 3;
...
MyTorus.Paint(this);
| |
|
BezierSurface |
BezierSurface MyBezierSurface =
new BezierSurface();
MyBezierSurface.ControlPoints =
new xyz[,]
{ {new xyz(-2,-4,1),
new xyz(-2,-2,1),
new xyz(-2,0,-1),
new xyz(-2,2,1)},
{new xyz(0,-4,1),
new xyz(0,-2,3),
new xyz(0,0,-3),
new xyz(0,2,1)},
{new xyz(2,-4,-1),
new xyz(2,-2,3),
new xyz(2,0,-3),
new xyz(2,2,-1)},
{new xyz(4,-4,1),
new xyz(4,-2,1),
new xyz(4,0,-1),
new xyz(4,2,1)}};
| |
|
BSplinesurface |
BSplineSurface MyBsplineSurface = new BSplineSurface();
MyBsplineSurface.UDegree = 2;
MyBsplineSurface.VDegree = 2;
MyBsplineSurface.ControlPoints = new xyz[,]
{
{new xyz(-4,-4,1),
new xyz(-4,-2,2),
new xyz(-4,0,1),
new xyz(-4,2,1)},
{new xyz(-2,-4,1),
new xyz(-2,-2,4),
new xyz(-2,0,3),
new xyz(-2,2,2)},
{new xyz(0,-4,2),
new xyz(0,-2,3),
new xyz(0,0,2),
new xyz(0,2,3)},
{new xyz(2,-4,1),
new xyz(2,-2,2),
new xyz(2,0,1),
new xyz(2,2,1)},
{new xyz(4,-4,1),
new xyz(4,-2,2),
new xyz(4,0,1),
new xyz(4,2,1)}
};
MyBsplineSurface.UKnots = Utils.StandardKnots(MyBsplineSurface.ControlPoints.GetLength(0), MyBsplineSurface.UDegree);
MyBsplineSurface.VKnots = Utils.StandardKnots(MyBsplineSurface.ControlPoints.GetLength(1), MyBsplineSurface.VDegree);
...
MyBsplineSurface.Paint(this);
| |
|
Nurbssurface |
NurbsSurface MyNurbsSurface = new NurbsSurface();
MyNurbsSurface.ControlPoints = MyBsplineSurface.ControlPoints;
// The same Controlpoints as MyBsplineSurface
// but weights !!!
...
MyNurbsSurface.UDegree = 2;
MyNurbsSurface.VDegree = 2;
MyNurbsSurface.Weights =
new double[,]
{ {1,1,1, 1},
{1,0.1,0.1,1},
{1,0.1,0.0,1},
{1,0.1,0.0,1},
{1,1,1,1} };
MyNurbsSurface.Paint(this);
| |
|
ArrayExtruder |
ArrayExtruder MyArrayExtruder = new ArrayExtruder();
xyArray Points = new xyArray(5);
Points[0] = new xy(0,0);
Points[1] = new xy(1,1);
Points[2] = new xy(2,-1);
Points[3] = new xy(3,1);
Points[4] = new xy(4,-1);
MyArrayExtruder.Array = Points;
MyArrayExtruder.Height = 3;
...
MyArrayExtruder.Paint(this);
| |
|
CurveExtruder |
CurveExtruder MyCurveExtruder =
new CurveExtruder();
...
MyCurveExtruder.Curve =
new Bezier(new xy(0, 0),
new xy(1, -1),
new xy(2, -1),
new xy(3, 0));
MyCurveExtruder.Height = 3;
...
MyCurveExtruder.Paint(this);
| |
|
4. Surfaces und Texturen
Texturen werden zuerst in den Paramterraum gemappt und dann auf die Oberfäche.
Somit füllt eine Textur mit Worldwidth = 1 und WorldHeight = 1
ein Surface aus.
Die Anwendung einer Textur auf ein Surface ist die selbe wie bei jedem Device-drawbefehl;
override override void OnPaint()
{
texture = MyTexture;
MySurface.Paint(this);
texture = null;
}
z.B.:
Barack Obama als Textur auf MyNurbsSurface:
5. Bounded Surfaces
Nehmen wir einen Kurvenzug curves, der im Parameterraum einen Bereich
umrandet. Die Abbildung von curves
umschließt ein Gebiet auf dem Surface, das man bounded surface nennt.
Darstellung von bounded surfaces mit Drawing 3d:
Der Typ Surface hat eine Egenschaft BoundedCurves. Weist man ihr curves
zu, so wird bei einem Aufruf von Paint nur
der innere Teil vom Surface gezeichnet.
Um das Ganze zu verstehen, machst du am besten ein Beispiel gemäß Hello World
und kopierst den folgenden Programmcode hinein:
Und das sieht so aus:
Bemerkung: Die Linien dienen nur zur Veranschaulichung des Trägersurfaces. Die goldene Fläche ist das bounded surface.
|
|