Δημοσιεύτηκε: 10 Ιουν 2009, 12:29
από Dimitris
Για να ξεφύγουμε λιγάκι από τις ψηφοφορίες και τις συζητήσεις---οι οποίες οφείλω να πω με κουράσανε αρκετά---είπα να γράψω κάτι διαφορετικό. Όλοι μας έχουμε παίξει παιχνίδια στον υπολογιστή ή σχεδιάσει διδιάστατα ή τρισδιάστατα με προγράμματα όπως το inkscape ή το qcad και θα έχουμε ακούσει για βιβλιοθήκες όπως η opengl. Τι κρύβεται πίσω από αυτά τα γραφικά; Απλές πράξεις όπως πρόσθεση και πολλαπλασιασμός. Bέβαια, κάποιες στοιχειώδη γνώσεις προγραμματισμού είναι απαραίτητες.

Στο παρόν νήμα θα συζητηθούν τα βασικά από τα γραφικά υπολογιστών. Καταρχήν να ξεχωρίσουμε τα γραφικά σε διανυσματικά (vector) και κυψελωτά (pixel ή raster). Τα διανυσματικά, με τα οποία θα ασχοληθούμε, παραμένουν αναλοίωτα--δεν αλλάζουν δηλαδή--όσες φορές κι αν τα μεγεθύνουμε (zoom in). Αντιθετα τα raster γραφικά, αρχίζουν και εμφανίζουν "τετραγωνάκια" που χαλάνε την ποιότητα της εικόνας.

Για την παρουσίαση των παραδειγμάτων θα χρησιμοποιηθεί το πρόγραμμα octave, μιας και δίνει αρκετές δυνατότητες τόσο υπολογιστές όσο και σχεδιασμού. Στο μέλλον θα υπάρξει, ελπίζω, και παράδειγμα με C-GTK+ και python-Tkinter, αλλά μέχρι τότε βλέπουμε.

Καταρχήν δημιουργούμε ένα φάκελο, ας τον ονομάσουμε vector-graphics όπου θα αποθηκεύουμε όλα τα αρχεία που θα δημιουργήσουμε. Ανοίγουμε το τερματικό και πηγαίνουμε στο φάκελο που μόλις δημιουργήσαμε, για παράδειγμα:
cd ~/Desktop/vector-graphics

και πληκτρολογούμε octave.

Θα ορίσουμε τώρα μια συνάρτηση, η οποία θα μας χρειαστεί αρκετά σε όσα κάνουμε στο μέλλον, και ονομάζεται συνάρτηση Bernstein προς τιμή του μαθηματικού που την ανακάλυψε. (Τα μαθηματικά αντικείμενα συνήθως ανακαλύπτονται και δεν εφευρίσκονται γιατί υπάρχουν εκεί έξω απλώς εμείς αγνοούμε την ύπαρξή τους)
Κώδικας: Επιλογή όλων
function b = bernstein(t, n, i)
b = nchoosek(n,i) * t.^i .* (1-t).^(n-i);
end

Η μεταβλητή t εδώ είναι διάνυσμα (ας μου βρει κάποιος μια ελληνική λέξη για την array, γιατί διάνυσμα είναι vector) H τελεία . πριν τα σύμβολα του πολλαπλασιασμού * και του εκθέτη ^ δηλώνει ότι οι πράξεις αυτές θα γίνονται για όλα τα στοιχεία του διανύσματος. Είναι ένας έμμεσος τρόπος να δηλωθεί ένας βρόχος. Η συνάρτηση nchoosek είναι η διωνυμική κατανομή (βλ. http://en.wikipedia.org/wiki/Binomial_coefficient)
Τώρα θα σχεδιάσουμε αυτή τη συνάρτηση. Πρώτα, ορίζουμε ένα γραμμικό σύνολο 100 σημείων:
Κώδικας: Επιλογή όλων
t = linspace(0, 1, 100);

μεταξύ 0 και 1. Όσο περισσότερα σημεία τόσο καλύτερη ανάλυση, από κάποιον αριθμό και πάνω μειώνεται η ταχύτητα φυσικά.
Κώδικας: Επιλογή όλων
b = bernstein(t, 3, 1);
plot(y, b)

Kαι έχουμε την (3,1) συνάρτηση Bernstein. O ακριβής συμβολισμός είναι B με εκθέτη 3 και δείκτη 1.

Oι καμπύλες Bezier ορίζονται ως ο γραμμικός συνδυασμός των b---τα λεγόμενα σημεία ελέγχου (control points)---και των συναρτήσεων Bernstein:
Κώδικας: Επιλογή όλων
function x = bezier(b, t, n, nsd)
x = zeros(length(t), nsd)
for i = 1:n
    tmp = bernstein(t, n-1, i-1);
    for j = 1:nsd
        x(:,j) = x(:,j) + b(i,j) * tmp(:);
    end
end
end


Στο inkscape για παράδειγμα σχεδόν όλα τα αντικείμενα είναι καμπύλες Bezier. Tα τετραγωνάκια που μπορούμε να μετακινήσουμε δεν είναι τίποτε άλλο από τα σημεία ελέγχου των καμπυλών Bezier. Aν ορίσουμε τώρα τα εξής δύο σύνολα σημείων:
Κώδικας: Επιλογή όλων
b = [0,0; 1,-0.075; 2,0; 3,0.1; 4,0.1];
x = bezier(b, t, 5, 2);
plot(x(:,1), x(:,2));

όπου 5 είναι το πλήθος των σημείων και 2 το πλήθος των διαστάσεων (ναι μπορούμε να ορίσουμε και τριδιάστατη καμπύλη) Αυτά επεκτείνονται και σε επιφάνειες όπου υπάρχουν σημεία ελέγχου της επιφάνειας.

Τώρα μπορούμε να γράψουμε τις συναρτήσεις bernstein και bezier σε δύο ξεχωριστά αρχεία με τα ονόματα bernstein.m και bezier.m αντίστοιχα και να τις χρησιμοποιούμε σε άλλα προγράμματα matlab.

ΥΓ. Όποιος ενδιαφέρεται παραπάνω για το θέμα ας το πει.