mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Kreis in die Ecke schieben


Autor: Pieter (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
moin moin,

drehe mich ein wenig im Kreis..;-)

Für den Kreis um Punkt A kann die Position zu C mit sin/cos und der 
Stecke C_D berechnet werden.
Wie aber berechne ich nun Punkt B?
Dieser Punkt liegt auf der Winkelhalbierenden C_D_E und jeweils lotrecht 
mit Abstand R zu den Strecken.
Das C_D eine Senkrechte ist, ist eigendlich auch ein Spezialfall, die 
Gleichung sollte davon unabhängig sein.

Danke.
Mit Gruß
Pieter

Autor: Roland Praml (pram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bezogen auf http://www.thehazymind.com/images/3DEngine/trig1.jpg
gilt a/b = tan alpha

(b ist ein Teilstück DEINER Strecke CD, a= Radius vom Kreis, alpha ist 
der halbe Winkel)

Gruß
Roland

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pieter wrote:

> Für den Kreis um Punkt A kann die Position zu C mit sin/cos und der
> Stecke C_D berechnet werden.

sin/cos
Du übertreibst.

Wenn du einen Verktor hast, zb den Vektor C_D, mit den Komponenten
C_Dx und C_Dy, dann hat ein dazu senkrechter Vektor die
Komponenten  -C_Dy, C_Dx
Diesen Vektor normierst du (bringst ihn auf Einheitslänge) und
skalierst ihn mit dem gewünschten Kreisradius. Diesen neuen
Richtungsvektor zum ursprünglichen Positionsvektor C addiert
ergibt den Mittelpunkt des Kreises A

   C_D.x = D.x - C.x
   C_D.y = D.y - C.y

   Perp.x = -C_D.x
   Perp.y =  C_D.y

   Len = sqrt( Perp.x * Perp.x + Perp.y * Perp.y )
   Perp.x = Perp.x / Len * r
   Perp.y = Perp.y / Len * r

   KreisA.x = C.x + Perp.x
   KreisA.y = C.y + Perp.y

Macht man sich eine schöne Vektor Datenstruktur mit ein
paar Hilfsfunktionen (für Addition etc.) oder in C++ eine
schöne Vektor Klasse, dann kann (im Falle von C++) die
ganze Berechnung so aussehen:

   KreisA = C + ( D - C ).Perpendicular().Normalize() * r;

> Wie aber berechne ich nun Punkt B?
> Dieser Punkt liegt auf der Winkelhalbierenden C_D_E und jeweils lotrecht
> mit Abstand R zu den Strecken.
> Das C_D eine Senkrechte ist, ist eigendlich auch ein Spezialfall, die
> Gleichung sollte davon unabhängig sein.

Ist sie auch.
Der Mittelpunkt des Kreises liegt auf dem Schnittpunkt
der Geraden, die im Abstand r jeweils parallel zu den original
Geraden liegen.

Da es zu jeder Geraden 2 dazu parallele Geraden mit einem
bestimmten Abstand gibt, gibt es insgesamt 4 solcher Schnittpunkte
und daher gibt es auch 4 Kreise, die die beiden Geraden (wenn sie
unendlich lang wären) berühren.

Aber im Grunde läuft es auf die Berechnung des Schnittpunkts
2-er Geraden hinaus.


Persönlich bin ich der Meinung, dass Winkelfunktionen überbewertet
werden. Mit ein wenig nachdenken und einem rechten Winkel kommt man
sehr oft sehr gut ohne sie aus. Schon alleine deswegen, weil dann
oft viele Spezialfälle (die zb beim Tangens in Unendlich oder bei
den anderen beiden in eine böse 0 die bei Divisionen stört, ausarten)
wegfallen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Die in der Mathematik so beliebte Geradengleichung

  y = k*x + d

ist ziemlich ungeeignet um Schnittpunkte 2-er Geraden vernünftig
zu berechnen. Da steckt nämlich wieder eine Winkelfunktion, diesmal
der Tanges, in Form des k drinnen. k wird bei Senkrechten Geraden
aber unendlich. Nicht gut zum rechnen.


Besser ist folgende Form:

Sei eine Gerade gegeben durch 2 Punkte auf ihr: P1 und P2

Dann gilt für jeden Punkt P auf der Geraden

   P = P1 + tP * ( P2 - P1 )

(P ist eine Vektorgleichung. Es gibt also jeweils eine Gleichung
für x und für y
   Px = P1x + tP * (P2x - P1x)
   Py = P1y + tP * (P2y - P1y)
)

wobei tP ein laufender Parameter ist. Setzt man für tP = 0
ein, so erhält man den Punkt P1. Setzt man tP = 1 dann erhält
man P2. Für Werte von tP zwischen 0 und 1 erhält man jeweils
einen Punkt der zwischen P1 und P2 und auf der Geraden
liegt.


Hat man also 2 Geraden, P und Q, dann schneiden sich die beiden
im Punkt S (so sie sich überhaupt schneiden, dazu später mehr)

Für diesen Punkt S muss daher gelten:

   S = P1 + tP * ( P2 - P1 )

und natürlich, da S ja ebenfalls auf Q liegen muss (sonst wäre es
ja kein Schnittpunkt)

   S = Q1 + tQ * ( Q2 - Q1 )

Dieses Gleichungssystem kann man zb nach tP lösen und erhält dann
für tP einen schnuckeligen Bruch. (als Aufgabe für den Leser
hier nicht gezeigt. Der Bruch ist aber wirklich nicht kompliziert)

Mit dem nun bekannten tP geht man in die Gleichung

  P = P1 + tP * ( P2 - P1 )

und erhält die Koordinaten des Schnittpunktes.

Wie immer bei einem Bruch muss man darauf achten, dass nicht durch
0 dividiert wird.
Überlegt man sich geometrisch welche Bedeutung eine 0 im Nenner
des Bruches hat, so stellt man fest, dass eine 0 anzeigt, dass die
beiden Geraden zueinander parallel sind. In dem Fall gibt es
klarerweise keinen Schnittpunkt.
Abgesehen davon gibt es aber keinen Sonderfall mehr und man kann
den Schnittpunkt 2-er beliebigen Geraden berechnen.

Autor: Pieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin moin,

@Karl Heinz

nun ja, rechte Winkel sind die Aussnahme, c verwende ich nicht, sqrt ist 
auch ein Problem...und und und..

habe mal ein wenig im Vermessungswesen geschmörkt..

danach sieht die Gleichung in allgemeiner Form so aus:

WH Winkelhalbierende
@ Anstieg der Gragen

B.Y = D.Y - r( sin(@) * tan(WH) - cos(@) )
B.X = D.X - r( cos(@) * tan(WH) - sin(@) )

an einer senkrechten Linie (@=90) verkürzen sich die Gleichungen zu

B.Y = D.Y - r*(1*tan(WH) - 0) = D.Y - r * tan(WH)
B.X = D.X - r*(0*tan(WH) - 1) = D.X + r

(das was Roland angegeben hatte)
muss nun noch die Vorzeichen mal durchrechen.

..und das ganze in mein Assemblerprogramm einbauen...


Danke und bis danne
Pieter

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pieter wrote:

> nun ja, rechte Winkel sind die Aussnahme,

Eher nicht. Rechte Winkel finden sich fast überall.
Man muss sie nur suchen und finden.

> c verwende ich nicht, sqrt ist
> auch ein Problem...und und und..

Wurzel ist ein Problem aber sin/cos/tan ist in Ordnung?
Wird Zeit dass der Komet kommt.

> B.Y = D.Y - r*(1*tan(WH) - 0) = D.Y - r * tan(WH)
> B.X = D.X - r*(0*tan(WH) - 1) = D.X + r

> ..und das ganze in mein Assemblerprogramm einbauen...

Na dann. Viel Spass beim Tangens.
Und bei all deinen Sonderfällen in denen dich bei Winkeln
in der Nähe von 180 Grad der Tangens (Winkelhalbierende nahe bei
90 Grad) in den Wahnsinn treiben wird. Von der abnehmenden
Genauigkeit je weiter sich der Winkel öffnet (und der Tangens
unaufhaltsam größer wird), rede ich erst mal gar nicht.

Hast du dir schon Gedanken darüber gemacht, wo du den Winkel
herkriegst :-) Du hast ja nur die 3 Punkte. Da wird dann
auch noch ein Arcus Sinus bzw. ein Arcus Cosinus fällig

:-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.