Zum Inhalt springen

Dreidimensionaler Kreisbogen im kartesischen Koordinatensystem


quorti

Empfohlene Beiträge

Hallo zusammen,

ein Kumpel und ich sind im Rahmen eines kleinen Projektes dabei eine CNC-Fräse an den Achsen mit Schrittmotoren auszustatten, welche mit einem Arduino verbunden sind. Der Arduino bekommt seine Befehle vom Parser, der wiederum seine Kommandos von G-Code kriegt.

Da wir nur eine dreiachsige Fräse haben können wir keine Bogen fahren und somit den G02 von G-Code nicht ausführen.

Dafür bin ich seit einiger Zeit dabei die Koordinaten einer Kugel in das Kartesische Koordinatensystem zu übersetzen. Gegeben (vom Parser) werden: der Startpunkt, der Endpunkt und der Mittelpunkt. Zum Testen habe ich eine kleine Klasse, die mir die Punkte in ein dreidimensionales Koordinatensystem einzeichnet.

Soweit so gut - und auf der x/y-Ebene funktioniert das wunderbar.

Soviel kurz zu Einleitung.

Jetzt mein Problem: kommen z-Werte dazu (^= bewegen wir uns im dreidimensionalen Raum) gibt es auf der x/z- und auf der y/z-Ebene ein gestrecktes "S" (sieht eher wie das Integral-Zeichen aus), wenn man direkt von oben drauf schaut (logischerweise sollte der Kreisbogen dann wie eine Linie aussehen).

Ich gehe bei der Berechnung so vor, dass ich anhand der zwei gegebenen Punkte zu allererst den Radius berechnen. Dann berechne ich die Winkel

Berechnung "winkel" (Winkel zwischen z-Achse und dem Punkt):


winkel = 180*Math.acos(((_p3dPointMin.z - _p3dUrsprung.z) / _intRadius))/Math.PI

Berechnung phi (Winkel zwischen x-Achse und dem Punkt):

if(point.x > 0)

   phi = Math.atan(point.y/point.x);

if(point.x == 0)

   phi = Math.signum(point.y)*Math.PI/2;

if(point.x < 0 && point.y >= 0)

   phi = Math.atan(point.y / point.x) + Math.PI;

if(point.x < 0 && point.y < 0)

   phi = Math.atan(point.y / point.x) - Math.PI;

Die Berechnung dieser beiden Winkel führe ich für beide gegeben Punkte durch. Damit habe ich dann insgesamt vier Winkel: 1. winkelVon 2. winkelBis 3. phiVon 4. phiBis Dann schaue ich bei welchem der "Hauptwinkel" die Differenz zwischen Von und Bis höher ist und nehme diese Differenz als die Anzahl der zu laufenden Schritte und setzte die Schrittgröße dieses Winkels auf 1. Die Schrittgröße des anderen "Hauptwinkels" errechnet sich dann über dessen Differenz geteilt durch die Anzahl der zu laufenden Schritte. Habe ich diese Werte, laufe ich in einer Schleife von 0 bis zur Anzahl der Schritte und erhöhe "winkel" und "phi" jeweils um deren Schrittgröße. Für jede "Winkelkombination" errechne ich dann wie folgt den jeweiligen Punkt:

x = _p3dUrsprung.x + _intRadius * Math.sin(Math.PI*winkel/180) * Math.cos(Math.PI*phi/180);

y = _p3dUrsprung.y + _intRadius * (Math.sin(Math.PI*winkel/180)) * Math.sin(Math.PI*phi/180);

z = _p3dUrsprung.z + _intRadius * Math.cos(Math.PI*winkel/180);

Wobei _p3dUrsprung der Kugelmittelpunkt und _intRadius der Radius der Kugel sind. (Darauf werden die Werte gerundet und es wird geprüft, ob sie innerhalb der angegeben Toleranz liegen (also für die Fräse abildbar sind), aber das klammere ich an dieser Stelle erstmal aus).

Als letztes schreibe ich diesen Punkt in eine ArrayList, welche am Ende dann zurückgegeben wird, wenn die Schleife fertig gelaufen ist.

Da die x/y-Ebene korrekt dargestellt wird ist meine Vermutung, dass das Problem entweder in der Berechnung von "winkel" oder in meiner Schleifenlogik liegt.

Ich wäre äußerst glücklich, wenn mir vielleicht jemand weiterhelfen könnte.

Achja: geschrieben ist das Ganze aktuell in Java, aber hier geht es eher um den Algorithmus, daher habe ich das mal hier gepostet.

LG und schon im Voraus vielen Dank,

quorti

(PS: SuFu habe ich benutzt, aber nichts hilfreiches gefunden)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gast runtimeterror

Hi, kannst du deine Zielsetzung etwas zusammenraffen? Es klingt vom Thema her nicht allzu kompliziert, ich kann deiner Beschreibung allerdings kaum folgen.

Ps: schau dir mal Math.atan2 () und Math.toRad ()/toDeg () an.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, kannst du deine Zielsetzung etwas zusammenraffen?

Hi runtimeterror.

Mein ziel ist quasi einen Kreisbogen mit linearen Koordinaten abzubilden. So ein bisschen wie beim Malen nach Zahlen, dass die Punkte mit Linien verbunden (nahezu) einen Kreis ergeben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gast runtimeterror

Es gibt mehrere Möglichkeiten in Abhängigkeit davon, welche Informationen gegeben sind.

m = Mittelpunkt des Kreises/der Kugel

right = ein Vektor in der Ebene in der sich der Kreis befindet und mit der Länge des Kreisradius (m + right = Position deines Punktes bei phi = 0°)

up = ein Vektor in der Ebene in der sich der Kreis befindet und mit der Länge des Kreisradius (und der senkrecht zu right steht) (m + up = Position deines Punktes bei phi = 90°)

phi = der Winkel im Bogenmaß

Die Anzahl der Dimensionen ist hierfür irrelevant

p = m + right * cos(phi) + up * sin(phi);
Oder in Java für 3D
p.x = m.x + right.x * Math.cos(phi) + up.x * Math.sin(phi);

p.y = m.y + right.y * Math.cos(phi) + up.y * Math.sin(phi);

p.z = m.z + right.z * Math.cos(phi) + up.z * Math.sin(phi);

Das ist die einfachste Form. Die Frage ist, welche Informationen du über die Lages des Kreisbogens im Raum besitzt. Es gibt auch die Möglichkeit einen bekannten Punkt um eine Achse im Raum zu rotieren. Hierfür wird der Mittelpunkt und die Achsrichtung/-Orientierung des Kreises benötigt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gast runtimeterror
Gegeben (vom Parser) werden: der Startpunkt, der Endpunkt und der Mittelpunkt.

Ah - das hatte ich überlesen. Ich schau mal, ob ich das auf die Schnelle hinbekomme ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gast runtimeterror

s = Startpunkt (gegeben)

e = Endpunkt (gegeben)

m = Mittelpunkt (gegeben)

u = s - m

v = e - m

axis = u X v = (Kreuzmultiplikation; Achse, um die sich der Kopf dreht)

angle = acos((u * v) / (u.length * v.length)) = Winkel zwischen Start und Endposition (* = Skalarprodukt)

right = u

up = (axis X right).normalize()

Also: (fiktive Vektor-Klasse, aus dem Kopf, ungetestet!!, auf die Schnelle -> muss weg :) )


Vector3D u = new Vector3D(s.x - m.x, s.y - m.y, s.z - m.z);

Vector3D v = new Vector3D(e.x - m.x, e.y - m.y, e.z - m.z);

double angle = Math.acos((u.x * v.y + u.y * v.y + u.z * v.z) / (u.length() * v.length()));

double radius = u.length();

Vector3D right = u;

Vector3D up = Vector3D.xmul(axis, right).normalize().mul(radius);


for (int i = 0; i <= STEP_COUNT; i++) {

    double phi = angle * i / STEP_COUNT;

    p.x = m.x + right.x * Math.cos(phi) + up.x * Math.sin(phi);

    p.y = m.y + right.y * Math.cos(phi) + up.y * Math.sin(phi);

    p.z = m.z + right.z * Math.cos(phi) + up.z * Math.sin(phi);

    pointList.add(p);

}

normalize() teilt den Vektor durch seine Länge, welcher dann eine Länge von 1 hat.

xmul() ist das Kreuzprodukt zweier Vektoren

Der Radius wird dem Startpunkt entnommen! Wenn der Endpunkt einen anderen hat -Pech :)

Viel Erfolg!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...