![]() |
[Mathematik] Suche Vektoren für Körper
Hallo zusammen.
Ich muss etwas mit räumlichen Körpern programmieren. Das eigentliche Problem ist soweit gelöst, aber ich bin dabei über ein mathematisches Problem gestoßen, wo ich nicht weiterkomme und auch Tante Google nichts brauchbares ausspuckt. Ich hoffe, hier finden sich einige mit passenden Mathekenntnissen. Es geht um folgendes: Wie komme ich bei räumlichen Körpern (Pyramide, 8-Flächenkörper (Oktaeder), 10-Flächenkörper (??), 12-Flächenkörper (Dodekaeder), 20-Flächenkörper (Ikosaeder)) auf die Vektoren, die vom Körpermittelpunkt jeweils in Richtung der Mittelpunkte der Flächen zeigen? Beispiel: Ich suche bei Ikosaeder nach genau 20 Vektoren, von denen jeder die Richtung beschreibt, vom Körpermittelpunkt zum Mittelpunkt jeweils einer der Flächen. |
AW: [Mathematik] Suche Vektoren für Körper
Hast du denn die Punkte zu einer Fläche gegeben? Falls ja, dann kannst du einfach koordinatenweise den „Mittelwert“ berechnen (m.x = (p_1.x + p_2.x + ... + p_n.x)/n; m.y = (p_1.y + p_2.y + ... + p_n.y)/n), um den Mittelpunkt der Fläche zu bekommen und dann die Differenz zum Mittelpunkt des Körpers berechnen. Sorry falls das am Thema vorbeigeht...
|
AW: [Mathematik] Suche Vektoren für Körper
Nein, ich weiß nur was es für ein Körper ist, wo der Mittelpunkte ist und theoretisch die Skalierung
|
AW: [Mathematik] Suche Vektoren für Körper
Vielleicht hilft dir
![]() |
AW: [Mathematik] Suche Vektoren für Körper
Danke für den Link. Da steht schon mal eine Menge drin, aber das einzige ähnliche sind die Vektoren für die Vertices. Evtl. kann ich mir daraus was stricken und von den Ecken jeweils auf die Flächen schließen.
Ich wäre trotzdem interessiert, wenn jemand für sowas Formeln oder Lösungen zur Hand hat :thumb: |
AW: [Mathematik] Suche Vektoren für Körper
Willst du den Richtungsvektor jeweils vom Ursprung zu den einzelnen Flächen des Körpers ermittelnt oder den Vektor mit korrektem Abstand (also normaler Vektor vom Ursprung bis zum Mittelpunkt einer Fläche)?
Fürs erstere gibts bestimmt schon ne Lösung.. ich würd mir dann gedanken darüber machen, aber erst mal warte ich auf deine Antwort. |
AW: [Mathematik] Suche Vektoren für Körper
Die Länge des Vektors ist für mich erstmal irrelevant, mir reicht also lediglich die Richtung. Ich wollte mit einem Vektor der Länge 1 arbeiten, den kann ich bei Bedarf dann entsprechend skalieren, falls nötig
|
AW: [Mathematik] Suche Vektoren für Körper
Ok, mein erster Gedanke dazu ist/war:
mit der Kugelformel rumspielen und die einzelnen Eckpunkte ermitteln (diese sind dann auch die gewollten Richtungsvektoren) Bin mir aber noch nicht sicher, ob das so klappen würde. Weiß nicht, ob man damit wirklich all diese Körper darstellen lassen kann. [Edit] Ein anderer sollte vorher das klarstellen, bevor du das einsetzt [/Edit] ![]() ![]() [Edit] Ach, man kann die Formel nicht lesen. x = sin(w1) * cos(w2) y = sin(w1) * sin(w2) z = cos(w1) [/Edit] Du müsstest hier bei die Kugel horizontal und vertikal jeweils in Slices (bei der Skizze mit Stacks und Slices versehen) unterteilen (dementsprechende Winkel verwenden, sofern das noch verständlich ist) ![]() ![]() |
AW: [Mathematik] Suche Vektoren für Körper
Also ich fürchte, das musst du "per Hand" einprogrammieren als Konstante.
Bei einem Ikosaeder (als Bsp.) habe ich die Formel für die Eckpunkte gefunden ( ![]() Daraus kannst du dann die Vektoren zu den Flächenmittelpunkten errechnen. (Der Mittelwert aus Eckpunkten einer Fläche ist der Vektor zum Flächenmittelpunkt) Eine einfache Lösung wie "Dodekaeder" rein, Koordinaten raus wird's wohl nicht geben. Das wird vermutlich auf große, konstante Arrays im Code hinauslaufen ;-) (Vielleicht lässt sich da noch was sparen, weil die Teile alle zwei Symmetrieebenen oder so haben, aber ob's das dann bringt weiß ich nicht) |
AW: [Mathematik] Suche Vektoren für Körper
Zitat:
Und ich würde vom Grundkörper ausgehen, d.h. ohne Rotationen, Verschiebungen oder Skalierungen. Damit dürfte die Lösung meines Erachtens eindeutig bleiben, wenn ich von normierten Vektoren ausgehe. |
AW: [Mathematik] Suche Vektoren für Körper
Zuerst ermittelst du dir mit einer Polyeder-Routine den Mittelpunkt M des räumlichen Körpers. Danach für jede Begrenzungsfläche den Mittelpunkt S2(i) am ebenen Ersatzsystem (N-Eck). Da der Schwerpunkt der Flächen in den jeweiligen Ebenen liegt, sollte die Transformation in die wirkliche räumliche Lage S3(i) nicht so schwierig sein. Deine Vektoren sind dann M, S3(i).
// Edit: Muss suchen.. Wenn ich was finde, poste ich was. |
AW: [Mathematik] Suche Vektoren für Körper
Ich hab' bezüglich der Transformation nichts gefunden, nur eine alte Studienarbeit (Polyeder). Interessiert dich das?
|
AW: [Mathematik] Suche Vektoren für Körper
Da ich in meinen Berechnungen die Tranformation, Rotation und Skalierung ignorieren kann .... JA, Interesse ist da
|
AW: [Mathematik] Suche Vektoren für Körper
Exklusiv für die DP von DOS Basic nach Delphi gestern umgeschrieben. :)
Nicht groß getestet, sollte aber funktionieren.
Delphi-Quellcode:
unit uPolyeder; // (c) 28.04.1985, 2.05.2012 Thomas Abel, Edgar Zocher
interface uses SysUtils, Dialogs; const MaxPoints = 500; // NEck (Sprich N-Eck), Polyeder MaxBegrenzungsEbenen = 50; // Polyeder MaxPointsJeBegrenzungsEbene = 20; // Polyeder type TD2Point = record X, Y: double; end; TD2Points = array [0..MaxPoints] of TD2Point; // Siehe auch CloseNEck TNEck = class private FCount: integer; // Anzahl der Punkte FPoints: TD2Points; function Determinante(const I: integer): double; procedure CloseNEck; function GetPoint(Index: integer): TD2Point; procedure SetPoint(const Index: integer; const X, Y: double); procedure PutPoint(Index: integer; const Value: TD2Point); public property Points[Index: integer]: TD2Point read GetPoint write PutPoint; property Count: integer read FCount; procedure Clear; procedure AddPoint(const X, Y: double); overload; procedure AddPoint(const Index: integer); overload; procedure DelPoint(const Index: integer); procedure InsPoint(const Index: integer; const X, Y: double); function Schwerpunkt: TD2Point; function Flaeche: double; constructor Create; end; TD3Point = record X, Y, Z: double; Exist: boolean; end; TD3Points = array [0..MaxPoints - 1] of TD3Point; TBegrenzungsEbene = record Count: integer; PointNumbers: array [0..MaxPointsJeBegrenzungsEbene - 1] of integer; procedure AddPointNumber(const Value: integer); procedure DelPointNumber(const Index: integer); procedure InsPointNumber(const Index, Value: integer); procedure Clear; end; TBegrenzungsEbenen = array [0..MaxBegrenzungsEbenen - 1] of TBegrenzungsEbene; TPolyederPoints = array [1..3, 1..3] of double; TPolyeder = class private FN: integer; // Anzahl der BegrenzungsEbenen FCount: integer; // Anzahl der Punkte FPoints: TD3Points; FEbenen: TBegrenzungsEbenen; function Determinante(const U, V, W: integer): double; function PolyederPoints(const U, V, W: integer): TPolyederPoints; function GetBegrenzungsEbene(Index: integer): TBegrenzungsEbene; function GetPoint(Index: integer): TD3Point; procedure SetPoint(const Index: integer; const X, Y, Z: double; const Exist: boolean); procedure PutPoint(Index: integer; const Value: TD3Point); procedure PutBegrenzungsEbene(Index: integer; const Value: TBegrenzungsEbene); public property Points[Index: integer]: TD3Point read GetPoint write PutPoint; property Ebenen[Index: integer]: TBegrenzungsEbene read GetBegrenzungsEbene write PutBegrenzungsEbene; property Count: integer read FCount; property N: integer read FN; procedure Clear; procedure AddPoint(const X, Y, Z: double); procedure DelPoint(const Index: integer); procedure InsPoint(const Index: integer; const X, Y, Z: double); procedure AddBegrenzungsEbene(const PointNumbers: array of integer); procedure DelBegrenzungsEbene(const Index: integer); procedure InsBegrenzungsEbene(const Index: integer; const PointNumbers: array of integer); function Schwerpunkt: TD3Point; function Volumen: double; constructor Create; end; implementation { NEck } function TNEck.GetPoint(Index: integer): TD2Point; begin Result:= FPoints[Index]; end; procedure TNEck.PutPoint(Index: integer; const Value: TD2Point); begin FPoints[Index]:= Value; end; procedure TNEck.SetPoint(const Index: integer; const X, Y: double); begin FPoints[Index].X:= X; FPoints[Index].Y:= Y; end; procedure TNEck.AddPoint(const X, Y: double); begin Inc(FCount); SetPoint(FCount - 1, X, Y); end; procedure TNEck.AddPoint(const Index: integer); begin AddPoint(FPoints[Index].X, FPoints[Index].Y); end; procedure TNEck.DelPoint(const Index: integer); var I: integer; begin for I:= Index to FCount - 2 do FPoints[I]:= FPoints[I + 1]; Dec(FCount); end; procedure TNEck.InsPoint(const Index: integer; const X, Y: double); var I: integer; begin Inc(FCount); for I:= FCount - 1 downto Index + 1 do FPoints[I]:= FPoints[I - 1]; SetPoint(Index, X, Y) end; function TNEck.Determinante(const I: integer): double; begin Result:= FPoints[I].X * FPoints[I + 1].Y - FPoints[I].Y * FPoints[I + 1].X; end; procedure TNEck.CloseNEck; begin FPoints[FCount].X:= FPoints[0].X; FPoints[FCount].Y:= FPoints[0].Y; end; function TNEck.Flaeche: double; var I: integer; begin Result:= 0; CloseNEck; for I:= 0 to FCount - 1 do Result:= Result + Determinante(I) / 2; end; function TNEck.Schwerpunkt: TD2Point; var I: integer; begin Result.X:= 0; Result.Y:= 0; CloseNEck; for I:= 0 to FCount - 1 do begin Result.X:= Result.X + (FPoints[I].X + FPoints[I + 1].X) * Determinante(I) / 6; Result.Y:= Result.Y + (FPoints[I].Y + FPoints[I + 1].Y) * Determinante(I) / 6; end; Result.X:= Result.X / Flaeche; Result.Y:= Result.Y / Flaeche; end; procedure TNEck.Clear; begin FCount:= 0; end; constructor TNEck.Create; begin inherited Create; Clear; end; { TBegrenzungsEbene } procedure TBegrenzungsEbene.Clear; begin Count:= 0; end; procedure TBegrenzungsEbene.AddPointNumber(const Value: integer); begin Inc(Count); PointNumbers[Count - 1]:= Value; end; procedure TBegrenzungsEbene.DelPointNumber(const Index: integer); var I: integer; begin for I:= Index to Count - 2 do PointNumbers[I]:= PointNumbers[I + 1]; Dec(Count); end; procedure TBegrenzungsEbene.InsPointNumber(const Index, Value: integer); var I: integer; begin Inc(Count); for I:= Count - 1 downto Index + 1 do PointNumbers[I]:= PointNumbers[I - 1]; PointNumbers[Index]:= Value; end; { TPolyeder } function TPolyeder.GetPoint(Index: integer): TD3Point; begin Result:= FPoints[Index]; end; procedure TPolyeder.PutPoint(Index: integer; const Value: TD3Point); begin FPoints[Index]:= Value; end; procedure TPolyeder.SetPoint(const Index: integer; const X, Y, Z: double; const Exist: boolean); begin FPoints[Index].X:= X; FPoints[Index].Y:= Y; FPoints[Index].Z:= Z; FPoints[Index].Exist:= Exist; end; procedure TPolyeder.AddPoint(const X, Y, Z: double); begin Inc(FCount); SetPoint(FCount - 1, X, Y, Z, true); end; procedure TPolyeder.DelPoint(const Index: integer); var I: integer; begin for I:= Index to FCount - 2 do FPoints[I]:= FPoints[I + 1]; FPoints[FCount - 1].Exist:= false; Dec(FCount); end; procedure TPolyeder.InsPoint(const Index: integer; const X, Y, Z: double); var I: integer; begin Inc(FCount); for I:= FCount - 1 downto Index + 1 do FPoints[I]:= FPoints[I - 1]; SetPoint(Index, X, Y, Z, true); end; function TPolyeder.GetBegrenzungsEbene(Index: integer): TBegrenzungsEbene; begin Result:= FEbenen[Index]; end; procedure TPolyeder.PutBegrenzungsEbene(Index: integer; const Value: TBegrenzungsEbene); begin FEbenen[Index]:= Value; end; procedure TPolyeder.AddBegrenzungsEbene(const PointNumbers: array of integer); var I: integer; begin Inc(FN); for I:= 0 to Length(PointNumbers) - 1 do FEbenen[FN - 1].AddPointNumber(PointNumbers[I]); end; procedure TPolyeder.DelBegrenzungsEbene(const Index: integer); var I: integer; begin for I:= Index to FN - 2 do FEbenen[I]:= FEbenen[I + 1]; Dec(FN); end; procedure TPolyeder.InsBegrenzungsEbene(const Index: integer; const PointNumbers: array of integer); var I: integer; Value: TBegrenzungsEbene; begin Value.Clear; for I:= 0 to Length(PointNumbers) - 1 do Value.AddPointNumber(PointNumbers[I]); Inc(FN); for I:= FN - 1 downto Index + 1 do FEbenen[I]:= FEbenen[I - 1]; FEbenen[Index]:= Value; end; function TPolyeder.PolyederPoints(const U, V, W: integer): TPolyederPoints; begin if not FPoints[U].Exist then raise Exception.Create('Punkt '+IntToStr(U) + ' existiert nicht.'); if not FPoints[V].Exist then raise Exception.Create('Punkt '+IntToStr(V) + ' existiert nicht.'); if not FPoints[W].Exist then raise Exception.Create('Punkt '+IntToStr(W) + ' existiert nicht.'); Result[1, 1]:= FPoints[U].X; Result[2, 1]:= FPoints[U].Y; Result[3, 1]:= FPoints[U].Z; Result[1, 2]:= FPoints[V].X; Result[2, 2]:= FPoints[V].Y; Result[3, 2]:= FPoints[V].Z; Result[1, 3]:= FPoints[W].X; Result[2, 3]:= FPoints[W].Y; Result[3, 3]:= FPoints[W].Z; end; function TPolyeder.Determinante(const U, V, W: integer): double; var P: TPolyederPoints; begin P:= PolyederPoints(U, V, W); Result:= P[1, 1] * (P[2, 2] * P[3, 3] - P[3, 2] * P[2, 3]) - P[2, 1] * (P[1, 2] * P[3, 3] - P[3, 2] * P[1, 3]) + P[3, 1] * (P[1, 2] * P[2, 3] - P[2, 2] * P[1, 3]); end; function TPolyeder.Volumen: double; var I, J, U, V, W: integer; E: TBegrenzungsEbene; begin Result:= 0; for I:= 0 to FN - 1 do begin E:= FEbenen[I]; U:= E.PointNumbers[0]; V:= E.PointNumbers[1]; for J:= 2 to E.Count - 1 do begin W:= E.PointNumbers[J]; Result:= Result + Determinante(U, V, W) / 6; V:= W; end; end; end; function TPolyeder.Schwerpunkt: TD3Point; var I, J, U, V, W, k1, k2: integer; E: TBegrenzungsEbene; M: array [1..3] of double; T: double; P: TPolyederPoints; begin for k1:= 1 to 3 do M[k1]:= 0; for I:= 0 to FN - 1 do begin E:= FEbenen[I]; U:= E.PointNumbers[0]; V:= E.PointNumbers[1]; for J:= 2 to E.Count - 1 do begin W:= E.PointNumbers[J]; P:= PolyederPoints(U, V, W); for k1:= 1 to 3 do begin T:= 0; for k2:= 1 to 3 do T:= T + P[k1, k2]; M[k1]:= M[k1] + Determinante(U, V, W) / 24 * T; end; V:= W; end; end; Result.X:= M[1] / Volumen; Result.Y:= M[2] / Volumen; Result.Z:= M[3] / Volumen; end; procedure TPolyeder.Clear; var I: integer; begin FCount:= 0; FN:= 0; for I:= 0 to MaxBegrenzungsEbenen - 1 do FEbenen[I].Clear; for I:= 0 to MaxPoints - 1 do FPoints[I].Exist:= false; end; constructor TPolyeder.Create; begin inherited Create; Clear; end; end.
Delphi-Quellcode:
unit PolyederUnit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uPolyeder; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var ANEck: TNEck; begin ANEck:= TNEck.Create; try // Vorhandene Flächen mathematisch positiv umfahren ANEck.AddPoint(0, 0); ANEck.AddPoint(10, 0); ANEck.AddPoint(10, 5); ANEck.AddPoint(0, 5); // Nr. 3 // Aussparungen mathematisch negativ umfahren ANEck.AddPoint(1, 4); // Nr. 4 ANEck.AddPoint(9, 4); ANEck.AddPoint(9, 1); ANEck.AddPoint(1, 1); ANEck.AddPoint(4); // Teilfläche schließen ANEck.AddPoint(3); // Aussparung schließen ShowMessage(FloatToStr(ANEck.Flaeche)); ShowMessage(FloatToStr(ANEck.Schwerpunkt.X)); ShowMessage(FloatToStr(ANEck.Schwerpunkt.Y)); finally ANEck.Free; end; end; procedure TForm1.Button2Click(Sender: TObject); var APolyeder: TPolyeder; begin APolyeder:= TPolyeder.Create; try APolyeder.AddPoint(0, 0, 0); APolyeder.AddPoint(10, 0, 0); APolyeder.AddPoint(10, 5, 0); APolyeder.AddPoint(0, 5, 0); APolyeder.AddPoint(10, 5, 20); // Begrenzungsflächen mathematisch positiv umfahren APolyeder.AddBegrenzungsEbene([0, 1, 4]); APolyeder.AddBegrenzungsEbene([1, 2, 4]); APolyeder.AddBegrenzungsEbene([2, 3, 4]); APolyeder.AddBegrenzungsEbene([3, 0, 4]); APolyeder.AddBegrenzungsEbene([0, 3, 2, 1]); ShowMessage(FloatToStr(APolyeder.Volumen)); ShowMessage(FloatToStr(APolyeder.Schwerpunkt.X)); ShowMessage(FloatToStr(APolyeder.Schwerpunkt.Y)); ShowMessage(FloatToStr(APolyeder.Schwerpunkt.Z)); finally APolyeder.Free; end; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz