Matematiska Vetenskaper 21 april 2010 Matematik med Matlab för I 2010. Programmering i Matlab. 2- och 3-dimensionell grafik. LAB 2: Några geometriska uppgifter och plottning av figurer. Inledning 1 Programmering i MATLAB 1.1 Funktionsfiler Programering i matlab sker med hjälp av m-filer. Dessa filer skall ges namn som slutar med.m (t.ex. funk.m, kvadrat.m etc). Första raden i en funktionsfil inleds alltid med ordet function, sedan följer utparametrarna och därefter funktionsnamnet följt av inparametrarna: function[y1,y2,...,yn]=filnamn(x1,x2,...,xm) % kommentarer (gärna en beskrivning av funktionen) beräkningar/satser som beskriver funktionen. För att skriva en m-fil så behövs en bra texteditor, t.ex.matlabs egna, emacs. Exempel 1: function y=fun(x) % indata är variabeln x och utdata är y=x^2*(1-sin(x)) y=x.*x.*(1-sin(x)); Du kan kontrollera att filen finns i det aktuella biblioteket med kommandot what. Testa sedan filen med >>help fun >>fun(1) >>fun([1,2,3]) Skriv gärna kommentarer i M-filer. Exempel 2: function[]=m1vrid1(fi) % Funktioner ritar upp en pyramid med hörnen i (0,0,0), (1,0,0), (0,0,1) och (0,1,0) %Hörnet (1,0,0) markeras med en ring. %Pyramiden roteras kring x- och -axlarna med vinkel fi radianer, %samtidigt som den förstoras 1.01^100 i dessa axlars riktning %Förloppet spelas upp i en sekvens med 100 bilder. % %Indata: vinkeln fi %Inga utdata % X=[0,0,0;1,0,0;0 0 1;0 1 0;0 0 0;0 0 1;0 1 0;1 0 0]; plot3(x(:,1),x(:,2),x(:,3)) grid on %hold on V=diag([1.01,1.01,1.01]); Y=X; x=fi/100; S=[cos(x), -sin(x) 0;sin(x) cos(x) 0;0 0 1]; %Avbildnings matris för rotationen kring -axeln
sid. 2 av?? T=[1 0 0;0 cos(x) -sin(x);0 sin(x) cos(x)];%avbildnings matris för rotationen kring x-axeln for k=1:100 Y=(V*T*S*Y ) ; plot3(y(:,1),y(:,2),y(:,3), r ) hold on plot3(y(2,1),y(2,2),y(2,3), ob ) axis([-2 2-2 2-2 2]) pause(0.1) hold off Se nästa kapitel för kommandona i exemplet. 1.2 Villkor och val Den enklaste villkorsatsen ser ut så här: if vilkor instruktioner(satser) åtskilda av ; Innebörden är att satserna bara utförs om vilkoret är uppfyllt. T.ex. if sie(x)=[1 3] & sie(y)=[1 3] x=x ; y=y ; Villkorssatser kan ha en mer komplicerad form, t.ex. if vilkor satser1 else satser2 Om villkoret är uppfyllt kommer de första satser1 att utföras. I annat fall utförs satser2. 1.3 Inmatning och utmatning Ett MATLAB-program kan skriva ut text, data eller felmedelanden. Kommandot disp används för att beordra utskrift av en matris eller text. disp( Matrisen har egenvärdena ); disp([2 3]); ger utskriften Matrisen har egenvärdena 2 3 Med kommandot input får man programmet att stanna och vänta på att användare av programmet skall mata in ett tal/matris. Programraden a=input ( Mata in en vektor i rummet som kolonnvektor ) leder till att programmet skriver ut texten och väntar på användarens svar. Den inmatade vektorn blir sedan värdet på variabeln a. Man kan också temporärt stoppa programflödet med pause. Programexekvering fortsätter när användaren trycker på ett valfri knapp. en programrad som innehåller kommandot error får MATLAB att skriva ut ett felmeddelande och gå ur programmet. Exempel: error( Du får inte mata in en radvektor ) Det finns ett antal ytterligare kommandon för att styra hur program skall arbeta. För information se help lang.
sid. 3 av?? 2 Ritning av godtyckliga figurer Om x = (x 1, x 2,...,x n ) och y = (y 1, y 2,...,y n ) är två radvektorer av samma längd så kommer ritkommandot plot(x,y) att rita en kurva som sammanbinder punkterna (x 1, y 1 ),... (x n, y n ). Man kan dirigera på vilket sätt kurvan ritas genom att ge order om särskild linjetyp. Det går också att rita ut punkterna utan att sammanbinda dem genom att bestämma vilken punkttyp som skall användas. Här några exempel: >>x=-3:0.5:3; y=sin(x) >>plot(x,y) >>plot(x,y, : ) (Prickad kurva) >>plot(x,y, o ) (Punkterna som små cirklar) Om vi vill rita t.ex. en polygon kan vi skapa en koordinatmatris vars kolonner är koordinater för hörnen uppräknade i en lämplig ordning. Denna matris kan skrivas på något av följande sätt [ ] x P = = [ ] p y 1 p 2... p n x och y är då radvektorer av längd n av x- resp y-koordinatern för hörnpunkterna, medan p i är en kolonnvektor med kordinaterna för ett hörn. Vi ritar nu figuren genom att plotta x-koordinaterna mot y-koordinaterna med kommandot >> plot(p(1,:),p(2,:)) Pröva genom att rita figuren nedan! (0,1) (1,1) (0,0) (1,0) Allmän hjälp för tvådimensionell grafik får du under rubriken help plotxy.du kan bl.a. en förteckning av alla linjetyper och punkttyper som finns genom att kalla på help plot. För att rita 3-dimensionella figurer använder man kommandot plot3 istället. Om x = (x 1, x 2,...,x n ), y = (y 1, y 2,..., y n ), = ( 1, 2,..., n ) är tre vektorer av samma längd så kommer plot(x,y,) sammanbinda punkterna (x 1, y 1, 1 ),..., (x n, y n, n ). 2.1 Flera kurvor i samma figur Antag att vi vill rita fler grafer i samma bild. Vi kan rita först en graf med hjälp av kommandot >>plot(x,y) och sedan ge kommandot >>hold on Då kommer de gamla graferna att behållas när nya grafer ritas. När man inte längre vill behålla gamla kurvor ger man kommandot >>hold off 2.2 Dimensionering av koordinataxlarna Normalt väljer MATLAB ett koordinatsystem så att alla punkter som skall ritas syns på skärmen. Man kan styra valet av koordinataxlar med hjälp av kommandot axis. För att ta reda på hur axis fungerar skriv >>help axis Pröva följande exempel: >>x=0:0.1:pi; y=sin(x); plot(x,y) >>axis([-1 4-1 2])
sid. 4 av?? >>axis( off ) >>axis([0 pi 0 1] >>axis ( on ) >>axis(axis);hold on >>x=-1:0.1:2; y=cos(x); plot(x,y) >>hold off >>x=0:0.1:pi; y=sin(x); plot(x,y) 3 Uppgifter till Lab 2 Kommandon som kan vara till nytta i dessa uppgifter : norm beräknar längden av en vektor. sie beräknar antalet rader och kolonner i en matris. acos arcus-cosinus. dot beräknar skalärprodukten av två vektorer (alternativt: x *y om x och y är kolonnvektorer). Vinkeln mellan två vektorer Uppgift 1: Skriv en funktionsfil som beräknar vinkeln mellan två givna vektorer. Matematisk formel : x y = x y cosv Funktionsfil: function v=vinkel(x, y) Input : x,y - två vektorer Output : v - vinkeln mellan x och y. Programmet skall ge vinkeln mellan vektorerna mätt i radianer. Skriv gärna programmet så att det inte spelar någon roll om vektorerna matas in som kolonnvektorer eller som radvektorer. Testa funktionen på några olika par av vektorer. Det är klokt att bl.a. testa med vektorer där du vet svaret. Spegling Matematisk bakgrund : Låt planet π vara givet som Ax + By + C = D. Dividerar vi ekvationen med A 2 + B 2 + C 2, så får vi en ny ekvation ax + by + c = d, och en normalvektor n = (a, b, c) av längd 1. Tag en punkt med ortsvektorn x, och låt p och s vara ortsvektorn för ortogonala projektionen respektive speglingen av x i planet π. Om nu x 0 är ortsvektorn för en punkt i planet så ger projektionsformeln (Observera att x 0 n = d för en punkt på planet) För spegelpunkten gäller s = x + 2(p x), dvs p x = ((x 0 x) n)n = (x 0 n x n)n = (d x n)n s = x + 2(d x n)n Uppgift 2: Skriv ett program som gör följande: Givet planet Ax + By + C = D och en punkt x i rummet, beräkna spegelbilden s av x i planet. Funktionsfil: function s=spegel(x, A, B, C, D) Input : Punkten x och parametrarna i planets ekvation. Output : Spegelbilden s. För bästa anpassning till nästa uppgift, presentera alla förekommande vektorer som kolonnvektorer. Testa funktionerna på några lämpligt valda plan och punkter, för vilka man lätt kontrollerar att resultaten stämmer.
Ritning av godtyckliga figurer sid. 5 av?? Uppgift 3: Rita en triangel i planet. Välj hörn så att triangeln inte skärs av linjen x + 2y = 1 (byt gärna ut någon koordinat om någon vinkel är nära 180 ). Använd funktionen spegel i föregåe avsnitt för att bestämma figurens spegelbild i linjen x+2y = 1. Observera att spegling i plan ska bytas ut mot spegling i linje: välj C = 0 och mata in vektorn x med -koordinaten noll. Plotta linjen, figuren och dess spegelbild i samma figur. Kommandot axis equal efter plot är nödvändigt för att speglingen ska se korrekt ut. Rotationer av objekt i 3d Först lite om basbyte och linjära transformationer. Detta behandlas mera utförligt i Lay, avsnitt 4.7. I nästa uppgift behöver vi rotera rummets vektorer kring en fritt vald axel. Om denna axel är axeln är det lätt att hitta standardmatrisen M för denna vridning. Om rotationsaxeln är en annan, kan man byta till en annan ON-bas (f 1,f 2,f 3 ), där f 3 är en vektor i rotationsaxelns riktning. Antag att koordinaterna för en vektor u i standardbasen (e 1,e 2,e 3 ) heter (x, y, ) och i den nya basen (ξ, η, ζ), då är u = xe 1 + ye 2 + e 3 = ξf 1 + ηf 2 + ζf 3, vilket också kan skrivas x y = [ f 1 f 2 f 3 ] ξ η ζ = P ξ η ζ P kallas basbytesmatrisen och dess kolonner är de nya basvektorerna. Om nu T är en linjär transformation som i basen (f 1,f 2,f 3 ) har matrisen M, och om T(u) = x e 1 + y e 2 + e 3 = ξ f 1 + η f 2 + ζ f 3, så gäller x y = P ξ η = PM ξ η = PMP 1 x y ζ ζ Standardmatrisen för T är därför PMP 1. När kolonnerna i P är ON, blir P 1 = P T (ortogonalmatris).
sid. 6 av?? Beräkning av rotationsmatriser Matematisk bakgrund: y Låt r = x y vara ortsvektorn för en punkt i rummet. Sambandet r = Mr, där cosθ sinθ 0 M = sin θ cosθ 0 0 0 1 θ r r x ger då en vridning av r en vinkel θ kring -axeln (fig). Vi vill nu vrida en punkt kring en axel genom origo med riktningsvektor v = a b c. Vi byter till en ny lämplig (högerorienterad) ON-bas B = {f 1,f 2,f 3 } som väljs så att f 1 = u/ u, f 2 = w/ w, och f 3 = v/ v där u = b a 0, w = ac bc (a 2 + b 2 ) θ r r y Med P = [f 1 f 2 f 3 ] (basbytesmatrisen) så ges sambandet mellan nya och gamla koordinater av r = Pρ, där ρ = [r] B (koordinaterna för r i basen B). I denna bas så ges matrisen för rotationen av matrisen M ovan. Vi får x ρ = Mρ och r = Pρ = PMρ = PMP 1 r. Notera att eftersom kolonnerna i P utgör en ON-bas så är P 1 = P T. Multiplikation med matrisen R = PMP T ger således en vridning med vinkeln θ kring vektorn v. En samtidig vridning av flera ortsvektorer r 1,r 2,...,r n åstadkommes genom matrismultiplikation v y r θ r. R[r 1 r 2... r n ] = [r 1 r 2... r n] x
sid. 7 av?? Uppgift 4: a. Rotationsmatrisen Skriv en funktionsfil R=rotation(v, t) där v är den vektor som ger rotationsaxeln, t är den skalär som ger rotationsvinkeln och där R är den beräknade 3x3 rotationsmatrisen. Eventuell finputsning: Om v är parallell med -axeln, blir vektorn u enligt proceduren ovan lika med nollvektorn. Tillfoga en villkorssats som gör att programmet klarar även detta fall! b. En roterande kub Skriv en funktionsfil kub(v,t) som åstadkommer en roterande kub i grafikfönstret till MATLAB där rotationsaxeln ges av vektorn v och kuben vrids vinkeln t i varje litet rotationssteg. Någon utvariabel behövs inte, filen ska ju bara åstadkomma plottning. Tillverka en matris K vars kolonner är koordinatvektorerna för kubens hörn, skrivna i en sådan ordning att vi kan plotta kubens alla kanter. Mata in dessa vektorer som k 1,... k 8, bilda sedan K genom att räkna upp vektorerna i lämplig ordning K = [k1 k2...] (rita figur som stöd). För att inte missa någon kant måste vi ta med varje hörn (minst) två gånger. Vi ritar nu figuren genom att plotta x-koordinaterna mot y-koordinaterna med kommandot >> plot(k(1,:),k(2,:)) Genom att utelämna koordinaterna får vi kubens projektion på xy planet. Animationen blir snyggast om man låter kubens centrum ligga i origo. Programmet kan t.ex. bygga på en loop där man i varje steg vrider kuben exempelvis 1/100 varv, ritar (plotta kubmatrisens första rad mot den andra, precis som ovan) och ger kommandot drawnow eller pause( t) (se Matlab help!). Ange axis square efter plotkommandot. Mera om plottning av 3d-objekt Det handlar om att avbilda en projektion av objektet på ett plan. Ett enkelt sätt att göra detta är som rekommerades i ovanståe uppgift att välja xy-planet som projektionsplan. Man plottar då punkternas x-koordinater mot y-koordinaterna (-koordinaterna lämnas därhän). Eftersom man här kan välja rotationsaxel fritt, kan man ändå åstadkomma alla perspektiv på en roterande kub om man nöjer sig med att projicera på xy-planet. Annars finns i Matlab ett 3D-plot-kommando plot3. Kommandot i föregåe uppgift blir då istället >> plot3(k(1,:),k(2,:),k(:,3)) Den projektion som används här, innebär att linjer som är parallella också ser parallella ut i projektionen. I verkligheten ser man dock parallella linjer konvergera mot en punkt långt borta (t ex skenorna på ett järnvägsspår). Betraktar man kuben på lite håll, så påverkas parallelliteten ganska lite. Det ser alltså någorlunda realistiskt ut, om man tänker sig att kuben inte befinner sig alltför nära ögat. Däremot kan det vara svårt att se vad som är fram och bak på kuben, och en vanlig synvilla är att den plötsligt byter rotationsriktning. Detta kan avhjälpas genom att man märker en av kubens sidor, t ex genom att rita ut diagonalerna i den sidan. (Vill man åstadkomma nyss nämnda projektion med konvergerande linjer, kan detta åstadkommas med sk homogena koordinater. Man arbetar med 4 4 matriser - se Lay, avsnitt 2.7!).