Just nu i M3-nätverket
Gå till innehåll
NetJosh

Räkna ut var två stycken cirklar korsar varandra

Rekommendera Poster

NetJosh

Hejsan!

 

Jag skulle behöva hjälp med en matematisk lösning som innebär att räkna ut de två punkterna (x,y) där två/eller flera cirklar korsar varandra.

 

Lite mer utförligt kan jag skriva:

 

Du har (i detta fall) två stycken cirklar. Om de korsar varandra så vill jag räkna ut var ytterkanten på de båda cirklarna korsas.

 

På engelska heter det "Intersection of two circles" och jag har sökt på google och fått fram flera alternativ, dock inget som jag lyckas lösa :S

 

Tack så mycket på förhand /Victor

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
wcanka

Hejsan

 

Jag tror det är lämpligt att använda sig av cirkelnekvation i detta fall. se länk:

http://matmin.kevius.com/cirkekv.html

 

Använd alltså (x - a)² + (y - B)² = r², förutsatt att du vet cirkelns mitt punkt samt radie. Har du två stycken cirklar så får du två stycken sådana här ekvationer. Och sen för att hitta vart de korsar varandra så är det bara att sätta dessa två ekvationer lika med varandra. ekv1 = ekv2. Och sen försöka klura ut värden på x och y.

 

 

- Ju mer man vet, desto mer vet man att man inte vet

wcanka

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

hehe tack! Jag ska kolla på det nu, eller efter lunchen.

 

Det jag vet är mittpunkterna på båda cirklarna samt radien på båda. Det jag vill ha tag på är koordinaterna för de två punkterna där cirklarna skär. Bara så ni vet ;)

 

 

EDIT: Jag ser ingen möjlighet att räkna ut punkternas x och y koordinater med hjälp av den formeln.

[inlägget ändrat 2007-06-29 12:24:37 av NetJosh]

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

jag har nu löst "halva" uppgiften, jag får ett streck igenom punkterna, men det är ett lååångt streck, vilket inte är det jag vill ha.. detta med hälp av:

 

abs() = absolutbeloppet

sqrt() = squareroot "rooten ur"

 

D = sqrt(abs(x1-x0)+abs(y1-y0))
a = (r0^2-r1^2+D^2)/(2*D)
h = sqrt(r0^2-a^2)
#h = sqrt(r1^2-b^2)

A = sqrt((D+r0+r1)*(D+r0-r1)*(D-r0+r1)*(r0+r1-D))

X0 = ((x0+x1)/2)-(((x0-x1)*(r0^2-r1^2))/(2*D^2))+(2*((y0-y1)/(D^2)))*A
Y0 = ((y0+y1)/2)-(((y0-y1)*(r0^2-r1^2))/(2*D^2))-(2*((x0-x1)/(D^2)))*A

X1 = ((x0+x1)/2)-(((x0-x1)*(r0^2-r1^2))/(2*D^2))-(2*((y0-y1)/(D^2)))*A
Y1 = ((y0+y1)/2)-(((y0-y1)*(r0^2-r1^2))/(2*D^2))+(2*((x0-x1)/(D^2)))*A

 

(jag ritar med hjälp av python)

 

Bara så att ingen missförstår, tråden är INTE LÖST :)

 

 

EDIT: detta funkar bara om radien är densamma på båda cirklarna :/

[inlägget ändrat 2007-06-29 13:23:09 av NetJosh]

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
Pejo

Hej,

 

Se figur för beteckningar.

 

För att två cirklar (a och B) ska korsas måste avståndet mellan deras centrum, d, vara mindre än summan av deras radier.

 

d <= Ra + Rb

 

d får du med hjälp av (Xa, Ya) och (Xb, Yb), likaså vinkeln m.

 

När två cirklar skär varandra får du en triangel där du vet alla sidor (Ra, Rb, d) och kan då räkna ut vinkeln n genom cosinussatsen. När du vet vinklarna n och m kan du räkna ut skärningspunkten p relativt mittpunkten i cirkel a.

 

mvh

/Johan

 

 

 

[bild bifogad 2007-06-29 16:49:20 av Pejo]

957527_thumb.jpg

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

hmm. tackar :) Dock har jag löst det, hittade ett färdigt script som inte utnyttjade cosinussatsen (det tar längre tid i et program). Tack ändå!

 

Men en till fråga! Hur räknar jag ut vinkeln mellan Rb och d för punkten (Xp,Yp), i detta fall?

 

 

det är de två gröna linjerna i bilden som jag söker efter.. alltså deras vinkel i en generell formel..

[inlägget ändrat 2007-07-05 15:01:20 av NetJosh]

[bild bifogad 2007-07-05 15:01:30 av NetJosh]

959461_thumb.jpg

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
Pejo
Dock har jag löst det, hittade ett färdigt script som inte utnyttjade cosinussatsen

 

Blir lite nyfiken på hur skriptet går till väga ...

 

Dock, vinklarna du frågar efter i din figur är precis vinklarna m+n och m-n i min figur (vinklarna är symmetriska runt avståndet d mellan mittpunkterna), fast i 2:a kvadranten. Beroende på hur vinklarna beräknas får uträkningen delas upp i några olika fall m.a.p i vilken kvadrant skärningen sker.

 

mvh

/Johan

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

okej.. hmm, jag borde förstå vad du menar men det är ju sommar :P. Jag vet ju vilka vinklar jag vill åt men inte hur jag räknar ut dem..

 

 

Du har först en sats som kollar om de överhuvudtaget skär varandra.

if (d > (r0 + r1)) or (d < abs(r0 - r1)):
           #ingen lösning
       else:
           #det finns en lösning

 

Sedan har du scriptet som räknar ut (xi,xi_prime,yi,yi_prime) men som utgår ifrån två cirklars x & y positions samt radien (x0,y0,r0) och (x1,y1,r1)

dx = x1 - x0
dy = y1 - y0
d = ((dy*dy) + (dx*dx)) ** 0.5 #rooten ur

a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d)

x2 = x0 + (dx * a/d)
y2 = y0 + (dy * a/d)

h = ((r0*r0) - (a*a)) ** 0.5 #rooten ur

rx = -dy * (h/d)
ry = dx * (h/d)

xi = abs(x2 + rx)
xi_prime = abs(x2 - rx)
yi = abs(y2 + ry)
yi_prime = abs(y2 - ry)

 

[inlägget ändrat 2007-07-06 08:30:42 av NetJosh]

[inlägget ändrat 2007-07-06 08:33:33 av NetJosh]

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

Det är ingen som lyckas knäcka denna mattenöt?

 

Jag ska försöka förklara igen..

 

Jag är ute efter två vinklar i en cirkel. I bilden som jag bifogade är det de två gröna vinklarna. De utgår från 0 och fortsätter 360 grader (nedåt/klockans varv) men det jag vill ha är en generell formel som funkar i _alla_ fall!

 

Hoppas det gjorde det lite klarare för er för för mig så är det fortfarande oklart hur jag ska gå tillväga.

 

MVH /Victor

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
Pejo

Hej igen, (har varit "off-line" några dagar)

 

Som jag fattade det fungerar skriptet (ser riktigt ut, men jag har inte kollat alla fall beroende på var skärningen sker) och i så fall har du redan dina punkter. För att få vinklarna till punkterna behöver du en invers trigonometrisk funktion (tex arccos, se http://mathworld.wolfram.com/InverseCosine.html). Eftersom denna inte täcker hela varvet (0-360grader) får du också ha lite koll på tecken.

 

Antag att en skärningspunkt har koordinaterna (xi,yi), relativt (x0, y0).

Enligt din figur blir det två fall för den sökta vinkeln, v.

 

yi<=0: v = arccos(xi)

yi>0: v = 360 - arccos(xi)

 

mvh

/Johan

 

P.S På den refererade sidan finns en approximation av arccos (Maclaurin-serien), om du vill ha en alternativ (och snabbare?) beräkning av funktionen. Tänk bara på att den är i radianer. D.S

 

[inlägget ändrat 2007-07-11 11:24:28 av Pejo]

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

Okej, det är förståeligt att du var off-line, dock kan jag inte det riktigt då jag måste slutföra mitt sommarjobb :)

 

Jo, att jag måste använd arccos är jag helt införstådd i, dock inte det där med "approximation av arccos (Maclaurin-serien)". Datorkapaciteten som finns tillgänglig på jobbet ska tydligen vara mer än tillräckligt, enligt mina chefer. Men det är klart att jag ska försöka optimera det så gott jag kan, men det får bli i ett senare skede när jag har fått fram en bra formel att använda :)

 

Jag kommer efter lunchen ta och kolla på det (enkla?) svaret och se om det kan vara något för mig.

 

tack för att du tar dig tiden :) /Victor

 

 

 

Jag kom och tänka på att du skriver "den sökta vinkeln v". För att det inte ska bli några missförstånd så är det faktiskt två vinklar jag är ute efter. Dessutom fick jag ett underligt fel när jag försökte räkna acos(xi) --> "ValueError: math domain error". I testexemplet som jag använder mig av har jag fått ut att xi = 187,5 (vilket förövrigt är rätt värde).

[inlägget ändrat 2007-07-11 13:02:20 av NetJosh]

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
Pejo
Antag att en skärningspunkt har koordinaterna (xi,yi), relativt (x0, y0).

Enligt din figur blir det två fall för den sökta vinkeln, v.

 

yi<=0: v = arccos(xi)

yi>0: v = 360 - arccos(xi)

Får skylla på att min hjärna inte går riktigt på högvarv efter några veckors semester och det saknas en liten men ack så viktig del i mina formler om de ska funka på någonting annat än enhetscirkeln ...

Nu tar vi det ordentligt från början.

Du har en cirkel med radien r0 och centrum i (x0,y0).

Skriptet ger en punkt med koordinaterna (xi,yi) på cirkelns omkrets.

De relativa koordinaterna för denna punkt är (xi-x0,yi-y0).

Vidare gäller att cos(v)=(xi-x0)/r0 och därmed att v = arccos[(xi-x0)/r0]. Argumentet till arccos måster vara i intervallet -1 till 1 och uttrycken citerade ovan ska alltså bli:

(yi-y0)<=0: v = arccos[(xi-x0)/r0]

(yi-y0)>0: v = 360 - arccos[(xi-x0)/r0]

 

 

mvh

/Johan

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

Tack! Detta funkar!

if ((yi-y0)<= 0):
   v = math.degrees(math.acos((xi-x0)/r0))
else:
   v = 360 - math.degrees(math.acos((xi-x0)/r0))

 

och jag har suttit och försökt mig på att göra samma sak för vinkeln för slutet, alltså den andra gröna vinkeln, men jag lyckas inte få till det.

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
Pejo

Nu förstår jag inte riktigt ... De båda skärningspunkternas vinklar beräknas på samma sätt, fast med sina respektive koordinater.

 

mvh

/Johan

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

Svar nej, det ser inte så ut i alla fall.. Men förmodligen har jag gjort fel:

 

v1 = math.degrees(math.acos((yi-y0)/r0))

#Respektive:

v1 =360 - math.degrees(math.acos((yi-y0)/r0))

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh

Hej igen!

 

Jag har nu fått en lösning av en annan, den ser ut som nedan:

 

v0 = 360 - math.degrees(math.atan2(yi - y0, xi - x0))
v1 = 360 - math.degrees(math.atan2(yi_prime - y0, xi_prime - x0))

 

Så enkelt var det :P

 

Jag har testat det men finns det någon lösning som detta inte klarar?

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
Pejo
Svar nej, det ser inte så ut i alla fall.. Men förmodligen har jag gjort fel:

 

v1 = math.degrees(math.acos((yi-y0)/r0))

 

#Respektive:

 

v1 =360 - math.degrees(math.acos((yi-y0)/r0))

 

Var kom (yi-y0) ifrån? Ditt tidigare uttryck var riktigt.

if ((yi-y0)<= 0):

v = math.degrees(math.acos((xi-x0)/r0))

else:

v = 360 - math.degrees(math.acos((xi-x0)/r0))

Använd detta både på (xi,yi) och (xi_prime,yi_prime)

 

Det spelar ingen roll om du använder arccos eller arctan, men som jag har fattat det vill du ha ett svar i intervallet 0 till 360 grader och båda dessa funktioner lämnar svar i intervallet -180 till 180 grader. Dvs du måste dela beräkningen i två delar som tar hänsyn till var skärningen inträffar.

 

mvh

/Johan

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser
NetJosh
Var kom (yi-y0) ifrån? Ditt tidigare uttryck var riktigt.

 

Nej, det funkar tyvärr inte! Jag har prövat och det blir inget bra.

 

Dela detta inlägg


Länk till inlägg
Dela på andra webbplatser

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Skapa ett nytt konto på vårt forum. Det är lätt!

Registrera ett nytt konto

Logga in

Redan medlem? Logga in här.

Logga in nu



×
×
  • Skapa nytt...