Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Drehsinn von Ebenen (https://www.delphipraxis.net/187110-drehsinn-von-ebenen.html)

Bjoerk 28. Okt 2015 10:59

Drehsinn von Ebenen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Gibt es die Möglichkeit herauszufinden ob der Drehsinn einer Ebene mathematisch positiv oder negativ eingegeben wurde (Siehe Anlage)? :oops:

Memnarch 28. Okt 2015 11:10

AW: Drehsinn von Ebenen
 
Ich schätze mal nicht. Für eine Drehung bzw eine sichtbare Orientierung eines Objektes gibt es mehrere Wege die nach Rom führen.

Bambini 28. Okt 2015 11:13

AW: Drehsinn von Ebenen
 
Zitat:

Zitat von Bjoerk (Beitrag 1319938)
Gibt es die Möglichkeit herauszufinden ob der Drehsinn einer Ebene mathematisch positiv oder negativ eingegeben wurde (Siehe Anlage)? :oops:

Wenn man die Reihenfolge der Vertexes kennt, schon.

Jens01 28. Okt 2015 11:14

AW: Drehsinn von Ebenen
 
Meinst Clockwise sowas?

Such mal nach "clockwise" auf der Seite.

So sieht die Funktion bei mir aus:

Delphi-Quellcode:
function TPolygon.IsClockwiseXY: Boolean;
// Paul Bourk - A = Area des Polygons
var
  A: Double;
  i: Integer;
begin
  A     := 0;
  for i := 0 to Count - 2 do
    A   := A + (Self[i].X * Self[i + 1].Y - Self[i + 1].X * Self[i].Y);
  A     := A / 2;
  Result := A < 0;
end;
Bin mir aber nicht ganz sicher, ob es das ist, was Du suchst.

Bjoerk 28. Okt 2015 11:23

AW: Drehsinn von Ebenen
 
Hallo Jens,
das mit A = Summe Determinanten / 2 stimmt nur am Gesamtsystem.

Bambini 28. Okt 2015 11:38

AW: Drehsinn von Ebenen
 
http://stackoverflow.com/questions/1...lockwise-order

Jens01 28. Okt 2015 11:57

AW: Drehsinn von Ebenen
 
Du zählst die Punkte eh irgendwie anders. Ist das FEM-Shit?:shock:

Bjoerk 28. Okt 2015 12:29

AW: Drehsinn von Ebenen
 
Nee, ich zähle nicht anders? :) Deine Formel gilt hat nicht für Slice(Polygon) und wäre auch nur so wie gezeigt richtig, wenn du den 1. Punkt als letzen Punkt nochmal drin hast.

Ich brauch das für die Berechnung von Volumen und Schwerpunkt von Spannungskörpern bei schiefer Biegung für meine Polyederklasse. Polyeder sind quasi räumliche N-Ecke. Da gibt man die Eckpunkte und die einzelnen Begrenzungsebenen an. Voraussetzung ist hierbei, daß alle Ebenen mathematisch positiv eigegeben worden sind. Hierfür wollte ich eine kleine Überprüfung schreiben und falls nicht dann die Punkte in umgekehrter Reihenfolge setzen.

Delphi-Quellcode:
    Polyeder.Clear;
    Polyeder.AddPoint(1, 1, 0);
    Polyeder.AddPoint(4, 1, 0);
    Polyeder.AddPoint(4, 6, 0);
    Polyeder.AddPoint(1, 6, 0);
    Polyeder.AddPoint(4, 6, 10);

    Polyeder.AddPlane([0, 3, 2, 1]);
    Polyeder.AddPlane([1, 2, 4]);
    Polyeder.AddPlane([1, 4, 0]);
    Polyeder.AddPlane([4, 3, 0]);
    Polyeder.AddPlane([3, 4, 2]);

    ShowMessage(Format('%.3f', [Polyeder.Volumen]));
    C := Polyeder.Center;
    ShowMessage(Format('%.3f', [C.X]));
    ShowMessage(Format('%.3f', [C.Y]));
    ShowMessage(Format('%.3f', [C.Z]));

Jens01 28. Okt 2015 12:48

AW: Drehsinn von Ebenen
 
Zitat:

wäre auch nur so wie gezeigt richtig, wenn du den 1. Punkt als letzen Punkt nochmal drin hast
Danke für den Himweis, schon bei mir korrigiert. Ansonsten bin ich raus. Ich schmeiss mal den Begriff Triangulation rein, aber ohne drüber nachgedacht zu haben.
Bis dahin...

Namenloser 28. Okt 2015 13:11

AW: Drehsinn von Ebenen
 
Einfach von allen aneinanderliegenden Vektoren (Differenzen zwischen den Punkten) das Kreuzprodukt nehmen? Wenn bei allen Ergebnissen (wieder ein Vektor) die Z-Achse > 0 ist, ist der Drehsinn positiv. Wenn er bei allen < 0 ist, ist der Drehsinn negativ. Falls beide Vorzeichen vorkommen, ist bei der Eingabe ein Fehler passiert. Zumindest müsste das meiner Meinung nach funktionieren.

Du solltest aber auch noch prüfen, ob die Punkte wirklich auf einer Ebene liegen.

Bjoerk 28. Okt 2015 14:34

AW: Drehsinn von Ebenen
 
Nein. Leider. Habs getestet. Und daß die Punkte auf der Ebene liegen ist hier gesichert weil die Ebenen so aufgespannt werden.

Der Code von #8 ist eine Pyramide. P0..P3 sind die Grundfläche, P4 die Spitze.
Bei Ebene 5 sagt er ist negativ.

Ich hab auf die Schnelle nur die ersten beiden Punkte einer Begrenzungsebene geprüft:

Delphi-Quellcode:
function TPolyeder.CrossProduct(const A, B: integer): TPolyederPoint;
begin
  Result.X := FPoints[A].Y * FPoints[B].Z - FPoints[A].Z * FPoints[B].Y;
  Result.Y := FPoints[A].Z * FPoints[B].X - FPoints[A].X * FPoints[B].Z;
  Result.Z := FPoints[A].X * FPoints[B].Y - FPoints[A].Y * FPoints[B].X;
end;

function TPolyeder.ClockwiseSense(const Index: integer): integer;
begin
  Result := Sign(CrossProduct(FPlanes[Index].Items[0], FPlanes[Index].Items[1]).Z);
  ShowMessage(Format('Result %d', [Result]));
end;

Namenloser 28. Okt 2015 14:51

AW: Drehsinn von Ebenen
 
Ja, ich habe deine Frage glaube ich etwas falsch verstanden, sorry. Da fällt mir jetzt auf die Schnelle auch nichts ein. :(

Bjoerk 28. Okt 2015 18:32

AW: Drehsinn von Ebenen
 
Wie sieht denn sowas für den Raum aus, das wär's (denke ich mal) :gruebel:

Für 2D:

Current = B, A = Prev, C = Next

Code:
    |xA, yA, 1|
Det |xB, yB, 1| > 0
    |xC, yC, 1|

Jens01 28. Okt 2015 20:17

AW: Drehsinn von Ebenen
 
Warte mal...
Du suchst dies IsClockwise, was ich für 2D gepostet habe für 3D?

Bjoerk 28. Okt 2015 21:07

AW: Drehsinn von Ebenen
 
Für D2 hab ich's doch direkt über deinem Post gepostet?

Delphi-Quellcode:
function TD2Points.ClockwiseOrder(const J: integer): boolean;
var
  I, K: integer;
  D: double;
begin
  I := Prev(J);
  K := Next(J);
  D := FItems[I].X * FItems[J].Y + FItems[J].X * FItems[K].Y + FItems[K].X * FItems[I].Y
    - FItems[J].Y * FItems[K].X - FItems[K].Y * FItems[I].X - FItems[I].Y * FItems[J].X;
  Result := D > 0;
end;


So gehts für D3 schon mal nicht. :shock:

Code:
     xA, yA, zA, 1
     xB, yB, zB, 1
Det  xC, yC, zC, 1  > 0
      0, 0, 0, 1

Jens01 28. Okt 2015 21:17

AW: Drehsinn von Ebenen
 
Zitat:

D2, D3
Na, schon etwas überarbeitet?:shock:

Ich über den Ansatz Matrix komme ich nicht, aber über den Ansatz mit Vektoren.
Das müßte doch einfach mit dem Crossprodukt gehen, oder? Ich habe sowas für Polygonflächen in 3D:thumb:.
Ist das nicht schon das Gesuchte :

Delphi-Quellcode:
    A    := 0;
    for i := 2 to Self.Count - 1 do
    begin
      t := Triangle.Create(Self[0], Self[i], Self[i - 1]);
      A := A + t.CrossProdukt;
    end;
    Result := A.Length / 2;

function Triangle.CrossProdukt: Vektor;
var
  R1, R2: Vektor;
begin
// FA, FB, FC => Vektoren des Triangle
  R1     := FC - FA;
  R2     := FB - FA;
  Result := R1.CrossProduct(R2);
end;

Bjoerk 29. Okt 2015 04:03

AW: Drehsinn von Ebenen
 
Hi Bud,

wollte nicht "überarbeitet" rüberkommen. Sorry. Kann sein, daß das Kreuzprdukt bei bei D2 funzt, aber defintiv nicht bei D3.

Damit hat's (bis jetzt) für alle Beispiele gefunzt (aber nur, wenn man das System in den Urpsrung (0,0,0) verschiebt).

Delphi-Quellcode:
    |xA, yA, zA, 1|
    |xB, yB, zB, 1|
Det |xC, yC, zC, 1| > 0
    | 1, 1, 1, 1|

Jens01 29. Okt 2015 11:13

AW: Drehsinn von Ebenen
 
Zitat:

aber nur, wenn man das System in den Urpsrung (0,0,0) verschiebt
Ist das ein Problem?

Bjoerk 29. Okt 2015 13:07

AW: Drehsinn von Ebenen
 
Das ist sicherlich no problem. Arber, das Problem ist, einen geeigneten Vektor zu finden um die fehlende Zeile der Determinante zu ergänzen. Hatte eben einen Fall wo es nicht ging. Ich lass es jetzt. Wenn noch jemand eine Idee zu hat, bitte her damit. Ich bin meinem Latein am Ende. Muß halt aufpassen daß ich die Ebenen korrekt eingebe.

Delphi-Quellcode:
    |xA, yA, zA, 1|
    |xB, yB, zB, 1|
Det |xC, yC, zC, 1| > 0
    | ?, ?,  ?, ?|
Dank' Dir und Gruß alle, die hier mitgewirkt haben.:thumb:

Jens01 29. Okt 2015 13:23

AW: Drehsinn von Ebenen
 
Du bist irgendwie so auf Matrix/Determinante fixiert. Vllt machst Du es doch mit dieser Flächenberechnung bzw Crossprodukt. Bis dahin...

BUG 29. Okt 2015 14:47

AW: Drehsinn von Ebenen
 
Wie soll der Drehsinn in 3D überhaupt definiert sein :gruebel:
Wenn man das ganze auf eine festgelegte Ebene projiziert dann kann man wieder den 2D-Ansatz nehmen.
In deinem Beispiel wäre die Projektionsebene eine die parallel zur x- und zur y-Achse ist.

Ansonsten macht das Ganze imho nicht so viel Sinn.

Bjoerk 29. Okt 2015 22:20

AW: Drehsinn von Ebenen
 
Normal zur Plattenebene. Und da liegt wohl der Haken. Woher weiß die Ebene was Ihre Unterseite ist. Dazu bräuchte man erst eine Transformationsmatrix E um dann auf E[3, 3] > 0 o.ä. zu prüfen. Oder man gibt einen Referenzknoten an. Keine Ahnung?

Namenloser 30. Okt 2015 15:11

AW: Drehsinn von Ebenen
 
Ich denke, man müsste/könnte von einem Punkt der Fläche aus in Richtung der Normalen einen Strahl aussenden und dann die Anzahl der Schnittpunkte mit den anderen Flächen zählen.

Oder, falls der Polyeder konvex ist, könnte man auch die vektorielle Distanz zwischen dem Mittelpunkt und einem Punkt auf der Fläche berechnen, und dann schauen, ob dieser "in die gleiche Richtung" zeigt wie die Normale der Fläche (Skalarprodukt > 0), was einfacher und schneller wäre.

Bjoerk 31. Okt 2015 10:52

AW: Drehsinn von Ebenen
 
Hab auch nochmal überlegt. Ich mach es lieber mit einem Referenzvektor. Den soll/kann eine Ebene bekommen. Wären entweder (1, 0, 0) oder (0, 1, 0) oder (0, 0, 1) oder (-1, 0, 0) oder (0, -1, 0) oder (0, 0, -1) und vergleiche auf <0.
Code:
  IsNeg = (PlaneNormal.X * V.X < 0) or (PlaneNormal.Y * V.Y < 0) or (PlaneNormal.Z * V.Z < 0).
Ich denke mal dieser Vektor wäre auch die 4. Zeile für die Determinante von #19. Keine Ahnung?

Wenn A,B,C die 1. Ersten drei Punkte der Ebene sind, dann geht der Normaldingens doch so, oder?
Delphi-Quellcode:
function TPolyeder.PlaneNormal(const A, B, C: integer): TPolyederPoint;
var
  AB, AC: TPolyederPoint;
begin
  AB.X := FPoints[B].X - FPoints[A].X;
  AB.Y := FPoints[B].Y - FPoints[A].Y;
  AB.Z := FPoints[B].Z - FPoints[A].Z;

  AC.X := FPoints[C].X - FPoints[A].X;
  AC.Y := FPoints[C].Y - FPoints[A].Y;
  AC.Z := FPoints[C].Z - FPoints[A].Z;

  Result.X := AB.Y * AC.Z - AB.Z * AC.Y;
  Result.Y := AB.Z * AC.X - AB.X * AC.Z;
  Result.Z := AB.X * AC.Y - AB.Y * AC.X;

  Showmessage(Format('%.4f, %.4f, %.4f', [Result.X, Result.Y, Result.Z]));
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:35 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