Vet inte om detta är rätt forum, men men. Du får ställa upp det på lite olika nivåer, så att säga. Tack för ditt svar, men, skulle du kunna vara snäll o skriva ett exempel, för jag förstår inte allt, men nästan. Det behöver inte vara i något speciellt språk, men bara hur grundstrukturen ser ut(alltså rent program-mässigt). Ojsan, där skrev jag visst jäkligt långsamt... inga svar när jag började skriva... =) Tackar för det mycket välgenomgågna svaret=) Ska ta mig en titt på det nu, men har lite brottom ut (lördakväll), men ska gå igenom det imorron. Förstår nästan allt du har skrvit, men när jag ska få ihop ett program av det så blir det något fel. (Jag är nog bara lite trög, men detta verkar invecklat=)) Lessen att jag inte har svarat, jag gjorde det i morse, men då fuckade datorn loss totalt, så det kom inte. Okej, datorn e fortfarande kass, men jag får sitta i felsäkert läge och skriva...Problem:Grafritare
Tänkte göra en grafritare, men jag undrar hur jag ska gå tillväga. Vill gärna kunna "zooma in".
Det som jag tänkte på först är:
man stoppar in x i en funktion och sen får ut y värdet. Sedan drar man ett sträck från föregående x och y värde till nästa. Detta borde ju funka, men hur gör man när man ska zooma in?
Programmeringsspråket är oviktigt i denna situationen.
Tack på förhand!Sv: Problem:Grafritare
För det första så har du en viewport; det du ser på skärmen. Det är en helt och hållet dynamisk grej.
Det kan du skriva som viewminx, viewmaxx, viewminy, viewmaxy, t.ex. Exakt hur du skriver det spelar ingen roll. Om du har en punkt (5, 4), t.ex. så ska du ha x=5 y=4 i viewporten.
Sen har du en "faktisk" skärm. Det har du på pixelnivå, t.ex. xmin=0, xmax=300, ymin=0, ymax=200
Denna förändras om du förändrar storlek på fönstret, men inte annars.
Nu gör du två funktioner; ViewportToScreen och ScreenToViewport, som tar en koordinat och gör om till en annan. På så sätt kommer du alltid vet vad en punkt är i båda systemen. Då tar du punkten ovan, (5,4), och omvandlar den till t.ex. (50,35).
För att zooma så förändrar du viewporten; inte svårare än så...
Sen vill du ha en fin jämn kurva, så då ska du ju ha ett y-värde för varje x-pixel, annars blir det hackigt. Därför loopar du igenom alla pixel-x (50) och omvandlar dem till viewport-x (5). Det nya x-et skickar du till din funktion, och därifrån får du ett viewport-y (4), som du omvandlar tillbaks till pixel-y (35). Sen kan du rita ut det.Sv: Problem:Grafritare
Är inte så bra på programmering än.Sv: Problem:Grafritare
Om vi säger så här, lite strukturerat:
1. En punkt beskrivs av ett koordinatpar, (x,y).
2. Det finns en viewport som kan ha en godtycklig storlek, och godtycklig förskjutning. I den "världen" lever punkter.
3. Det finns en skärm som har en fast storlek, och som alltid börjar på samma punkt, i den "världen" lever pixlar.
4. Du kan omvandla fram och tillbaka mellan dessa världar.
Eller så här: Tänk dig ett rutat papper som du ska rita en graf på. Pappret har en viss storlek, men grafen kan se ut hur som helst. x-axeln kan gå från -1 till 1, 0 till 100 eller 1000 till 5000, t.ex.
Här är pappret skärmen och skalorna är på samma sätt godtyckliga. Det du nu vill göra är att omvandla från en Viewportpunkt till en Skärmpunkt, och tillbaka. Det som är det krångliga här är att komma på hur man omvandlar detta. Nu vet jag inte hur gammal du är,men jag antar att du känner till funktioner.
Vi betecknar x-koordinaten i viewporten som x, och x-koordinaten på skärmen som X. Vi har kanske en viewport där x ligger mellan -1 och 1. vi kallar de kanterna för xmin och xmax. Skärmen har kanske x-koordinater mellan 0 och 300, dessa gränser kallar vi Xmin och Xmax. Detta innebär att vi har en bild som är 300 pixlar i bredd.
Då ska xmin motsvara Xmin, och xmax motsvara Xmax.
Vi skriver nu X(x), dvs. X som funktion av x, eller skärmkoordinater som funktion av vykoordinater. Principen är nu att vi kan stoppa in en vykoordinat och få ut en skärmkoordinat.
Eftersom X är linjär skriver vi så här:
X(x)=A*x+b
Nu kan vi till exempel säga så här: Jag vet att x är 0.3. Vilken pixel motsvarar det?
X(0.3)=A*0.3+b
Men vi måste ta reda på vad A och b är. Vi känner till X i kantpunkterna, så vi kan skriva
X(xmax)=A*xmax+b=Xmax
och
X(xmin)=A*xmin+b=Xmin
Om vi nu subtraherar den undre från den övre får vi:
X(xmax)-X(xmin)=A*xmax+b-A*xmin-b=Xmax-Xmin
Vi bryter ut A, och får A(xmax-xmin)=Xmax-Xmin
A=(Xmax-Xmin)/(xmax-xmin)
Okej?
sen sätter man in det i första ekvationen, och då får vi
X(xmax)=A*xmax+b=(Xmax-Xmin)/(xmax-xmin)*xmax+b=Xmax
Och då kan vi bryta ut b.
Detta skriver vi nu som en funktion:
double ViewportxToScreenx(double x)
{
return A*x+b;
}
Gör samma sak för X->x, och de båda y-varianterna.
Sen kan du tillexempel göra så här:
for(X=Xmin; X++; X<Xmax) //gå igenom alla pixlarna
{
x=ScreenToViewportx(X); //nu har du det "riktiga" värdet på x
y=f(x); //nu får du fram det "riktiga" värdet på y
Y=ViewportToScreeny(y); //och nu får du fram y-koordinaten för funktionen i pixelform.
//rita en linje från förra punkten till (X, Y)
}
kanske lite otydlig, säg till om du inte förstår.Sv: Problem:Grafritare
Det som rörde till det för mig var viewport, eftersom jag programmerar i Pascal(ska snart börja med c++).
Beträffande ålder, är jag 18 år gammal
Tackar igen=)Sv: Problem:Grafritare
Skulle du kunna klargöra lite mer det exemplet du gjorde. Du hoppar lite fram och tillbaka. Skulle du kunna skrivat det som om det skulle kunna funka(om inte det är för mycket begärt), Vad symboliserar a och b?
Tack på förhand.
Så här långt har jag fattat:
function
y=sin(x)
slut på funktion
for-sats från dator-x-min till dator-x-max
dator-x ska bli lika med skärm-x men hur?
dator-y blir skickas till funktionen tillexmpel y=sin(x)
skärm-y ska bli lika med dator-y men hur?
ritar upp skärm-x-y
slut på for satsSv: Problem:Grafritare
Jag ska försöka svara imorrn, det är inte så krångligt, men jag har så förbannat ont om tid.
Kan ge en extremt kort förklaring:
A är en slags "skalfaktor", dvs. om du flyttar dig 0.1 åt höger i vyn, hur mycket åt höger ska du flytta dig i antal pixlar?
Det blir typ A*(storlek i vyn).
B är ett offset. Det är till för att xmin inte alltid är 0, som skärmen oftast är.Sv: Problem:Grafritare
Du är med på att du har en "riktig" punkt, t.ex. x=pi/2~1.6, y=sin(pi/2)=1?
Om du nu ska rita in det på ett papper så har du t.ex. x-skalan=[0, 2pi], y-skalan=[-1.5, 1.5]. Du har ett rutat papper och du fyller i hela den rutan som motsvaras av punkten (pi/2, 1). Samma sak ska du göra på skärmen.
Du har som sagt xmin, xmax, ymin, ymax, vilket motsvaras av: 0, 2pi, -1.5, 1.5, i fallet ovan.
Sen har du Xmin, Xmax, Ymin, Ymax. Det motsvaras av storleken på pappret. Du kan säga att Xmin=Ymin=0, det innebär att du kallar den översta vänstra eller understa vänstra punkten för (0,0).
Både den "riktiga" skalan och "skärmskalan" är linjära, och det innebär följande:
Låt säga att du har x i verkligheten och X på skärmen. En viss punkt x=1 motsvaras av punkten X=3. Om du nu flyttar dig ett steg till höger i x-skalan får du x=2. Samma förflyttning motsvaras ax X=5.
Du ser att i x-skalan blir förflyttningen (2-1)=1, men i X-skalan blir den (5-3)=2.
Flyttar du nu den verkliga punkten ytterligare ett steg åt höger, x=3, får du X=7, med x-skillnad (3-2)=1, och X-skillnad (7-5)=2 - precis samma förflyttning. Att det är samma förflyttning är det man menar med att de förhåller sig linjärt till varandra.
Det är det som A representerar; hur mycket X-skalan förändras i en förändring av x-skalan, vilket vi kan skriva som X=Ax. Men det är ett fel, och det ser du snart:
Går man ett steg till vänster i x-skalan från punkten x=1 kommer man ju till x=0. Eftersom vi har sett hur X-skalan är dubbelt så stor som x-skalan, så listar vi ut att x=0 måste motsvaras av X=1.
Eftersom x=0 inte sammanfaller med X=0, så räcker det inte med att X=Ax, utan vi måste lägga till B, och den blir i det här fallet 1
Slutsatsen blir alltså att X(x)=2x+1. Det kan vi kolla med värdena ovan:
X(0)=2*0+1=1, rätt!
X(1)=2*1+1=3, rätt!
X(2)=2*2+1=5, rätt!
Sen kan man naturligtvis göra samma sak åt andra hållet, men det gör man lättast algebraiskt:
X=2x+1
X-1=2x
x=0.5X-0.5
Och det kan vi också prova:
x(1)=0.5*1-0.5=0
x(3)=0.5*3-0.5=1
x(5)=0.5*5-0.5=2
Nu hoppas jag att du förstår principen. Vi ska räkna ut två stycken parametrar; A och B. Sedan kan vi använda dem för att kunna omvandla punkter fram och tillbaka.
Samtidigt är det ganska lätt att inse att vi bara behöver veta vad kantvärdena motsvarar för att lösa det. Vi sätter in xmin i X(x)=Ax+B, och vet att det ska vara lika med Xmin. Sen gör vi samma sak med xmax, och då har vi två ekvationer (en för xmin och en för xmax) och två obekanta (A och B).
Vi kan ta ett enkelt exempel. Vi har en skärmruta med en bredd på 20 pixlar. Det motsvaras av Xmin=0, XMax=20. Vi kan gå igenom varje pixel i denna ruta genom att skriva
for(int x=0; x<20; x++)
//...
I denna ruta vill vi nu visa en speciell vy, t.ex. intervallet [-5, 5]. Det kan till exempel vara något som händer från tiden t=-5s till t=5s.
Det första vi ser är att LÄNGDEN på x-axeln i verkligheten är 10, men LÄNGDEN på x-axeln på skärmen är 20. En ändring från -5 till -4 kommer motsvaras av en förändring från pixeln x=0 till x=2, dvs A=2.
Sen motsvarar inte den verkliga punkten x=0 skärmpunkten X=0, utan X(0)=10 (mitten av intervallet).
Du kan alltså säga att A=längden på skärmen/längden i verkligheten = (Xmax-Xmin)/(xmax-xmin) = (20-0)/(5-(-5)) = 20/10 = 2
B däremot är krångligare, men du får ut det från
X(xmin)=A*xmin+B=Xmin
B=Xmin-A*xmin, eller i det här fallet:
B=0-2*(-5)=10
Nu hoppas jag att du förstår hur man gör. Själv måste jag plugga partiella differentialekvationer... =)