Indonesian (Bahasa Indonesia) translation by Keti Pritania (you can also view the original English article)
Terinspirasi oleh Prof. Wildberger dalam seri kuliah nya aljabar linear, aku berniat untuk mengimplementasikan ide-ide matematis dengan Flash. Kami tidak akan menyelidiki manipulasi matematika matriks melalui aljabar linear: hanya melalui vektor. Pemahaman ini, meskipun menipiskan keanggunan aljabar linear, sudah cukup untuk memulai kita ke beberapa kemungkinan menarik 2 x 2 matrix manipulasi. Secara khusus, kami akan menggunakannya untuk menerapkan berbagai efek penggunting, skewing, membalik dan skala gambar pada saat runtime.
Hasil akhir Tinjauan
Mari kita lihat hasil akhir yang akan kita upayakan. Tekan empat tombol arah - atas, bawah, kiri, kanan - untuk melihat beberapa efek yang dapat kita capai dengan transformasi affine.
Jika Anda hanya menggunakan tombol panah kiri dan kanan, ikan muncul untuk berenang di sekitar di ruang isometrik pseudo-3D.
Langkah 1: Ruang koordinat berbeda
Grafik digambar ke dalam ruang koordinat. Jadi untuk memanipulasi mereka, terutama untuk menerjemahkan, memutar, skala, memantulkan dan condong grafik, sangat penting bahwa kita memahami ruang koordinat. Kita umumnya memanfaatkan tidak hanya satu, tetapi beberapa ruang koordinat dalam satu proyek - ini berlaku tidak hanya untuk desainer menggunakan Flash IDE, tetapi juga untuk pemrogram menulis ActionScript.
Dalam Flash IDE ini terjadi setiap kali Anda mengonversi gambar Anda menjadi simbol MovieClip: setiap simbol memiliki asalnya sendiri.

Gambar di atas menunjukkan asal-usul tahap ' mengkoordinasikan ruang (titik merah), dan bahwa simbol ruang koordinat (pendaftaran titik yang ditandai oleh crosshair). Untuk mengetahui yang ruang Anda berada di saat ini, mengamati bilah di bawah timeline Flash IDE seperti yang ditunjukkan oleh gambar di bawah.

(Saya menggunakan Flash CS3, jadi lokasinya mungkin berbeda untuk CS4 dan CS5.) Yang ingin saya tekankan adalah adanya ruang koordinat yang berbeda, dan fakta bahwa Anda sudah terbiasa menggunakannya.
Langkah 2: Alasan
Sekarang ada alasan yang baik untuk ini. Kita dapat menggunakan satu ruang koordinat sebagai referensi untuk mengubah ruang koordinat lainnya. Ini mungkin terdengar asing, jadi saya sudah menyertakan presentasi Flash di bawah untuk memfasilitasi penjelasan saya. Klik dan seret panah merah. Main-main dengan itu.
Di latar belakang adalah kotak biru, dan di latar depan adalah kotak merah. Panah biru dan merah awalnya sejajar sepanjang x - dan y sumbu Flash mengkoordinasikan ruang, Pusat yang saya telah bergeser ke tengah panggung. Grid biru adalah grid referensi; gridlines tidak akan berubah saat Anda berinteraksi dengan panah merah. Grid merah, di sisi lain, dapat reoriented dan ditingkatkan dengan menyeret panah merah.
Perhatikan bahwa panah juga menunjukkan properti yang penting ini Grids. Mereka menunjukkan gagasan unit x dan y pada grid mereka masing-masing unit. Ada dua panah merah di kotak merah. Masing-masing menunjukkan panjang satu unit pada sumbu x dan sumbu y. Mereka juga menentukan orientasi ruang koordinat. Mari kita mengambil panah merah menunjuk sepanjang sumbu x dan memperluas hal itu terjadi dua kali selama panah asli (ditampilkan dengan warna biru). Mengamati gambar berikut.






Kita melihat bahwa gambar (kotak hijau) digambar di grid merah sekarang melebar horizontal, karena fakta bahwa kotak merah ini ditarik ke telah dua kali luas. Intinya aku mencoba membuat agak sederhana: Anda dapat menggunakan satu ruang koordinat sebagai dasar untuk mengubah ruang koordinat yang lain.
Langkah 3: Affine transformations ruang koordinat
Jadi apa adalah "ruang koordinat affine transformations"? Yah, aku yakin Anda berhati-hati untuk mengamati bahwa ruang ini koordinat tertarik menggunakan grids paralel. Mari kita mengambil ruang affine transformations merah misalnya: tidak ada jaminan bahwa sumbu x dan sumbu y yang selalu tegak lurus satu sama lain, tapi yakinlah bahwa namun Anda mencoba untuk men-tweak Panah, Anda tidak pernah akan tiba di sebuah kasus sebagai berikut.



Ruang koordinat ini bukanlah sebuah ruang koordinat affine transformations.
Pada kenyataannya, axes x dan y biasanya mengacu pada ruang koordinat Kartesius, seperti yang ditunjukkan di bawah ini.



Perhatikan bahwa kisi horizontal dan vertikal saling tegak lurus. Cartesian adalah jenis ruang koordinat affine, tetapi kita dapat mengubahnya ke ruang affine lain sesuai keinginan. Grid horisontal dan vertikal tidak selalu harus tegak lurus satu sama lain.



Contoh dari sebuah ruang koordinat affine transformations



Contoh lain dari ruang koordinat affine
Langkah 4: Transformasi Affine
Seperti yang sudah bisa Anda duga, transformasi affine adalah terjemahan, scaling, refleksi, membuat dan rotasi.



Ruang affine transformations asli



Ruang affine diskalakan



Tercermin affine transformations Ruang



Ruang affine transformations miring



Diputar dan skala affine transformations Ruang
Perlu dikatakan, sifat-sifat fisik seperti x, y, scaleX, scaleY dan rotasi tergantung pada ruang. Ketika kita membuat panggilan ke properti-properti, kami benar-benar adalah transformasi affine transformations koordinat.
Langkah 5: Pemahaman matriks
Saya berharap gambar yang ditampilkan di atas cukup jelas untuk pulang ide. Hal ini karena untuk programmer bekerja dengan FlashDevelop, kita tidak akan melihat mereka grid yang nyaman menampilkan Flash IDE untuk desainer. Semua ini harus hidup di kepala Anda.
Selain dari membayangkan grid ini, kita juga perlu untuk meminta bantuan matriks kelas. Dengan demikian, memiliki pemahaman matematika matriks penting, jadi kami akan merevisi operasi matriks berikut: penambahan dan perkalian.

Langkah 6: Geometris makna tambahan matriks
Matriks operasi convery makna geometris. Dengan kata lain, Anda dapat membayangkan apa yang mereka berarti pada grafik. Mari kita asumsikan bahwa kita memiliki empat poin dalam ruang koordinat kami dan ingin beralih mereka untuk satu set lokasi baru. Ini dapat dilakukan menggunakan matriks penambahan. Lihat gambar di bawah.



Seperti yang Anda lihat, kami sebenarnya menggeser seluruh ruang koordinat lokal (kotak merah) di mana keempat titik ini diambil. Notasi untuk melakukan operasi ini adalah seperti yang ditunjukkan di bawah ini:



Kita juga dapat melihat bahwa pergeseran ini dapat benar-benar diwakili menggunakan vektor (tx, ty). Mari kita membedakan vektor dan statis titik dalam koordinat ruang dengan kami menggunakan kurung dan kurung. Saya telah menulis ulang dalam gambar di bawah.



Langkah 7: ActionScript implementasi
Berikut ini adalah implementasi sederhana penambahan matriks. Memeriksa komentar:
public class Addition extends Sprite { public function Addition() { var m:Matrix = new Matrix(); //instantiate matrix m.tx = stage.stageWidth * 0.5; //shift in x m.ty = stage.stageHeight * 0.5; //shift in y var d:DottedBox = new DottedBox(); //create the custom graphic (dotted box is a Sprite) addChild(d); d.transform.matrix = m; //apply the matrix to our graphic } }
Langkah 8: Makna Geometris dari Penggandaan Matriks
Perkalian matriks agak lebih canggih dari matriks penambahan tapi Prof Wildberger elegan telah rusak itu ke penafsiran sederhana ini. Saya dengan rendah hati akan mencoba untuk mengulangi penjelasannya. Bagi mereka yang ingin menyelam lebih dalam ke pemahaman aljabar linear yang mengarah ke ini, memeriksa seri kuliah sang profesor.
Mari kita mulai dengan mengatasi kasus matriks identitas, saya.



Dari gambar di atas kita mengetahui bahwa mengalikan matrix sewenang-wenang, A, dengan matriks identitas, aku akan selalu menghasilkan A. Berikut adalah analogi: 6 x 1 = 6; matriks identitas disamakan dengan nomor 1 di perkalian itu.
Selain itu, kita dapat menulis hasil dalam format vektor berikut yang akan sangat menyederhanakan interpretasi kita:



Interpretasi geometris formula ini ditunjukkan dalam gambar di bawah.



Dari Cartesian grid (kiri grid), kita dapat melihat titik biru terletak di (2, 1). Sekarang jika kita ingin mengubah ini grid asli x dan y untuk grid baru (kanan grid) menurut satu set vektor (di bawah grid tepat), titik biru akan dipindahkan ke (2, 1) pada grid baru - tetapi ketika kita peta ini kembali ke grid asli , itu adalah titik yang sama seperti sebelumnya.
Karena kita mengubah asli grid ke grid lain yang saham vektor sama untuk x dan y, kita melihat ada perbedaan. Pada kenyataannya, perubahan x dan y dalam transformasi ini nihil. Ini adalah apa yang dimaksud dengan matriks identitas, dari sudut pandang geometris.
Namun, jika kita mencoba untuk melakukan pemetaan menggunakan transformasi lain, kita akan melihat beberapa perbedaan. Aku tahu itu bukan contoh paling mengungkapkan untuk memulai dengan, jadi mari kita beralih ke contoh lain.
Langkah 9: Scaling sepanjang X



Gambar di atas menunjukkan skala ruang koordinat. Memeriksa vektor x dalam ruang koordinat berubah: satu unit berubah x account untuk dua unit x asli. Pada ruang koordinat transformasi, koordinat titik biru masih (2, 1). Namun, jika Anda mencoba untuk peta ini koordinat dari berubah grid ke grid asli, itu adalah (4, 1).
Gagasan ini ditangkap oleh gambar di atas. Bagaimana rumus? Hasilnya harus konsisten; Mari kita periksa.
Saya yakin Anda ingat rumus ini. Sekarang, saya telah menambahkan makna mereka masing-masing.

Sekarang untuk memeriksa hasil numerik dari contoh penskalaan kami.
- Asli Koordinat: (2, 1)
- Vektor pada sumbu x yang ditransformasikan: (2, 0)
- Vektor pada sumbu berubah: (0, 1)
- Diharapkan hasil: (2 * 2 + 0 * 1, 0 * 2 + 1 * 1) = (4, 1)

Mereka setuju dengan satu sama lain! Sekarang kita gembira dapat menerapkan ide ini untuk transformasi lain. Tetapi sebelum itu, sebuah implementasi ActionScript.
Langkah 10: Implementasi ActionScript
Memeriksa pelaksanaan ActionScript (dan SWF yang dihasilkan) di bawah ini. Perhatikan bahwa salah satu kotak tumpang tindih yang membentang sepanjang x oleh skala 2. Saya telah menyoroti nilai-nilai penting. Nilai-nilai ini akan men-tweak di langkah kemudian untuk mewakili transformasi yang berbeda.
public class Multiplication extends Sprite { public function Multiplication() { var ref:DottedBox = new DottedBox(); //create reference graphic addChild(ref); ref.x = stage.stageWidth * 0.5; ref.y = stage.stageHeight * 0.5; var m:Matrix = new Matrix(); //instantiate matrix m.tx = stage.stageWidth * 0.5; //shift in x m.ty = stage.stageHeight * 0.5; //shift in y m.a = 2; m.c = 0; m.b = 0; m.d = 1; var d:DottedBox = new DottedBox(); //create the custom graphic addChild(d); d.transform.matrix = m //apply the matrix onto our graphic } }
Langkah 11: Skala X dan Y



Di sini kita telah turunkan grid dengan faktor dua sepanjang x - maupun y-axes. Titik biru adalah (2, 1) dalam grid asli sebelum transformasi, dan (4, 2) dalam grid asli setelah transformasi. (Tentu saja, hal ini masih di (2, 1) dalam grid baru setelah transformasi.)
Dan untuk mengonfirmasi hasil secara numerik ...

... mereka cocok lagi! Untuk melihat ini dalam implementasi ActionScript, cukup ubah nilai m.d
dari 1 menjadi 2.
(Perhatikan bahwa arah peregangan dari y adalah ke bawah, tidak ke atas, karena y akan menambahkan ke bawah di Flash tetapi ke atas di ruang koordinat Kartesius normal yang saya gunakan dalam diagram.)
Langkah 12: refleksi



Di sini kita telah merefleksikan kisi di sepanjang sumbu x menggunakan dua vektor ini, sehingga posisi titik biru di kisi asli berubah dari (2, 1) menjadi (-2, 1). Perhitungan numerik adalah sebagai berikut:

ActionScript implementasi adalah sama seperti sebelumnya, tetapi menggunakan ini nilai-nilai sebaliknya: m.a =-1, darinazrul = 0 untuk mewakili vektor untuk transformasi x, dan: m.c = 0 dan m. d = 1 untuk mewakili vektor untuk transformasi y.
Selanjutnya, apa tentang mencerminkan secara bersamaan di x dan y? Lihat gambar di bawah.



Juga, numerik dihitung dalam gambar di bawah ini.

Untuk implementasi ActionScript... Yah, saya yakin Anda tahu nilai untuk dimasukkan ke dalam matriks. m.a =-1, darinazrul = 0 untuk mewakili vektor untuk transformasi x; m.c = 0 dan m. d =-1 untuk mewakili vektor untuk transformasi y. Saya telah menyertakan SWF akhir di bawah ini.
Langkah 13: Skewing dan geser
Skewing dilengkapi dengan sedikit menyenangkan. Untuk kasus gambar di bawah, grid berubah memiliki sumbu-x yang reoriented dan skala. Bandingkan panah merah di grid kedua di bawah ini: mereka berbeda, tetapi sumbu y tetap tidak berubah.



Skewing
Secara visual, tampaknya bahwa distorsi yang terjadi di sepanjang y-arah. Ini benar karena sumbu x kita berubah sekarang memiliki y-komponen dalam vektor nya.
Numerik, ini adalah apa yang terjadi...

Dalam implementasi, saya telah terdaftar tweak di bawah ini.
m.a = 2
darinazrul = 1
m.c = 0
m.d = 1
Saya yakin pada titik ini Anda ingin mencoba berbagai hal sendiri, jadi lanjutkan dan atur
- orientasi sumbu berubah sambil mempertahankan sumbu-x
- orientasi kedua sumbu sama sekali
Saya telah menyertakan Flash keluaran kedua kasus sebagai berikut. Untuk pembaca yang ingin bantuan dengan nilai-nilai ini, periksa Multiplication_final.as di download sumber.
Langkah 14: Rotasi
Saya menganggap rotasi subset dari skewing. Satu-satunya perbedaan adalah bahwa dalam rotasi, besarnya unit x dan sumbu y dipertahankan, seperti Jual: perpendicularity antara dua sumbu.

ActionScript sebenarnya menyediakan metode di kelas Matrix
, rotate()
, untuk melakukan ini. Tapi mari kita lanjutkan ini.
Sekarang kita tidak ingin mengubah besarnya satuan panjang di x dan y dari grid asli; hanya untuk mengubah orientasi masing-masing. Kita dapat menggunakan trigonometri untuk tiba di hasilnya ditampilkan pada gambar diatas. Diberikan sudut roation,, kita akan mendapatkan hasil yang diinginkan dengan menggunakan vektor (cos a, dosa) untuk sumbu x dan (-dosa a, cos) untuk sumbu. Besarnya untuk setiap sumbu baru masih akan satu unit, tetapi setiap sumbu akan pada sudut, dibandingkan dengan aslinya.
Untuk pelaksanaan Actionscript, dengan asumsi bahwa sudut,, 45 derajat (yaitu 0,25 * Pi radian), hanya men-tweak matriks nilai-nilai berikut:
var a:Number = 0.25*Math.PI m.a = Math.cos(a); m.c = -1*Math.sin(a); m.b = Math.sin(a); m.d = Math.cos(a);
Sumber lengkap dapat dirujuk di Multiplication_final.as
.
Langkah 15: aplikasi
Memiliki sebuah interpretasi vektor 2 x 2 matriks membuka ruang bagi kita untuk mengeksplorasi. Penerapannya di memanipulasi bitmap (BitmapData, LineBitmapStyle, LineGradientStyle, dll) luas - tapi saya pikir saya akan menyimpan itu untuk tutorial lain. Untuk kasus artikel ini, kami akan berusaha untuk condong sprite kami pada saat run-time sehingga terlihat seperti itu benar-benar membalik dalam 3D.

Pandangan dunia isometrik pseudo-3D
Dari gambar di atas kita dapat melihat bahwa, dalam dunia dengan pandangan isometrik, salah grafis itu "berdiri" terus vektor sumbu yang berubah sedangkan vektor sumbu x adalah berputar. Dicatat bahwa satuan panjang untuk x - dan y sumbu tidak berubah - dengan kata lain, tidak ada skala harus terjadi di axis baik, hanya rotasi di sekitar sumbu-x.
Berikut ini contoh ide ini di Flash. Klik di mana saja di panggung dan mulai menyeret sekitar untuk melihat kemiringan ikan. Lepaskan untuk menghentikan interaksi Anda.
Berikut adalah sedikit penting ActionScript. Aku sudah menyoroti jalur penting yang menangani rotasi sumbu x. Anda juga dapat merujuk ke FakeIso.as.
private var f1:Fish, m:Matrix; private var disp:Point; private var axisX:Point, axisY:Point; public function FakeIso() { disp = new Point(stage.stageWidth * 0.5, stage.stageHeight * 0.5); m = new Matrix(); m.tx = disp.x; m.ty = disp.y; //displace to the center of stage f1 = new Fish(); addChild(f1); f1.transform.matrix = m; //apply transformation to onto fish axisX = new Point(1, 0); //vector for x - axis axisY = new Point(0, 1); //vector for y - axis stage.addEventListener(MouseEvent.MOUSE_DOWN, start); //start interaction stage.addEventListener(MouseEvent.MOUSE_UP, end); //end interaction } private function start(e:MouseEvent):void { f1.addEventListener(Event.ENTER_FRAME, update); } private function end(e:MouseEvent):void { f1.removeEventListener(Event.ENTER_FRAME, update); } private function update(e:Event):void { axisX.setTo(mouseX - f1.x, mouseY - f1.y); //determine orientation (but magnitude changed as well) axisX.normalize(1); //fix magnitude of vector with new orientation to 1 unit apply2Matrix(); //apply matrix onto fish } private function apply2Matrix ():void { m.setTo(axisX.x, axisX.y, axisY.x, axisY.y, disp.x, disp.y); f1.transform.matrix = m; }
Di sini, saya telah menggunakan kelas Point untuk menyimpan vektor.
Langkah 16: Tambahkan Keyboard kontrol
Dalam langkah ini, kita akan mencoba untuk menambahkan keyboard kontrol. Lokasi ikan akan memperbarui menurut kecepatan, velo. Kita akan menentukan langkah-langkah bertahap untuk rotasi (searah jarum jam) positif dan negatif rotasi (anti-searah jarum jam) juga.
velo = new Point(1, 0); //velo will be used to define x-axis axisY = new Point(0, 1); delta_positive = new Matrix(); delta_positive.rotate(Math.PI * 0.01); //positive rotation delta_negative = new Matrix(); delta_negative.rotate(Math.PI * -0.01); //negative rotation
Berdasarkan tekan tombol, velo akan memutar:
private function keyUp(e:KeyboardEvent):void { if (e.keyCode == Keyboard.LEFT) { velo = delta_negative.transformPoint(velo) //rotate velo counter-clockwise } else if (e.keyCode == Keyboard.RIGHT) { velo = delta_positive.transformPoint(velo) //rotate velo clockwise } }
Sekarang untuk setiap frame, kami akan berusaha untuk warna sisi depan ikan, dan ikan serta condong. Jika kecepatan, velo, memiliki besaran lebih dari 1 dan kita menerapkannya kepada matriks ikan, m, kita akan mendapatkan efek skala-sehingga untuk menghilangkan kemungkinan ini, kita akan menormalisasi kecepatan dan kemudian hanya menerapkan bahwa ikan matriks.
private function update(e:Event):void { var front_side:Boolean = velo.x > 0 //checking for the front side of fish if (front_side) { f1.colorBody(0x002233,0.5) } //color the front side of fish else f1.colorBody(0xFFFFFF,0.5) //white applied to back side of fish disp = disp.add(velo); //update current displacement with velocity var velo_norm:Point = velo.clone(); //in case velo > 0, we need to recalculate 1 unit of length for x. velo_norm.normalize(1); //note that x-axis more than 1 will perform scaling. We dont want that for now m.setTo(velo_norm.x, velo_norm.y, axisY.x, axisY.y, disp.x, disp.y); f1.transform.matrix = m; }
Langkah 17: Ikan Anda
Klik panggung, lalu tekan tombol panah kiri dan kanan untuk melihat membuat ikan mengubah arah.
Langkah 18: Lain Keyboard kontrol
Untuk barang-barang rempah, mari kita memungkinkan kontrol vektor sumbu juga.
private function keyUp(e:KeyboardEvent):void { if (e.keyCode == Keyboard.LEFT) { velo = delta_negative.transformPoint(velo) } else if (e.keyCode == Keyboard.RIGHT) { velo = delta_positive.transformPoint(velo) } if (e.keyCode == Keyboard.UP) { axisY = delta_negative.transformPoint(axisY) } else if (e.keyCode == Keyboard.DOWN) { axisY = delta_positive.transformPoint(axisY) } }
Juga untuk menentukan sisi depan dari ikan, kita sekarang perlu memasukkan sumbu y di. Berikut adalah kode untuk itu:
var front_side:Boolean = velo.x * axisY.y > 0 if (front_side) { f1.colorBody(0x002233,0.5) } else f1.colorBody(0xFFFFFF,0.5)
Langkah 19: Ikan Anda tidak-jadi-reguler
Yah, untuk beberapa hasil mengendalikan kedua sumbu mungkin terbukti menjadi sedikit membingungkan, tapi intinya adalah bahwa Anda sekarang dapat condong ikan Anda, menerjemahkan, mencerminkan dan bahkan memutar itu! Mencoba combo dari atas + kiri, up + kanan, ke kiri, bawah + kanan.
Juga, lihat jika Anda dapat mempertahankan "front" sisi ikan (ikan akan berwarna abu). Petunjuk: Tekan terus, kemudian meninggalkan, kemudian turun, lalu kanan. Anda membuat rotasi!
Kesimpulan
Saya harap Anda menemukan matriks matematika aset berharga untuk proyek-proyek Anda setelah membaca artikel ini. Saya berharap untuk menulis sedikit lebih di aplikasi 2 x 2 matriks dalam sedikit Tips cepat yang bercabang dari artikel ini, dan pada Matrix3d yang penting untuk manipulasi 3D. Terima kasih untuk membaca, terima kasih.