Sida 1 av 2
Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 26 jun 2007, 11:19
av Victor
Hejsan, nu kommer jag här med en svår fråga
Jag har skapat ett roligt script i Python som ritar cirklar, ganska många faktiskt (jag läser ur en fil), som i dagsläget överlappar varandra, vilket jag inte vill att de ska göra.. Det jag vill är att om en cirkel skulle gå in i en annan cirkel så "klipps" den delen bort som går in i den andra filen. Likaså ska den andra cirkeln "klippas" så att det i slutändan ser ut något såhär:
[img width=419 height=362]http://img339.imageshack.us/img339/8800/cellsmz9.png[/img]
Shot at 2007-06-26
Man måste alltså plocka ut skärningspunkterna där de båda skär varandra (i kanterna) och dra ett sträck där emellan samtidigt som man tar bort "överflödet".
Hoppas ni förstår frågan, om inte så säg till.
EDIT: Kan tillägga att jag för tillfället utnyttjar PIL men att jag inte är bunden till det.
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 26 jun 2007, 17:48
av pbodin
Det här kanske hjälper dig med matematiken:
http://local.wasp.uwa.edu.au/~pbourke/geometry/2circle/
Det bör inte vara så svårt att implementera.
HTH
PB
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 27 jun 2007, 10:20
av Victor
hehe, tack

nu fick man lite jobb

återkommer om jag får det att funka.. jag återkommer nog om det inte funkar heller

SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 27 jun 2007, 12:47
av Victor
okej. nu har jag tittat på bilden. en grej jag inte förstår är hur jag ska räkna ut x2 och y2 vilket är lika med P2..
EDIT: lägger till en fråga: om jag kör programmet nedan så bli ju h(höjden) = 0 oavsett vad för värden jag stoppar in. Antingen tänker jag hur knasigt som helst eller så är det fel formler..
Kod: Markera allt
from math import sqrt
r0 = 4.00
r1 = 2.00
d = r0+r1
a = ((r0*r0)-(r1*r1)+(d*d))/(2*d)
h = sqrt((r0*r0)-(a*a))
print 'a = ',a,'\nh = ',h
OUTPUT:
a = 4.0
h = 0.0
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 27 jun 2007, 14:18
av Konservburk
Victor skrev:
en grej jag inte förstår är hur jag ska räkna ut x2 och y2
Använd likformighet;
(P2 - P0)/a = (P1 - P0)/d.
Victor skrev:
Antingen tänker jag hur knasigt som helst eller så är det fel formler..
Men
d är endast lika med summan av
r0 och
r1 om cirklarna råkar
tangerar varandra! Du vill ta reda på avståndet
d = || P1 - P0 ||.
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 27 jun 2007, 16:26
av Victor
hmm.. bra

jag kanske ska ta tag i saken imorgon istället för nu verkar (och känns) det som att jag är trött. Tack iaf!
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 29 jun 2007, 13:28
av Victor
DrKonservburk skrev:
Använd likformighet; (P2 - P0)/a = (P1 - P0)/d.
hur tänker du nu?
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 03 jul 2007, 15:41
av Konservburk
Victor skrev:
DrKonservburk skrev:
Använd likformighet; (P2 - P0)/a = (P1 - P0)/d.
hur tänker du nu?
P1 - P0 är en vektor som börjar i punkten
P0 och pekar på punkten
P1. Om du normerar (delar vektorn med vektorns längd) så har du
en enhetsvektor (med längden 1) som börjar i
P0 och fortfarande
pekar åt samma håll.
Om du gör samma sak för vektorn
P2 - P0 så får du en exakt likadan
enhetsvektor som tidigare.
DVS vi har ekvationen
(P1 - P0)/||P1 - P0|| = (P2 - P0)/||P2 - P0||.
I figuren som var länkad så hade de kallat
||P1 - P0|| för
d och
||P2 - P0|| för
a. Därav
(P2 - P0)/a = (P1 - P0)/d.
Om du nu inte har någon bra koll på vektorer så kanske jag ska tala
om att detta samma sak som separata ekvationer i x-led och i y-led:
(x2 - x0)/a = (x1 - x0)/d
(y2 - y0)/a = (y1 - y0)/d
Vektorns längd kan du räkna ut med Pythagoras sats:
||P1 - P0||^2 = (x1 - x0)^2 + (y1 - y0)^2
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 04 jul 2007, 10:59
av Victor
Tack alla! Jag har nu gjort så att jag hittar alla skärningar på alla cirklar/celler och dessutom ritar ut dem. Men nu kommer ett annat stort problem. Som topicen säger så vill jag "klippa" bort överflödet! Finns det något sätt som jag kan göra detta på? Se bilden i första posten..
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 04 jul 2007, 11:10
av upnorth
Går det inte att koda så att ingenting ritas ut förrän allt är uträknat?
Då kanske du skulle kunna skriva koden så att ringarna byter färg eller liknande efter skärningspunkterna?
Alternativt att de slutar ritas ut, men det verkar svårare...
Annars kanske det går att lägga en fylld rektangel med bakgrundsfärgen över överfödet i kant med gränslinjerna...
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 04 jul 2007, 11:32
av Victor
Alltså, allt målas ut efter att det räknats ut..
Dock har jag ingen aning om vilken "teknik" jag ska använda, alltså, om jag ska säga åt programmet att inte måla på just det stället eller något. Jag vet inte vilka funktioner jag i så fall skulle utnyttja eller hur jag ska gå tillväga..
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 04 jul 2007, 11:56
av upnorth
Har du skivit funktionen som ritar ut själva cirklarna själv, eller är det en färdig funktion som du bara anropar?
Om du gjort den själv borde du kunna skriva den så att den ritar pixel för pixel kring en punkt med en agiven radie.
Då skulle du kunna ange start och slutpunkterna, är det samma punkt - voila! - en full cirkel, annars får du en "parantes".
Har lite problem med att sätta mig in i syntaxen, och dessutom kommer jag inte ihåg hur man skriver ut enskilda pixlar. Har bara sysslat med tecken i konsol förut.
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 04 jul 2007, 12:08
av Victor
Svar ja, jag har skrivit funktionen som ritar cirkeln själv (det finns ingen funktion som ritar cirklar utan man får skapa en själv utifrån en ellips).
Att rita pixel för pixel borde kanske inte vara något problem. Jag kollar nu, men om någon annan vet ett bättre/annat sätt samt kunde ge ett exempel vore jag tacksam.
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 04 jul 2007, 12:11
av upnorth
Haha, lyckas du efter mina idéer gör du det bra!
Men skämt åsido, hur fungerar den funktionen du gjort nu?
Vilken metod bygger den på alltså?
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 04 jul 2007, 12:30
av Victor
chord
draw.chord(xy, start, end, options)
Same as arc, but connects the end points with a straight line.
The outline option gives the colour to use for the chord outline. The fill option gives the colour to use for the chord interior.
Det är en chord jag ska rita, inte en cirkel - verkar det som.. Dock vet jag inte hur jag ska utnyttja mina punkter (skärningarna) i chorden. Jag tror föresten inte det går att rita en sådan om cirkeln/cellen skär med mer än en cirkel(?)...
Min funktion är lite mer komplex, det finns en funktion till alla x1,y1,x2... enkelt kan jag säga att den i slutändan ser ut såhär:
Kod: Markera allt
#detta är x,y på mittpunkten och sedan radien
#x0 = 200
#y0 = 300
#r0 = 100
x01 = int(x0)-int(r0)
y01 = int(y0)-int(r0)
x02 = int(x0)+int(r0)
y02 = int(y0)+int(r0)
draw.ellipse((x01, y01, x02, y02), outline='black')
EDIT: La till lite ovan..
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 05 jul 2007, 12:40
av Victor
Tja igen, jag har lyckats skapa två cirklar som överlappar varandra (se bild). Jag har även lyckats skapa en chord med hjälp av att räkna ut start och slut värdena.
(x01,y01,x02,y02) är positionen och det är samma som den cirkeln som överlappar har.
Kod: Markera allt
n = 180
aStart = int(math.degrees(math.asin((-h)/r0))+n)
aEnd = int(math.degrees(math.asin(h/r0))+n)
draw.chord((x01,y01,x02,y02),aStart,aEnd, fill='green', outline='green')
i dagsläget funkar detta bara om cirklarna har samma y-värde och om cirkeln som överlappar ligger till höger om den som överlappas. Det kan man dock ändra på lätt och sätta n=0 istället. I detta fall är det den svarta som överlappar den gröna och jag har även lagt på en chord som är grön med hjälp av koden jag skrev.
Bilden som jag skapat just nu ser ut såhär:
[img width=300 height=300]http://img360.imageshack.us/img360/9721/hallovz6.jpg[/img]
Shot at 2007-07-05
Hoppas det kan vara till hjälp för er så ni kan hjälpa mig

SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 05 jul 2007, 12:46
av upnorth
Men kan du lägga till ytterligare cirklar efter de där?
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 05 jul 2007, 13:09
av Victor
Det borde inte vara några problem då jag ritar en chord för varje överlappning. Däremot om det finns flera stycken cirklar som skär vid samma punkt/er så kanske det kan bli konstigt..
Och varför skulle ja inte kunna lägga till fler cirklar efteråt?
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 05 jul 2007, 13:17
av upnorth
Victor skrev:
Det borde inte vara några problem då jag ritar en chord för varje överlappning. Däremot om det finns flera stycken cirklar som skär vid samma punkt/er så kanske det kan bli konstigt..
Och varför skulle ja inte kunna lägga till fler cirklar efteråt?
Nä, jag bara ANTOG att du kanske gjorde bilden i ditt första inlägg av en anledning...men kul att det fungerar!
SV: Rita cirklar som man ska "klippa" i när de överlappar varandra
Postat: 05 jul 2007, 13:25
av Victor
Mjo. visst gjorde jag den av en anledning

men det funkar ju inte riktigt som jag vill.. Det funkar BARA om de har samma Y-värde! Jag skulle behöva en generell formel..
Här är en bild till, med tre stycken..
[img width=400 height=300]http://img366.imageshack.us/img366/5025/halloen9.jpg[/img]
Shot at 2007-07-05
de har alla samma y värde...