k 2 k 1 = y a a y f = k 1 y f y 2 = y 1 + k 1 (x 2 x 1 ) k 2 = k 1 y 2

Relevanta dokument
k 1 k 2 y a b Figur 1: En ljusstråle genom en tunn lins ändrar sin vinkel då den passerar genom linsen. Ljusstrålens lutning före linsen är här k1 = y

Laboration 1: Linser

Laboration 1: Linser

Laboration 1: Linser

Laboration 1: Linser

Laboration 1: Linser

Laboration 1: Linser

Programkonstruktion för F, 2D1342, Laboration 0: Kom igång med Java-programmering - förberedande uppgifter

UNIX. 2D1339 Programkonstruktion Hösten 2001 Datorintroduktion Laboration 1. Mål. Vad laborationen går ut på. Redovisning

Lab5 för prgmedcl04 Grafik

2D1339 Programkonstruktion för F1, ht 2003

2D1339 Programkonstruktion för F1, ht 2004

Optisk bänk En Virtuell Applet Laboration

Att prova på en enkel Applet och att lära sig olika sätt att hämta data från tangentbordet. Du får även prova på att skapa din första riktiga klass.

Objektorienterad programmering i Java. Föreläsning 5 Kort om Java-Applets

Java: Utvecklingsverktyg, datatyper, kontrollstrukturer

2D1339 Programkonstruktion för F1, ht 2003

2D4112 Datalogi I, grundkurs med Java, Labkurs 1. Godkänd Labkurs 1 ger 2p (högskolepoäng) av kursens totalt 10p

Programutveckling med Java Development Kit. (JDK 1.1.x) och Programmers File Editor (PFE 7.02)

Frivillig Java-swing-Graphics-lab Programmeringsteknik MN1 vt02

PROGRAMMERINGSTEKNIK TIN212

TENTAMEN I PROGRAMMERING. På tentamen ges graderade betyg:. 3:a 24 poäng, 4:a 36 poäng och 5:a 48 poäng

Introduktion till Matlab

OBJEKTORIENTERAD PROGRAMVARUUTVECKLING. Övningstentamen 2

Institutionen för matematik och datavetenskap Karlstads universitet. GeoGebra. ett digitalt verktyg för framtidens matematikundervisning

Laboration 1. "kompilera"-ikonen "exekvera"-ikonen

ID1004 Laboration 3, 5-6 November 2012

GeoGebra i matematikundervisningen - Inspirationsdagar för gymnasielärare. Karlstads universitet april

Introduktion till Matlab

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Studieanvisning i Optik, Fysik A enligt boken Quanta A

NetBeans 7. Avsikt. Projektfönster

Mätning av fokallängd hos okänd lins

GeoGebra i matematikundervisningen - Inspirationsdagar för gymnasielärare. Karlstads universitet april. Liten introduktionsguide för nybörjare

DN1240, Numeriska metoder. Laboration 0 (frivilliga delar) (dvs uppgifterna behöver inte redovisas) Introduktion till UNIX och MATLAB

Inlämningsuppgift 1 Programmeringsteknik MN1 vt02

OBS! Snabbinsatt Matlab-intro vissa fönsterhanteringsdetaljer kan vara fel men gör gärna Matlab-uppgifterna. DN1240, Numeriska metoder för OPEN1.

DN1212, Numeriska metoder & grundläggande programmering. Laboration 1 del 1-3 (frivilliga delar) Del 1-3 (dvs upg ) behöver inte redovisas

Laboration 1 Introduktion till Visual Basic 6.0

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

Det är principer och idéer som är viktiga. Skriv så att du övertygar examinatorn om att du har förstått dessa även om detaljer kan vara felaktiga.

Objektorienterad Programkonstruktion. Föreläsning 3 9 nov 2015

Kort-kort om utdelade användarkonton och datormiljön på NADA

LABORATION 1 AVBILDNING OCH FÖRSTORING

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

NetBeans 5.5. Avsikt. Projektfönster

Laboration: Grunderna i MATLAB

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

Föreläsning 5-6 Innehåll

Programmeringsteknik II - HT18. Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt

Träff 1 Skissa & Extrudera

Använda Python Laboration 1 GruDat, DD1344

Laboration 1. "kompilera"-ikonen "exekvera"-ikonen

Parallella jobb ctrl-z emacs & more README ctrl-z jobs. %<jobnr>

PROGRAMMERING-Java Omtentamina

3 Man kan derivera i Matlab genom att approximera derivator med differenskvoter. Funktionen cosinus deriveras för x-värdena på följande sätt.

Geometrisk optik. Syfte och mål. Innehåll. Utrustning. Institutionen för Fysik

Editering, Kompilering och Exekvering av Javaprogram

Applets med komponenter

Exempel på användning av arv: Geometriska figurer

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

Övningsuppgifter till föreläsning 2 Variabler och uttryck

Undersökande arbetssätt i matematik 1 och 2

TENTA: TDDD11 & TDDC68. Tillåtna hjälpmedel. Starta Emacs, terminal och tentakommunikationsfönster. Skicka in frågor och uppgifter

Vrida detalj samt flytta nollpunkt 1

Eclipse. Avsikt. Nu ska ett fönster liknande figuren till höger synas.

TANA17 Matematiska beräkningar med Matlab

Handbok Svarta lådan. Nicolas Roffet Robert Cimrman Philip Rodrigues Lauri Watts Översättare: Stefan Asserhäll

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

OBJEKTORIENTERAD PROGRAMVARUUTVECKLING. Övningstentamen 1

3.5 Visuell programmering

SF1520, Numeriska Metoder och Grundläggande Programmering för K2 Lab1.

4.4 Swing ett interaktivt grafiskt gränssnitt

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

Program. Kapitel make Program Interpreterande och kompilerande program

DD1342 Programkonstruktion för F1, ht 2007

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

STOCKHOLMS UNIVERSITET VT 2011 Avd. Matematisk statistik GB DATORLABORATION 1: TIDSSERIER.

Kom igång. Readyonet Lathund för enkelt admin. Logga in Skriv in adressen till din webbsida följt av /login. Exempel:

Objektorienterad programmering i Java I

Handbok Förstoringsglaset. Sarang Lakare Olaf Schmidt Översättare: Stefan Asserhäll

Programmering, grundkurs, 8.0 hp, Elektro, KTH, hösten Programmering: att instruera en maskin att utföra en uppgift, kräver olika språk:

Kompilera och exekvera Javakod

Uppgiften är att beskriva en kvadrat i ett Java program. En första version av programmet skulle kunna se ut så här:

Kort om klasser och objekt En introduktion till GUI-programmering i Java

2D1342 Programkonstruktion för F1, ht 2006

TAIU07 Matematiska beräkningar med Matlab

Laboration: Grunderna i Matlab

FrontPage Express. Ämne: Datorkunskap (Internet) Handledare: Thomas Granhäll

Förberedelseuppgift inför datorlaborationen

Programmering. Scratch - grundövningar

Precis som var fallet med förra artikeln, Geogebra för de yngre i Nämnaren

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Laboration 3. Funktioner, vektorer, integraler och felskattning

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

*****************************************************************************

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Laboration 4: Digitala bilder

Objektorienterad programmering Föreläsning 2

Tentamen i TDP004 Objektorienterad Programmering Praktisk del

Transkript:

Programkonstruktion för F, 2D1342, 1998 1999 Laboration 1: Linser [Sista tid för redovisning: vecka 49] 1 Målsättning Under denna laboration ska du skriva ett mindre Java-program. Följande ska du kunna när du är klar med labben: hur man kompilerar och kör Java-program hur man delar upp program i olika metoder för olika uppgifter hur man utför enkla beräkningar och slingor hur man ritar figurer och tar hand om användarens musklickningar Laborationen är tänkt att genomföras under fyra laborationspass. För att underlätta din tidsplanering har vi delat upp laborationen i fyra delar som förslagsvis görs vid de fyra passen. Om du känner att du förstår vad du gör och tiden tillåter får du gärna jobba vidare i förväg. Under alla omständigheter bör du läsa på i förväg vad som ska göras under nästa laborationspass så att du inte behöver ödsla tid framför datorn med att ta reda på det. 2 Lästips Följande avsnitt i boken behandlar saker som du behöver använda i denna laboration: Inför första labbtillfället: Kapitel 1, Att komma igång, speciellt avsnitten 1.7 (applets) och 1.8 (grafik) Inför andra labbtillfället: Avsnitt 2.3, variabler Avsnitt 2.4, definiera och anropa metoder Inför tredje labbtillfället: Avsnitt 6.4, fält, d.v.s. indexerbara variabler Avsnitt 6.5, for-satsen Inför fjärde labbtillfället: Avsnitt 1.8, grafik, speciellt färger Avsnitt 10.1 och 10.2, mus-händelser 1

y a b Figur 1: En ljusstråle genom en tunn lins ändrar sin vinkel då den passerar genom linsen. Ljusstrålens lutning före linsen är här y/a och efter linsen y/b. 3 Uppgiften Du ska konstruera ett Java-program som beräknar och visar hur ett knippe ljusstrålar bryts när de passerar en uppsättning linser, t.ex. i en kikare eller ett mikroskop. Programmet ska skrivas i form av en applet, d.v.s. ett miniprogram som t.ex. kan läggas in på en WWW-sida. För att inte krångla till uppgiften gör vi några begränsningar. För det första begränsar vi oss till att studera ljusstrålar i ett plan. Detta gör vi främst för att det blir enklare att rita upp resultatet. För det andra förutsätter vi att linserna är tunna och att de sitter centrerade efter varandra utefter samma optiska axel. Detta är ett rimligt antagande för vanliga optiska utrustningar som okular, objektiv o.s.v. och gör att beräkningarna blir enklare. Programmet ska när det är klart rita upp linserna samt ett antal strålars väg från en punktformig ljuskälla. Det ska vara enkelt att ändra antalet linser samt deras position och styrka. Slutligen ska ljuskällans position kunna ändras interaktivt med hjälp av musen. 4 Fysikalisk bakgrund För att kunna konstruera programmet måste vi först hitta en lämplig matematisk modell för hur ljusstrålar bryts när de passerar igenom en lins. En snabb titt i närmaste optikbok visar att det finns flera olika modeller att välja mellan. Om linserna är tillräckligt tunna kan vi använda en enklare modell än om man måste ta hänsyn till tjockleken. Här väljer vi den förenklade modellen för tunna linser. För en tunn lins gäller den s.k. linsformeln: 1 a + 1 b = 1 f där f är linsens brännvidd och a och b avståndet till föremålet respektive bilden av föremålet (se figur 1). För att kunna rita upp hur ljusstrålarna bryts i ett linssystem måste man dock översätta linsformeln till en formel för hur en ljusståle ändrar riktning när den passerar en lins. Vi väljer här att representera rikningen med hjälp av linjens lutning som vi betecknar med k. I figur 1 ser vi vad som händer med en ljusstråle med 2

y x 2,y 2 k 2 k 1 x 1,y 1 x Figur 2: Koordinatsystemet väljs så att x-axeln sammanfaller med linsens optiska axel. En ljusstråle från punkten (x 1,y 1) med lutningen k 1 träffar linsen i punkten (x 2,y 2) och fortsätter sedan med lutningen k 2. lutningen k 1 = y/a som träffar linsen på avstånden y ovanför centrum: den får den nya riktningen k 2 = y/b. Eftersom denna översättning mellan lutning och a- resp. b-värden gäller för godtyckliga a och bkan vi använda detta tillsammans med linsformeln för att räkna ut strålens riktning efter linsen (k 2 ) när vi vet riktningen före (k 1 ). k 2 = y ( 1 b = y f 1 ) = y a a y f = k 1 y f Vi ser här att den nya lutningen helt enkelt blir den gamla lutningen minskat med termen y/f där y anger var strålen träffar linsen och f är linsens brännvidd. För att följa en ljusstråle genom en lins kan vi nu göra på följande sätt: Först väljer vi ett koordinatsystem så att x-axeln sammanfaller med systemets optiska axel (figur 2). Vi kallar ljuskällans position (x 1,y 1 ) och strålens riktning k 1 (d.v.s. linjens lutning). Positionen för linsen kallar vi x 2. Med enkel geometri (se figur 2) kan vi räkna ut var strålen träffar linsen: y 2 = y 1 + k 1 (x 2 x 1 ) Efter linsen kommer strålen följdaktligen att gå från punkten (x 2,y 2 ).Återstår att räkna ut den nya riktningen k 2. Denna får vi med hjälp avvår modifierade linsformel från ovan: k 2 = k 1 y 2 f Om man har mer än en lins så är det bara att upprepa samma beräkning igen; nu med (x 2,y 2 ) som startpunkt och k 2 som startriktning, o.s.v. 3

5 Första labbtillfället Under det första labbtillfället ska ni hinna med två saker: Installera kursanpassningar och registrera er på kursen Skriva och provköra ett litet Java-program 5.1 Installation av kursanpassningar För att det ska gå lätt och smidigt att köra Java-program har vi gjort iordning speciella anpassningar av systemet. Det första ni bör göra är därför att installera dessa anpassningar så att ni automatiskt får dem varje gång ni loggar in. Detta ska göras för båda era konton så ni måste göra det två gånger. Logga in. Du bör redan ha fått lära dej hur man gör detta på Krama-dindator -kursen. Ge kommandot: course join progk98 Detta gör att bl.a. Emacs anpassas så att du får tillgång till några specialkommandon för att köra Java-program. Du får också en direktlänk till kursens hemsida i Netscape. Registrering på kursen För att vi ska kunna hålla ordning på vilka som läser kursen och vilka delresultat ni har skrapat ihop måste ni registrera er på kursen. Detta sker genom att ni ger kommandot: res checkin progk98 Ni får då ett antal frågor (namn, personnummer o.dyl.) som vi måste veta för att kunna registrera era resultat. Skapa en gemensam kurskatalog Du och din labbkompis behöver en gemensam filkatalog. Denna tillverkar man enklast med hjälp av course-kommandot. Ge kommandot: course labdir progk98 kompis där kompis är användarnamnet (på formen f98-xxx ) för din labb-kompis. Logga sedan ut och upprepa alla stegen på din labb-kompis konto också. Det är viktigt att ni båda registrerar er på kursen och att båda era konton blir riktigt anpassade för kursen. När ni båda är klara med detta kan ni enkelt gå till er gemensamma katalog genom cd progk98 Det är meningen att ni ska lägga alla filer som har med ProgK-labbarna att göra under denna gemensamma katalog. Det brukar vara en bra idé att skapa underkataloger under progk98, förslagsvis en för varje laboration. Det gör ni med det vanliga Unix-kommandot mkdir ( make directory ). De åtgärder vi har beskrivit här behöver bara göras en gång vid kursens början. Om ni ska byta labb-kompis eller får problem så be en handledare om hjälp med det praktiska. 4

5.2 Skriv och provkör en Java-applet Innan du börjar skriva det riktiga programmet är det lämpligt att börja med något enklare. Under det första laborationspasset ska du därför skriva en enkel Java-applet som inte gör annat än att rita ett par streck påskärmen. Det viktiga är alltså inte vad programmet gör utan hur du går tillväga för att köra programmet. Du ska dock inte fullständigt ignorera innehållet i själva programmet. Vi kommer senare i labben att använda detta lilla program som ett skelett där vi succesivt fyller på med mer och mer funktionalitet. 5.2.1 Filer och kataloger Det första man bör göra när man ska skriva ett program är att skapa en ny filkatalog. Alla filer som har att göra med programmet ska nämligen placeras i en egen filkatalog. Välj ett namn på katalogen som gör att du enkelt känner igen programmet. Eftersom denna laboration handlar om linser kan det vara passande att kalla katalogen linser. I den katalogen kommer vi så småningom att ha tre typer av filer:.java.class.html Detta är textfiler som innehåller själva programmet. Du skapar själv dessa filer med hjälp av Emacs (textredigeraren) och det är i dessa filer du skriver själva programmet. I denna laboration kommer du att ha en sådan fil: Linser.java. Detta är filer som innehåller en kodad form av programmet som används när programmet ska köras. Du behöver inte göra någonting med dessa filer (utom möjligen att städa bort dem när du är klar). I denna laboration kommer det så småningom att skapas en sådan fil: Linser.class. När programmet är en applet måste det startas från en WWW-sida. Denna fil innehåller en minimal WWW-sida som vi bara använder för att kunna provköra programmet. I vårt fall kommer denna fil att heta Linser.html. Lägg märke till att vi använder stor begynnelsebokstav i ordet Linser i filnamnen. Detta beror på att Linser är namnet på en klass i programmet och vi skriver alltid klassnamn med stor begynnelsebokstav. 5.2.2 Skriv HTML-filen Skapa med hjälp av Emacs filen Linser.html med följande innehåll: <APPLET code="linser.class" width=400 height=300> </APPLET> Detta betyder att programmet Linser.class är en applet som ska synas i ett fönster som är 400 bildpunkter brett och 300 högt. 5

5.2.3 Skriv Java-filen Skapa filen Linser.java med följande innehåll: import java.awt.*; import java.applet.*; public class Linser extends Applet public void paint(graphics g) g.drawline(100, 250, 200, 100); g.drawoval(100, 100, 100, 150); } } Detta är ett litet Java-program som ritar en liten figur bestående av en linje och en oval. 5.2.4 Kompilera och provkör programmet Innan du kan köra programmet du just skrivit måste det kompileras. Kompileringen innebär att programmet översätts till ett internformat som snabbt kan tolkas när programmet kör. Kompileringen kan antingen göras genom att man ger kommandot: javac Linser.java eller genom Compile-kommandot i Emacs. Det senare är att föredra eftersom Emacs då kan ge dig stöd för att tolka felmeddelanden o.dyl. Du hittar Compile-kommandot i Tools-menyn. Emacs föreslår ett lämpligt javac-kommando som du får bekräfta genom att trycka på radslut (=Enter). Det föreslagna kommandot innehåller även väljaren -depend som instruerar kompilatorn att kompilera alla de java-filer som ändrats. Detta spelar dock ingen roll i denna första laboration eftersom vi bara kommer att jobba med en Java-fil hela tiden. Om kompileringen lyckades så har du nu fått en fil med namnet Linser.class som innehåller programmet i det interna formatet. Vi är nu redo för att provköra programmet. Se till att placera dig (med hjälp av cd-kommandot) i den katalog där programmet ligger. Vårt program är en applet och vi kör det därför med hjälp av kommandot: appletviewer Linser.html Har du nu gjort allting rätt så ska det dyka upp ett nytt fönster med titeln AppletViewer: Linser.class på skärmen. Första gången du kör kan det tänkas att du får upp ett fönster med licensvillkoren för Java-systemet JDK (Java Development Kit). Du måste då bekräfta att du läst dessa innan du kan gå vidare. När din applet väl har startat ska linjen och ovalen synas i dess fönster. Det finns också en meny med namnet Applet som du framförallt använder för att avsluta provkörningen (menyalternativet Quit längst ned). 5.2.5 Ändra i programmet Prova att göra några enkla ändringar i programmet och kontrollera att ni kan köra den modifierade versionen. 6

Ändra först parametrarna vid anropet av drawline och drawoval och se om ni kan rita någon annan figur. Slår man upp dokumentationen (t.ex. i WWW via kursens hemsida) för dessa två metoder så hittar man följande beskrivningar, för drawline: public abstract void drawline(int x1, int y1, int x2, int y2) Draws a line between the coordinates (x1,y1) and (x2,y2) using the current color. Parameters: x1 - the x coordinate of the start of the line y1 - the y coordinate of the start of the line x2 - the x coordinate of the end of the line y2 - the y coordinate of the end of the line...och för drawoval: public abstract void drawoval(int x, int y, int width, int height) Draws the outline of an oval covering the specified rectangle using the current color. The resulting oval will cover an area (width + 1) pixels wide by (height + 1) pixels tall. Parameters: x - the x coordinate of the upper left corner of the oval to be drawn y - the y coordinate of the upper left corner of the oval to be drawn width - the width of the oval to be drawn height - the height of the oval to be drawn See Also: filloval Stämmer denna beskrivning med vad som händer när du ändrar värdena? Inför gärna något fel i programmet för att se vad som händer. När får du motsvarande felmeddelande: när du skriver felet, sparar programtexten, kompilerar eller kör programmet? Förstår du vad felmeddelandet betyder? Prova gärna med några olika typer av fel, t.ex. felstavningar, konstiga tecken, fel ordning på rader. Om du kompilerar med hjälp av Compile-kommandot i Emacs så kommer felmeddelanden från kompilatorn i ett speciellt Emacs-fönster. Man kan klicka på dessa meddelanden med musens mittknapp för att direkt komma till platsen för felet. Mycket praktiskt! 7

X y x Y Figur 3: Java använder ett koordinatsystem där man räknar i bildpunkter från övre vänstra hörnet (X, Y )-systemet. Inom matematiken och fysiken är det vanliga att använda ett s.k. högersystem (x, y). 6 Andra labbtillfället Målet med detta labbtillfälle är att ni ska skriva en Java-applet som beräknar och ritar hur en ljusstråle bryts när den passerar en lins. Detta program ska ni nästa gång utvidga för att hantera både flera strålar och flera linser. Förra laborationen arbetade vi med ett program som använde sig av färdiga metoder: drawline och drawoval. Denna gång ska du själv definiera egna metoder som räknar om koordinater mellan två olika koordinatsystem. Vi kommer också att stöta på behovet att mellanlagra beräknade värden som ska användas senare. Detta sker genom lagring i variabler. 6.1 Koordinatsystemet Java, liksom många andra datorbaserade grafiksystem, använder sig av ett för en matematiker ganska bakvänt koordinatsystem: origo ligger i övre vänstra hörnet med x-axeln åt höger och y-axeln nedåt. Dessutom är det bara tillåtet att använda heltalskoordinater (som motsvarar antal bildpunkter). När man arbetar med naturvetenskapliga problem är det ofta mycket mer naturligt att använda ett koordinatsystem med y-axeln riktad uppåt och med reella tal som koordinater (se figur 3). Det är egentligen ganska enkelt att konvertera koordinater mellan de två koordinatsystemen. Vi ska börja med att definiera metoder för dessa konverteringar. Eftersom x-axlarna och y-axlarna i de två systemen är parallella kan vi konvertera x-koordinaten och y-koordinaten separat. Detta gör det lite enklare att formulera metoderna för konverteringen. Vi kan också till att börja med begränsa oss till konverteringen från det reella systemet till grafiska heltalssystemet eftersom det är detta som behövs när vi ska rita. En metod för konvertering från x (det reella koordinatvärdet) till X (heltalet) kan illustreras med följande figur: 8

x xtoint Motsvarande definition i Java ser ut på detta sätt: X int xtoint(double x) return <beräkning av heltalskoordinaten för x> ; } Ordet int anger att resultatet är ett heltal (integer). xtoint är metodens namn (du kan själv välja ett annat namn om det passar bättre). Texten (double x) betyder att metoden tar en parameter och att denna parameter är ett reellt tal som vi kallar x (double betyder reella tal lagrade med s.k. dubbel precision). Namnet x används inne i metoddefinitionen för att beteckna värdet av denna parameter. Det speciella ordet return skall följas av ett beräkningsuttryck som anger hur det resulterande värdet ska beräknas. När metoden xtoint väl är definierad kan man använda den som en matematisk funktion i programmet. Man kan t.ex. skriva xtoint(0.5) för att ange den heltalskoordinat som motsvarar 0.5. Jämför t.ex. med hur man använder en funktion som sin(x). Lägg nu in definitionen för två metoder: xtoint och ytoint. Tänk först igenom hur koordinaterna ska räknas om. Välj själv en lämplig skala för problemet. Det kan t.ex. vara lämpligt att arbeta i enheten meter och kanske också att försöka få 0.1 m att bli ungefär en decimeter på skärmen. Tips: Eftersom omvandlingen från ett reellt tal till heltal innebär att man tappar noggranhet (decimalerna försvinner) så måste man uttryckligen begära denna omvandling (se även bokens avsnitt 2.3.4). Man använder då det speciella skrivsättet: (int)<double-uttryck> Exempelvis: double a = 3.1415; int k; k = 25 * (int)(a + 0.3); Uttrycket (a + 0.3) beräknas här som ett double-tal som sedan omvandlas till ett heltal. Detta heltal multipliceras sedan med 25 för att få det slutliga heltalet som lagras i variabeln k. Fundera själv ut hur din omvandling från reella till heltalskoordinater ska gå till. Prova slutligen metoderna genom att rita några linjer uttryckta i det reella koordinatsystemet. Detta gör man genom att ersätta heltalen som är parametrar till drawline mot anrop av dina nya metoder. Kontrollera att resultatet verkar vettigt. 9

Figur 4: När du är klar med andra labbtillfället ska det se ut på ungefär detta sätt på skärmen. 6.2 Rita ljusstrålar i rätt skala Nu ska vi komplettera programmet så att det verkligen räknar ut hur en ljusstråle bryts i en lins. För detta behövs några variabler där man kan mellanlagra beräknade värden som sedan kan användas vid själva uppritningen. Börja med att införa variabler för ljusstrålens utgångspunkt (x 1 och y 1 )och dess lutning (k 1 ). Du behöver även variabler för linsens position (bara x-värdet) och dess brännvidd (f). Det är paint-metoden som används för att rita figuren som man ser i fönstret. Komplettera därför paint-metoden i programmet så att den först räknar ut de koordinater som behövs för att kunna rita strålen både före och efter linsen och därefter ritar motsvarande linjer. Inför några lokala variabler för att lagra de beräknade koordinaterna. Strålen fortsätter oändligt långt till höger, men välj ett lämpligt stort x-värde för att få en slutpunkt för den ritade linjen (det gör inget om du hamnar utanför fönstret). Komplettera dessutom paint-metoden så att den ritar ut ett koordinatsystem (bara axlarna) och linsen (i form av en oval). Bredden och höjden på ovalen beskrivs bäst i heltals-koordinatsystemet medan positionen måste beskrivas i vårt nya koordinatsystem. När du är klar ska figuren se ut ungefär som exemplet i figur 4. Prova att ändra på lampans position och linsens brännvidd. Vad händer om brännvidden är negativ? 10

7 Tredje labbtillfället Nu är det dags att utvidga programmet så att det löser den egentliga uppgiften: att beräkna och rita hur flera ljusstrålar går igenom flera linser. Du kommer att stöta på två programmeringstekniska nyheter. För det första ska vi använda två fält 1 (eng. array) för att lagra linsernas egenskaper. För det andra ska vianvända två upprepningssatser (slingor) för att upprepa samma beräkningar flera gånger, dels för flera linser, dels för flera ljusstrålar. Vi börjar med att införa flera linser men håller kvar vid en ljusstråle så länge. Hela beräkningen och uppritningen av strålen läggs lämpligen i en egen metod så att det blir enkelt att generalisera till flera strålar. Vi låter startpunkt och startlutning vara parametrar till denna metod så att man senare kan anropa den flera gånger med olika värde på lutningsparametern, en för varje ståle. 7.1 Utvidgning till flera linser Definiera en ny metod med följande metodhuvud: void drawray(graphics g, double xstart, double ystart, double kstart) Denna metod har som uppgift att rita en stråles väg genom alla linserna. Strålen startar i punkten (x start,y start ) med lutningen k start. Uppritningen skall ske genom upprepade anrop av g.drawline. Deberäkningar vi tidigare gjorde direkt i paint-metoden skall alltså flyttas över till vår nya drawray och generaliseras till fler linser. Det som behöver finnas kvar i paint-metoden är uppritningen av koordinataxlarna och linserna samt ett nytt anrop av drawray. Eftersom det nu är flera linser är det lämpligt att använda en for-sats för att rita ut alla linserna. Tips: Tidigare har vi använt en variabel för linsens position och en annan för linsens brännvidd. När vi nu ska ha flera linser måste vi hålla reda på flera positioner och brännvidder. Ett fält är ett objekt som kan innehålla flera värden av samma typ. Man använder sig då av index för att välja ut komponenter ur fältet. Indexen är alltid heltal, från noll och uppåt. Det finns flera olika sätt att skapa fält men vi kan här nöja oss med det enklaste: att skriva komponenterna direkt vid variabeldefinitionen. Om vi t.ex. vill ha ett fält a med komponenterna 4.2, 3.6 och 7.2 (lagrade som double-tal) skriver vi i programmet: double[] a = 4.2, 3.6, 7.2}; Hakparenteserna efter double anger att det handlar om ett fält. När detta är gjort kan man plocka fram de tre komponenterna med hjälp av uttrycken a[0], a[1] resp. a[2]. Finessen är att man även kan låta indexet vara en variabel så att man kan tala om a[i] där i är en heltalsvariabel. Använd alltså denna teknik för att skapa två fält i ditt program, ett för linsernas positioner (x-koordinaten) och ett för linsernas brännvidder. 7.2 Utvidgning till flera ljusstrålar Om du har gjort allting rätt är det nu enkelt att komplettera programmet så att det ritar ut hur ett helt strålknippe bryts genom linserna. Det är lämpligt att rita ett 20-tal strålar, antingen med jämnt avstånd mellan k start-värdena eller (vilket är snyggare) med jämnt steg mellan vinklarna ut från lampan. 1 Det råder delade meningar om vad indexerbara variabler (engelskans array) skall kallas på svenska. Vi använder här beteckningen fält eftersom denna används i boken. Ofta kallas de istället vektorer. Båda beteckningarna är olyckliga eftersom de också har andra betydelser i datorsammanhang. 11

Figur 5: När programmet är färdigt ska det se ut på ungefär detta sätt på skärmen (men i färg). 8 Fjärde labbtillfället Vi ska nu komplettera programmet så att det ser lite snyggare ut. Dessutom ska vi införa metoder som anropas när användaren drar med musen så att man interaktivt kan flytta på lampan utan att behöva ändra i programmet. När du är klar ska programmet se ut ungefär som i figur 5. 8.1 Lägg till färger Det ser lite tråkigt ut med svarta ljusstrålar, eller hur? Det är egentligen ganska enkelt att rita med andra färger så varför inte fixa till programmet så att det ser mer tilltalande ut. Det är två saker vi behöver göra. För det första väljer vi en annan bakgrundsfärg, förslagsvis svart. Detta gör man en gång för alla genom att anropa en metod när programmet startar. För det andra väljer vi en lämplig färg varje gång något ska ritas. På detta sätt blir det enkelt att ha olika färger för koordinatsystemet, ljusstrålarna och linserna. När en applet startas anropas metoden init (om en sådan finns). init skall alltid definieras med följande huvud: public void init() Detta är en lämplig plats för att sätta bakgrundsfärgen. Varje gång man ska rita någonting bör man nu också välja vilken färg man ska rita med. Detta gör man genom att anropa metoden setcolor som finns i grafikobjektet. För att t.ex. rita vita linjer gör man såhär: g.setcolor(color.white); g.drawline(...); 12

På motsvarande sätt kan man fylla ovalerna med en färg, t.ex. blått g.setcolor(color.blue); g.filloval(...); Placera in dessa anrop på lämpliga platser i programmet så att det hela ser både tilltalande och tydligt ut på skärmen. 8.2 Gör det möjligt att flytta lampan Det sista tillägget till programmet är att vi vill låta användaren kunna flytta på lampan genom att helt enkelt dra med musen. För att klara detta måste vi komplettera programmet med metoder som tar hand om musklickningar eller musrörelser. Dessa kallas i Java för händelser (eng. events). Musklickningar och musrörelser är i själva verket olika händelser som också hanteras olika. Här är det faktiskt smartast att ta hand om musrörelser eftersom vi då kan få programmet att succesivt rita strålknippet medan användaren drar runt lampan (musklick-händelser känner bara av var musen är precis när man trycker ned musknappen). För att åstadkomma detta måste vårt program kompletteras med tre nyheter: 1. Ange att programmet förstår musförflyttningshändelser. 2. Ange att programmet ska få reda på alla musförflyttningar. 3. Skriva de två metoder som anropas vid musförflyttningar. Vi tar detta i tur och ordning. Allra först måste vi lägga in en extra importrad i filens början som anger att vi behöver tillgång till ett paket med klasser och gränssnitt som har med händelser (events) att göra: import java.awt.event.*; För att nu ange att programmet förstår musförflyttningshändelser måste inledningsraden kompletteras på detta sätt: public class Linser extends Applet implements MouseMotionListener Texten implements MouseMotionListener betyder att vi lovar att skriva de två metoder som krävs för att ta hand om musförflyttingshändelser. Nästa steg är att se till att programmet verkligen får reda på alla musförflyttningar. Detta gör man genom att anropa metoden addmousemotionlistener på detta sätt: addmousemotionlistener(this); 13

Detta skall ske när programmet startar och läggs därför lämpligen in i init-metoden tillsammans med valet av bakgrundsfärg. Nu återstår det egentliga arbetet: att skriva de två metoder som anropas vid musförflyttningar. Anledningen till att det behövs två metoder är att den ena (mousemoved) anropas när musen förflyttas utan att någon musknapp tryckts ned medan den andra (mousedragged) anropas när användaren håller musknappen nere. Metoderna skall definieras med följande huvuden: public void mousemoved(mouseevent e) respektive public void mousedragged(mouseevent e) Definiera dessa metoder så att de variabler som beskriver lampans position uppdateras när man drar musen med nedtryckt knapp. Man kan använda metoderna e.getx() och e.gety() för att få den aktuella positionen för musen (i heltalskoordinatsystemet). När du ändrat variablerna som bestämmer lampans positions måste du också se till att figuren ritas om. Du skall dock aldrig själv anropa paint-metoden, det är alltid Java-systemets uppgift. Använd istället metoden repaint() för att tala om för systemet att det är dags att rita om fönstret. Java-systemet kommer då att se till att din paint-metod anropas snarast möjligt. Har du nu gjort rätt ska du med musen kunna flytta på lampan och direkt se vart strålarna tar vägen genom linssystemet. Om du flyttar lampan till höger om den första linsen händer det konstiga saker (om du inte gjort något speciellt för att förhindra det). Det beror på att vi förutsatt att stålarna går igenom alla linserna. Det är inte så svårt att åtgärda men krävs inte för att du ska vara klar med labben. 8.3 Frivilliga tillägg Hoppa över linser som ligger till vänster om lampan. Gör det möjligt att med musen flytta även på linserna och att ändra deras styrka. Du kan t.ex. använda skift+klick för att skilja detta från flyttningar av lampan. Inför en diameter för varje lins och låt bli att bryta ljusstrålar som går utanför linsen. Rita linserna med en form som antyder styrkan. Observera att negativa linser motsvarar konkava ytor. 14