418341 ภาคต้น 2552: การบ้าน 2
คำเืตือน: การบ้านนี้เป็นการบ้านที่ต้องเขียนโปรแกรมมาก และมีเวลาทำน้อย นอกจากนี้ยังต้องมีความรู้ภาษา C++ เป็นอย่างดี
ุถ้าคุณไม่มั่นใจว่าคุณมีความรู้ภาษา C++ ดีพอ คุณสามารถไปหาข้อมูลเพิ่มเติมได้จาก
นอกจากนี้ โค้ดที่ให้ไปในการบ้านนี้มีจำนวนมาก ผมได้อธิบายรายละิเอียดของโ้ด้ดพวกนี้ไปบางส่วนแล้วในเลคเชอร์วันที่ 19 และ 21 สิงหาคม การดู สไลด์ ประกอบการสอนจะช่วยคุณได้มาก
เนื้อหา
ดาวน์โหลดโค้ด
ขั้นแรกให้ดาวน์โหลดโค้ดจากงลิงนี้ก่อน: homework-02.zip หลัีงจากนั้นให้ขยายไฟล์แล้วเปิดไฟล์ด้วย homework-02.sln ด้วย Microsoft Visual Studio 2008 Express
ข้อ 1: Matrix
เมื่อเปิดไฟล์ homework-02.sln แล้วให้ปิด project ทั้งหมดแล้วเหลือ project เหล่านี้เอาไว้
- gtest
- problem0
- problem1
- problem1_test
โดยการปิดโปรเจคใ้้ห้ทำโดยคลิกขวาที่ชื่อโปรเจคแล้วเลือก Unload Project
หลังจากนั้นให้เปิด problem1.cpp ในโปรเจค problem1 แล้วเติมฟังก์ชันเหล่านี้ให้สมบูรณ์
Matrix4x4 Matrix4x4::identity()
- คืน identity matrix ขนาด 4 คูณ 4
Matrix4x4 Matrix4x4::translate(float x, float y, float z)
- คืน matrix ของการเลื่อนแกนขนานไปตามแกน x เท่ากับอาร์กิวเมนต์ x, ไปตามแกน y เท่ากับอาร์กิวเมนต์ y, และไปตามแกน z เท่ากับอาร์กิวเมนต์ z
Matrix4x4 Matrix4x4::translate_x(float x)
- คืน matrix ของการเลื่อนแกนขนานไปตามแกน x เท่ากับอาร์กิวเมนต์ x
Matrix4x4 Matrix4x4::translate_y(float y)
- คืน matrix ของการเลื่อนแกนขนานไปตามแกน y เท่ากับอาร์กิวเมนต์ y
Matrix4x4 Matrix4x4::translate_z(float z)
- คืน matrix ของการเลื่อนแกนขนานไปตามแกน z เท่ากับอาร์กิวเมนต์ z
Matrix4x4 Matrix4x4::scale(float x, float y, float z)
- คืน matrix ของการย่อขยายขนาดตามแกน x เท่ากับอาร์กิวเมนต์ x เท่า, ตามแกน y เท่ากับอาร์กิวเมนต์ y เท่า, และตามแกน z เท่ากับอาร์กิวเมนต์ z เท่า
Matrix4x4 Matrix4x4::scale_x(float x)
- คืน matrix ของการย่อขยายขนาดตามแกน x เท่ากับอาร์กิวเมนต์ x เท่า
Matrix4x4 Matrix4x4::scale_y(float y)
- คืน matrix ของการย่อขยายขนาดตามแกน y เท่ากับอาร์กิวเมนต์ y เท่า
Matrix4x4 Matrix4x4::scale_z(float z)
- คืน matrix ของการย่อขยายขนาดตามแกน z เท่ากับอาร์กิวเมนต์ z เท่า
Matrix4x4 Matrix4x4::rotate(float degrees, Vector3 axis)
- คืน matrix ของการหมุนเป็นมุม degrees องศา รอบแกน axis
Matrix4x4 Matrix4x4::rotate_x(float degrees)
- คืน matrix ของการหมุนเป็นมุม degrees องศา รอบแกน x
Matrix4x4 Matrix4x4::rotate_y(float degrees)
- คืน matrix ของการหมุนเป็นมุม degrees องศา รอบแกน y
Matrix4x4 Matrix4x4::rotate_z(float degrees)
- คืน matrix ของการหมุนเป็นมุม degrees องศา รอบแกน z
เมื่อเติมเสร็จเรียบร้อยแล้วให้ทดลอง compile ด้วยการกด F7
ถ้าคอมไพล์ผ่านให้เลือกโปรเจค problem1_test เป็น Startup Project โดยคลิกขวาที่ชื่อโปรเจค problem1_test แล้วเลือก Set as Startup Project หลังจากนั้นจึงลองรันมันด้วยการกด Ctrl+F5 ถ้าโปรแกรมคุณทำงานได้ถูกต้อง คุณจะผ่านการทดสอบที่เขียนไว้ใน problem1_test.cpp
ข้อ 2: Transform
หลังจากทำข้อ 1 เสร็จแล้ว ให้เปิดโปรเจค problem2 และ problem2_test ด้วยการคลิกขวาที่ชื่อโปรเจคแล้วเลือก Load Project
ในข้อ 2 นี้เราจะทำการ implement ฟังก์ชันสำหรับสร้าง instance ของคลาส Transform ซึ่งใช้แทน affine transformation ที่สำคัญใน computer graphics
คลาส Transform มีส่วนประกอบเป็น matrix ขนาด 4 คูณ 4 สาม matrix ได้แก่
- m เป็น matrix ของ transform
- mi เป็น inverse ของ m
- mit เป็น inverse transform ของ m (กล่าวคือเป็น transpose ของ mi)
ฟังก์ชันที่ต้ัองเติมให้สมบูรณ์อยู่ในไฟล์ชื่อ problem2.cpp ในโปรเจค problem2 มีดังต่อไปนี้
Transform Transform::identity()
- คืน Transform ที่แทน identity transformation
Transform Transform::translate(float x, float y, float z)
- คืน Transform ที่แทนการเลื่อนแกนขนานไปตามแกน x เท่ากับอาร์กิวเมนต์ x, ไปตามแกน y เท่ากับอาร์กิวเมนต์ y, และไปตามแกน z เท่ากับอาร์กิวเมนต์ z
Transform Transform::translate_x(float x)
- คืน Transform ที่แทนการเลื่อนแกนขนานไปตามแกน x เท่ากับอาร์กิวเมนต์ x
Transform Transform::translate_y(float y)
- คืน Transform ที่แทนการเลื่อนแกนขนานไปตามแกน y เท่ากับอาร์กิวเมนต์ y
Transform Transform::translate_z(float z)
- คืน Transform ที่แทนการเลื่อนแกนขนานไปตามแกน z เท่ากับอาร์กิวเมนต์ z
Transform Transform::scale(float x, float y, float z)
- คืน Transform ที่แทนการย่อขยายขนาดตามแกน x เท่ากับอาร์กิวเมนต์ x เท่า, ตามแกน y เท่ากับอาร์กิวเมนต์ y เท่า, และตามแกน z เท่ากับอาร์กิวเมนต์ z เท่า
Transform Transform::scale_x(float x)
- คืน Transform ที่แทนการย่อขยายขนาดตามแกน x เท่ากับอาร์กิวเมนต์ x เท่า
Transform Transform::scale_y(float y)
- คืน Transform ที่แทนการย่อขยายขนาดตามแกน y เท่ากับอาร์กิวเมนต์ y เท่า
Transform Transform::scale_z(float z)
- คืน Transform ที่แทนการย่อขยายขนาดตามแกน z เท่ากับอาร์กิวเมนต์ z เท่า
Transform Transform::rotate(float degrees, Vector3 axis)
- คืน Transform ที่แทนการหมุนเป็นมุม degrees องศา รอบแกน axis
Transform Transform::rotate_x(float degrees)
- คืน Transform ที่แทนการหมุนเป็นมุม degrees องศา รอบแกน x
Transform Transform::rotate_y(float degrees)
- คืน Transform ที่แทนการหมุนเป็นมุม degrees องศา รอบแกน y
Transform Transform::rotate_z(float degrees)
- คืน Transform ที่แทนการหมุนเป็นมุม degrees องศา รอบแกน z
เมื่อเติมเสร็จเรียบร้อยแล้วให้ทดลอง compile ด้วยการกด F7
ถ้าคอมไพล์ผ่านให้เลือกโปรเจค problem2_test เป็น Startup Project โดยคลิกขวาที่ชื่อโปรเจค problem1_test แล้วเลือก Set as Startup Project หลังจากนั้นจึงลองรันมันด้วยการกด Ctrl+F5 ถ้าโปรแกรมคุณทำงานได้ถูกต้อง คุณจะผ่านการทดสอบที่เขียนไว้ใน problem2_test.cpp
หมายเหตุ: เพื่อให้ข้อนี้ไม่ง่ายเกินไป ผมได้ลบฟังก์ชัน inverse ออกไปจาก matrix4x4.h คุณจะต้องหาทางหา inverse ของวัตถุต่างๆ เอาเอง
ข้อ 3: Mesh
เมื่อทำข้อ 3 เสร็จแล้วให้เปิดโปรเจค problem3 และ problem3_test
ในข้อนี้เราจะทำการ implement คลาส Mesh คุณสามารถดูรายละเอียดของคลาสนี้ได้จาก สไลด์
คุณสามารถแ้ก้ไข declaration ของคลาส Mesh ได้ในไฟล์ problem3.h แต่คุณไม่ควรแก้ลบ method ที่มีอยู่แล้วออกไปเนื่องจากโค้ดส่วนอื่นใช้ method เหล่านี้ อนึ่ง คลาส Mesh ที่ให้มาไม่มีฟีลด์ใดๆ อยู่เลย ฉะนั้นคุณจะต้องเพิ่มฟีลด์ที่เหมาะสมเข้าไปเอง
หลังจากแก้ไข declaration แล้วให้ไป implement method ต่างๆ ในไฟล์ problem3.cpp อย่าลืมว่าถ้าคุณเพิ่ม method ใดขึ้นมาคุณจะต้อง implement method นั้นด้วย
เมื่อคุณ implement คลาด Mesh เรียบร้อยแล้วให้ลองคอมไพล์ แล้วจึงเซต problem3_test เป็น Startup Project แล้วรัน ถ้าโปรแกรมคุณทำงานได้ถูกต้อง คุณจะผ่านการทดสอบที่เขียนไว้ใน problem3_test.cpp
ข้อ 4: อ่านไฟล์ .obj
ในข้อสี่ คุณจะทำการอ่านไฟล์ .obj เข้าใส่ในคลาส Mesh ที่เขียนไว้ในข้อ 3
คุณสามารถอ่านรูปแบบของไฟล์ .obj ได้ในเวบไซต์นี้: http://www.royriggs.com/obj.html