0HURP'DOJRULWPHU-DYDOD\RXW GXEEHOEXIIULQJPP ) UHOVQLQJ,QQHKnOO ²0HURP'DOJRULWPHU ²-DYDPHURPNRPSRQHQWHUOD\RXWGXEEHOEXIIULQJ PP.RRUGLQDWV\VWHPRFKNRRUGLQDWHU 9DQOLJHQMREEDUYLL&DUWHVLVNDNRRUGLQDWHU ² 9LVVDÃV\VWHPÃKDUÃRULJRÃQHUHÃWLOOÃYQVWHU ² DQGUDÃXSSHÃWLOOÃYQVWHU 9UOVGNRRUGLQDWHU ² buãgrpãnrruglqdwhuãylãdqyqghuãlãynudãdssolndwlrqhu ² +UÃEU\UÃYLÃLQWHÃRVVÃRPÃKXUÃYLONDÃSL[ODUÃSnÃVNUPHQÃVRPÃNRPPHU UHSUHVHQWHUDÃGHP 6NUPNRRUGLQDWHUHQKHWVNRRUGLQDWHU ² 'HÃNRRUGLQDWHUÃVRPÃYHUNOLJHQÃUHSUHVHQWHUDUÃSXQNWHUÃSnÃVNUPHQ HQKHWHQ 1RUPDOLVHUDGHNRRUGLQDWHU ² 2IWDÃQRUPDOLVHUDVÃNRRUGLQDWHUQDÃYLGÃ YHUVWWQLQJÃIUnQ YUOGVNRRUGLQDWHUÃLQQDQÃXWULWQLQJÃÃVNHU ² 1RUPDOLVHUDGHÃNRRUGLQDWHUÃGYVÃNRRUGLQDWHUÃWLOOK UDQGHÃ>Ã@ ² 'HWWDÃJ UÃDWWÃYLVVDÃWUDQVIRUPDWLRQHUÃNDQÃVNHÃREHURHQGHÃDYÃXWHQKHW - 2 - %M UQ(LGHUEFN 1
) QVWHURFKY\HU (WWI QVWHULI QVWHUKDQWHUDUPHQLQJEUXNDU RIWDGHODVLQLGHOY\HUYLHZSRUWV,YDUMHYLHZSRUWMREEDUPDQPHGHWWORNDOW NRRUGLQDWV\VWHPI QVWUHWKDURFNVnHWW NRRUGLQDWV\WHP - 3-9LVXDOLVHULQJVSLSHOLQH Konstruera scen i värdskoordinater Normaisera vykoordinaterna Modeering Översätt ti utritnings-koord Normaisera Vykoordinater Översätt värdskoordinater utritningskoordinatsystem (tex genom att ba vrida värskoordinatsystemet) Översätt ti respektive vys koordinater - 4 - %M UQ(LGHUEFN 2
«PHUJHQHUHOOW Konstruera grafiska modeer och programmera Omvanda objekten ti pixevärden Modeering Geometr. transf. Rastrering Visuaisering Vika objekt finns på skärmen, hur färgas och skuggas dom normaisera, kipp, ta bort skymda injer, skugga Rita ut, ta eventuet bort taggighet (antiaiasing) - 5 -.OLSSQLQJ 'npdqnrqvwuxhuduhwwi QVWHUDWWULWDL EUXNDUHOOHUNDQPDQRFNVnDQJH NOLSSUHNWDQJODU ² 'YVDQJHGRPRPUnGHQGUREMHNWHQVNDOOV\QDV 2EMHNWXWDQI UHOOHUGHOYLVXWDQI UµNOLSSVµPRWRPUnGHW - 6 - %M UQ(LGHUEFN 3
.OLSSRSHUDWLRQHU 9LEHK YHUNOLSSDERUWRPUnGHQVRPUXWDQI U HQYLVVWI QVWHU ² (OOHULEODQGPHUJHQHUHOODRPUnGHQ 2OLNDW\SHUDYNOLSSDOJRULWPHU ² 3XQNWNOLSSQLQJ ² /LQMHNOLSSQLQJ ² <WNOLSSQLQJ ².XUYNOLSSQLQJ ² 7H[WNOLSSQLQJ - 7 -.OLSSQLQJDYOLQMHVHJPHQWL' (QNOLSSDOJRULWPDYJ UYLONDSULPLWLYHUHOOHU GHODUDYGHPVRPVNDOOULWDVSnVNUPHQ - 8 - %M UQ(LGHUEFN 4
&RKHQ6XWKHUODQG 9LGHODULQVNUPHQLRPUnGHQNULQJHWWUHNWDQJXOUWI QVWHU 6QDEEDUXSSEHKDQGOLQJHQDYOLQMHVHJPHQWJHQRPDWWLQLWLDOW UHGXFHUDDQWDOHWVNUQLQJDUVRPPnVWHEHUNQDV 'HQI UVWDDOJRULWPHQVRPI UV NWHHUVWWDNRVWVDPPD PXOWLSOLNDWLRQHURFKGLYLVLRQHUPHGHQNRPELQDWLRQDY IO\WWDOVVXEWUDNWLRQRFKELWRSHUDWLRQHU 'HODXSSI QVWUHWLQLRRPUnGHQPLWWHUVWDI QVWUHWGHWLQUHDY NOLSSUHNWDQJHOQ 9DUMHWLOOGHODVXQLNELWDUVVHNYHQV ² UHVSHNWLYHÃELWÃVWnUÃI U 1001 över, under, höger, vänster 0001 0101 1000 0000 0100 1010 0010 0110-9 - DOJRULWPVNLVV *LYHWc1 = kod(p1)rfkc2 = kod(p2)gup1rfkp2 SXQNWHU c1 = c2 = 0 EnGDÃSXQNWHUQDÃLQQDQI UÃPLWWHUVWDÃI QVWUHW c1 0RFKc2 = 0HOOHUYLFHYHUVD HQÃSXQNWÃLQQHÃHQÃXWHÃNRGHQÃLQGLNHUDUÃYLONHQÃGHOÃVRPÃUÃXWDQI UÃRFK YLONHQÃVRPÃUÃLQQDQI U EHUNQDÃVNUQLQJÃRFKÃJ UÃRPÃPHGÃQ\ÃNRG c1 && c2 0ELWYLVWORJLVNWRFK EnGDÃSXQNWHUQDÃOLJJHUõSnÃVDPPDÃVLGDµ c1 && c2 = 0 EnGDÃSXQNWHUQDÃXWDQI UÃPHQÃSnÃROLNDÃVLGRU NROODÃVNUQLQJÃEHUNQDÃQ\ÃNRGÃRFKÃJ UÃRP - 10 - %M UQ(LGHUEFN 5
/LDQJ%DUVN\ 0HG&RKHQ6XWKHUODQGEHK YHUYLVSHFLDOEHKDQGOD YHUWLNDODOLQMHUSnIRUPHQy = mx + h /LDQJ%DUVN\XQGYLNHUSUREOHPHWJHQRPDWWDQYQGD SDUDPHWHUIRUPI UOLQMHUQDLVWOOHW p( α ) (1 α ) p + α = 1 8GHUV NαYUGHQLVNUQLQJDUPHGNOLSS\WDQ α1 α2 α3 α4 α1-11 - α3 p 2 α2 α4 XUVDPEDQGHQ x y w w min min x 1 1 + α x x NDQWH[αI UNOLSSQLQJPRW\ PD[ InVXU y w y max 1 α = y OLNDGDQDHNYDWLRQHUNDQInVIUnQGRPWUHDQGUD NDQWHUQD - 12 - w y + α y y max w max 0 α 1 %M UQ(LGHUEFN 6
Viket medför att det hea kan skrivas αp p p p p 1 2 3 4 k q k, = x, = x, = y, = y, k = 1,2,3,4 q q q 1 q 2 3 4 = x 1 = x = = y y 1 x w w max y max w min x w 1 min y 1 och för varje p k skijt från no α = q p k k - 13 - ([HPSHO - 14 - %M UQ(LGHUEFN 7
.OLSSQLQJPRWLFNHUHNWDQJXOUDI QVWHU %ngh/ldqj%duvn\vrfk&\uxv%hfnvdojrulwphu NDQHQNHOWXWYLGJDVWLOONOLSSQLQJPRWJHQHUHOOD NRQYH[DSRO\JRQHU ) UGHWWDQGDPnONDQNRQNDYDSRO\JRQHUYLG EHKRYRPYDQGODVWLOONRQYH[D &LUNODURFKDQGUDILJXUHUEHVNULYQDDYNXUYRUU P MOLJDPHQIRUGUDUIOHUEHUNQLQJDU - 15-2PYDQGOLQJDYNRQNDYDWLOONRQYH[DSRO\JRQHU V 6 E 6 E 1 V 1 V 2 E 5 V 5 E 2 E 4 V 3 E3 V4 Ta kryssprodukter för aa intiiggande kanter Om aa kanter har samma tecken så är poygonen konvex annars konkav (E 1 E 2 ) > 0 (E 2 E 3 ) < 0 (E 3 E 4 ) > 0 (E 4 E 5 ) > 0 (E 5 E 6 ) > 0 (E 6 E 1 ) > 0 Oika tecken atså konkav För att göra poygonen konvex spittar vi ängs första kanten som ger E 6 negativt tecken och vi får två poygoner E 1 V 1 V 2-16 - V 6 E 5 E 2 V 3 E3 V 5 E 4 V4 %M UQ(LGHUEFN 8
.OLSSQLQJDYSRO\JRQHU.OLSSPRWNDQWLNOLSSUHNWDQJHOQLWDJHW - 17-6XWKHUODQG+RGJHPDQ Föj kanterna på poygonen och kipp mot en kant i taget V 1 V 1 V 2 V 2 V 2 V 1 ut in spara V 1, V 2 V 3 in in spara V 3 V 4 V 3 V 3 in ut spara V 3 Förbättring: Vi kan eiminera vertexista genom att skicka vidare varje kant ti nästa "kippare" V 4 ut ut spara ingen - 18 - %M UQ(LGHUEFN 9
SUREOHP Kippning av konkava poygoner kan ge sammanhängande kanter som inte finns - 19 - :HLOHU$WKHUWRQ En ösning på föregående probem är att använda Weier-Athertons agoritm. om man går från en punkt utanför kipprektangen ti en innanför föjer man poygonkanten men föjer fönsterkanten medurs om man går innefrån och ut V 3 V 1 V 1 V 4 V 3 V 2 V 2-20 - %M UQ(LGHUEFN 10
$QGUDW\SHUDYREMHNW $QYQGI UVWRPVOXWDQGHUHNWDQJHOHOOHU XWVWUFNQLQJJHQHUHOOUHJHO.OLSSQLQJLIUDPHEXIIHUWHQ ² 2IWDVWEWWUHDWWNOLSSDLQQDQREMHNWHQLIUDPHEXIIHUWHQ ² EHK YVYDQOLJHQEDUDI UREMHNWDYW\SUDVWHU - 21 - /D\RXW LayoutManager BorderLayout GridBagLayout GridLayout CardLayout FowLayout - 22 - %M UQ(LGHUEFN 11
)ORZ/D\RXW ² UÃGHIDXOWÃI UÃ3DQHOREMHNW ² SODFHUDUÃNRPSRQHQWHUÃIUnQÃYQVWHUÃWLOOÃK JHUÃ9LGÃIXOOÃUDGÃVnÃQ\ÃUDG *ULG/D\RXW ² VHUÃWLOOÃDWWÃDOODÃNRPSRQHQWHUÃKDUÃVDPPDÃVWRUOHNÃ5XWQWÃUDGÃNROXPQ %RUGHU/D\RXW ² UÃGHIDXOWÃI UÃ:LQGRZNODVVHUÃH[Ã)UDPHÃRFKÃ'LDORJ ² 3ODFHUDUÃNRPSRQHQWHUÃLõYGHUVWUFNµ &DUG/D\RXW ² 3ODFHUDUÃREMHNWHQÃLÃHQõNRUWOHNµÃGUÃHQGDVWÃHWWÃNRUWÃLÃWDJHWÃV\QOLNW *ULG%DJ/D\RXW ² 0HVWÃJHQHUHOOÃRFKÃNRPSOH[Ã'HODUÃLQÃ\WDQÃLÃIOHUDÃFHOOHU ² $QYQGHUÃUHVWULNWLRQHUÃHQJÃFRQVWUDLQWVÃI UÃDWWÃEHVNULYD KXUÃNRPSRQHQWHUÃSODFHUDVÃVDPWÃGHUDVÃXWVWUFNQLQJ - 23 - ([HPSHO)ORZOD\RXW import java.awt.*; import java.appet.*; pubic cass DemoFowayout extends Appet { Button buttons[]; pubic void init() { super.init(); setlayout(new FowLayout()); buttons = new Button[10]; for (int i = 0; i < 10; i++) { buttons[i] = new Button("Knapp " + i); add(buttons[i]); - 24 - %M UQ(LGHUEFN 12
/D\RXWHQµI OMHUPHGµI UQGULQJDUDY I QVWHUVWRUOHN - 25 - ([HPSHO*ULGDO\RXW import java.awt.*; import java.appet.*; pubic cass DemoGridayout extends Appet { Button buttons[]; pubic void init() { super.init(); setlayout(new GridLayout(5, 2)); buttons = new Button[10]; for (int i = 0; i < 10; i++) { buttons[i] = new Button("Knapp " + i); add(buttons[i]); - 26 - %M UQ(LGHUEFN 13
([HPSHO%RUGHUOD\RXW import java.awt.*; import java.appet.*; pubic cass DemoBorderayout extends Appet { pubic void init() { super.init(); resize(300, 400); setlayout(new BorderLayout()); add("north", new Button("Knapp " + "Norr"));; add("south", new Button("Knapp " + "Söder"));; add("east", new Button("Knapp " + "Öster"));; add("west", new Button("Knapp " + "Väster"));; add("center", new Button("Knapp " + "Centrum"));; - 27-0HWRGHUI UDWWKDQWHUDNRPSRQHQWHU I UXWRPOD\RXWNDQNRPSRQHQWHURFNVnEOD ² YLVDVHOOHUG OMDV VHW9LVLEOHERROHDQ ² J UDVDNWLYDHOOHUSDVVLYD VHW(QDEOHGERROHDQ ² RPULWDVULWDVHOOHUPDUNHUDVVRP NRUUXSWDµ UHSDLQWÃSDLQW*UDSKLFVÃLQYDOLGDWH ² OD\RXWNDQDQJHVI UFRQWDLQHUEDVHUDGH ² I QVWHUNDQYLVDVOJJDVLI UHOOHUEDNJUXQGHQWLWHONDQDQJHV PP VKRZÃWR)URQWÃWR%DFN ² FXUVRUNDQQGUDV ² VWRUOHNNDQJHVWQNSnOD\RXWQXOO ² - 28 - %M UQ(LGHUEFN 14
%ODQGDWH[HPSHO import java.awt.*; import java.awt.event.*; pubic cass TestOfFrame extends Frame { pubic TestOfFrame(String s) { super(s); protected void deay(int ms) { // Vi måste ta hand om exceptions, viket görs med ett try-catch-par try{ Thread.currentThread().seep(ms); catch(exception e) { - 29 - protected void testlayoutes() { /* Lite urartat visar vi hur man kan fråga om komponenter. I det här faet vet vi att det är en Container och "kastar" */ Container pane = (Container) this.getcomponents()[0]; int deaytime = 3000; deay(deaytime); pane.setlayout(new GridLayout(5, 4, 10, 20)); this.settite("gridayout"); this.vaidate(); deay(deaytime); pane.setlayout(new FowLayout(FowLayout.LEFT, 7, 7)); this.settite("fowayout"); this.vaidate(); - 30 - %M UQ(LGHUEFN 15
Component[] panecomponents = pane.getcomponents(); for (int i = 0; i < panecomponents.ength; i++) { Component component = panecomponents[i]; component.setbounds((i % 5) * 40, i * 25, 50, 20); deay(deaytime); pane.setlayout(nu); this.settite("nu ayout"); this.vaidate(); - 31 - pubic static void main(string args []){ TestOfFrame frame = new TestOfFrame("Test of frame ayout"); Pane pane; frame.addwindowlistener(new WindowAdapter(){ pubic void windowcosing(windowevent e) { System.exit(0); ); frame.setsize(200, 300); frame.show(); // Vi skapar en pane för att automatiskt få objekten utpacerade med pane = new Pane(); frame.add(pane); - 32 - %M UQ(LGHUEFN 16
//Vi skapar några knappar for (int i = 0; i < 10; i++) { Button button = new Button("Button-" + new Integer(i).toString()); pane.add(button); // Aa knappar får bi "stängknappar" button.addactionlistener(new ActionListener() { pubic void actionperformed(actionevent e) {System.exit(0); ); /* För att ett nytt objekt ska visas på skärmen måste vi göra vaidate på framen (repaint eer invaidate hjäper inte! Bug??) */ frame.vaidate(); /* Vi skue ju kunna göra vaidate efter singan och visa aa nya knappar på en gång förstås! */ - 33 - //Vi skapar några fät for (int i = 0; i < 10; i++) { TextFied fied = new TextFied("Fied-" + new Integer(i).toString()); pane.add(fied); // Den här gången gör vi "det" efter singan frame.vaidate(); // Nu testar vi att ändra ayouten frame.testlayoutes(); - 34 - %M UQ(LGHUEFN 17
([HPSHO6WXGVDQGHEROODU import java.appet.*; import java.awt.*; /** An appet that dispays a simpe animation */ pubic cass BouncingCirce extends Appet impements Animation { int x = 150, y = 50, r=50; // position and radius of the circe int dx = 11, dy = 7; // trajectory of circe /** A timer for animation: ca our animate() method every 100 miiseconds. Creates a new thread. */ AnimationTimer timer = new AnimationTimer(this, 100); - 35 - /** Draw the circe at its current position */ pubic void paint(graphics g) { g.setcoor(coor.red); g.fiova(x-r, y-r, r*2, r*2); /** Move and bounce the circe and request a redraw. * The timer cas this method periodicay. */ pubic void animate() { // Bounce if we ve hit an edge. if ((x - r + dx < 0) (x + r + dx > bounds().width)) dx = -dx; if ((y - r + dy < 0) (y + r + dy > bounds().height)) dy = -dy; - 36 - %M UQ(LGHUEFN 18
// Move the circe. x += dx; y += dy; // Ask the browser to ca our paint() method to draw the circe at its new position. repaint(); /** Start the timer when the browser starts the appet */ pubic void start() { timer.start_animation(); /** Pause the timer when browser pauses the appet */ pubic void stop() { timer.pause_animation(); - 37 - /** This interface for objects that can be animated by an AnimationTimer */ interface Animation { pubic void animate(); /** The thread cass that periodicay cas the animate() method */ cass AnimationTimer extends Thread { Animation animation; // The animation object we re serving as timer for int deay; // How many miiseconds between "animation frames" pubic AnimationTimer(Animation animation, int deay) { this.animation = animation; this.deay = deay; - 38 - %M UQ(LGHUEFN 19
pubic void start_animation() { if (isaive()) super.resume(); ese start(); pubic void pause_animation() { suspend(); /** Loop forever, caing animate(), and then pausing the specified time. */ pubic void run() { for(;;) { animation.animate(); try { Thread.seep(deay); catch (InterruptedException e) { ; - 39 - ([HPSHO6WXGVDQGHEROODUPHGGXEEHOEXIIULQJ import java.appet.*; import java.awt.*; /* An appet that dispays a simpe animation using doubebuffering and cipping */ pubic cass SmoothCirce extends Appet impements Runnabe { int x = 150, y = 100, r=50; // Position and radius of the circe int dx = 8, dy = 5; // Trajectory of circe Dimension size; // The size of the appet Image buffer; // The off-screen image for doube-buffering Graphics buffergraphics; // A Graphics object for the buffer Thread animator; // Thread that performs the animation booean pease_stop; // A fag asking animation thread to stop - 40 - %M UQ(LGHUEFN 20
/** Set up an off-screen Image for doube-buffering */ pubic void init() { size = this.size(); buffer = this.createimage(size.width, size.height); buffergraphics = buffer.getgraphics(); - 41 - /** Draw the circe at its current position, using doubebuffering */ pubic void paint(graphics g) { // Draw into the off-screen buffer. buffergraphics.setcip(g.getcip()); // cear the buffer buffergraphics.setcoor(this.getbackground()); buffergraphics.firect(0, 0, size.width, size.height); buffergraphics.setcoor(coor.red); // draw the circe buffergraphics.fiova(x-r, y-r, r*2, r*2); // Then copy the off-screen buffer onto the screen g.drawimage(buffer, 0, 0, this); - 42 - %M UQ(LGHUEFN 21
/** Don t cear the screen; just ca paint() immediatey * It is important to override this method ike this for doube-buffering */ pubic void update(graphics g) { paint(g); /** The body of the animation thread */ pubic void run() { whie(!pease_stop) { // Bounce the circe if we ve hit an edge. if ((x - r + dx < 0) (x + r + dx > size.width)) dx = -dx; if ((y - r + dy < 0) (y + r + dy > size.height)) dy = -dy; // Move the circe. x += dx; y += dy; - 43 - /* Ask the browser to ca our paint() method to redraw the circe at its new position. Te repaint what portion of the appet needs be redrawn: the rectange containing the od circe and the the rectange containing the new circe. These two redraw requests wi be merged into a singe ca to paint() */ // repaint od position of circe repaint(x-r-dx, y-r-dy, 2*r, 2*r); // repaint new position of circe repaint(x-r, y-r, 2*r, 2*r); // Now pause 1/10th of a second before drawing the circe again. try { Thread.seep(100); catch (InterruptedException e) { ; animator = nu; - 44 - %M UQ(LGHUEFN 22
ÃÃ/** Start the animation thread */ pubic void start() { if (animator == nu) { pease_stop = fase; animator = new Thread(this); animator.start(); /** Stop the animation thread */ pubic void stop() { pease_stop = true; - 45 - /** Aow the user to start and stop the animation by cicking, Java 1.0 */ pubic booean mousedown(event e, int x, int y) { if (animator!= nu) pease_stop = true; ese start(); return true; - 46 - %M UQ(LGHUEFN 23