Transcript Document

01418341 สภาพแวดล ้อมการทางาน
คอมพิวเตอร์กราฟิ กส ์
การบรรยายครัง้ ที่ 2
ประมุข ขันเงิน
[email protected]
CULLING
Culling
• รูปหลายเหลีย
่ มมีสองหน ้า: ด ้านหน ้า กับ
ด ้านหลัง
• เวลาวาดรูปทรงสามมิต ิ สว่ นมากด ้านหน ้าจะหัน
หน ้ามาหาเรา
• ฉะนัน
้ โดยมากไม่มค
ี วามจาเป็ นต ้องวาดรูป
เหลีย
่ มทีห
่ น
ั หลังใสเ่ รา
– ชว่ ยให ้โปรแกรมเร็วขึน
้
่ มองเห็นภาพ
– ชว่ ยทาเอฟเฟกต์บางอย่าง เชน
ภายนอกจากภายในวัตถุ
• เราสามารถสงั่ ให ้ OpenGL ไม่วาดรูปหลาย
glCullFace
• glCullFace(GLenum mode)
– กาหนดรูปแบบการ cull รูปหลายเหลีย
่ ม
– mode มีคา่ ได ้สามแบบ
• GL_FRONT = ไม่วาดด ้านหน ้า
• GL_BACK = ไม่วาดด ้านหลัง
• GL_FRONT_AND_BACK = ไม่วาดทัง้ สองด ้าน
– ห ้ามเรียกใน glBegin(…) และ glEnd()
– ก่อนการทา culling จะมีผล จะต ้องสงั่
ี ก่อน
glEnable(GL_CULL_FACE) เสย
– ยกเลิกการทา culling (วาดหมดทุกด ้าน) โดยการสงั่
glDisable(GL_CULL_FACE)
แล ้วอะไรคือด ้านหน ้า อะไรคือ
ด ้านหลัง?
• โดยปกติ รูปหลายเหลีย
่ มทีเ่ รามองแล ้วเห็นจุด
ิ ถือว่าหัน
มุมเรียงกันตามแนวทวนเข็มนาฬกา
“ด ้านหน ้า” ให ้เรา
ิ ถือว่าหัน
• ถ ้าเห็นจุดมุมเรียงกันตามเข็มนาฬกา
“ด ้านหลัง” ให ้
• แต่เราสามารถเปลีย
่ นได ้ ด ้วย glFrontFace
– glFrontFace(GL_CCW) = ถือว่า “ทวนเข็ม” เป็ น
ด ้านหน ้า
– glFrontFace(GL_CW) = ถือว่า “ตามเข็ม” เป็ น
ด ้านหน ้า
ดู demo
ANIMATION WITH GLUT
สร ้างภาพเคลือ
่ นไหวด ้วย GLUT
• เราสามารถสร ้างภาพเคลือ
่ นไหวโดยการวาด
ภาพใหม่เป็ นระยะๆ
• กล่าวคือ ทุกชว่ งเวลาจากัด เราจะต ้องมีการ
ั ทีเ่ ราให ้ไปใน glutDisplayFunc ใหม่
เรียกฟั งก์ชน
– ถ ้าต ้องการความเร็วประมาณ 30 เฟรม/วินาที (ลืน
่
้ ้) ต ้องมีการเรียกฟั งก์ชน
ั นีท
ไหลพอใชได
้ ก
ุ ๆ 33
มิลลิวน
ิ าที
– ถ ้าต ้องการความเร็วประมาณ 60 เฟรม/วินาที (ลืน
่
ั นีท
ไหลมากๆ) ต ้องมีการเรียกฟั งก์ชน
้ ก
ุ ๆ 17
มิลลิวน
ิ าที
ั display
แล ้วจะเรียกฟั งก์ชน
อย่างไร?
้
• เรียกตรงๆ ความจริงก็ได ้อยู่ แต่มันจะไปซ้าซอน
กับการเรียกใน glutMainLoop
ั
• เราสามารถสงั่ ให ้ glutMainLoop เรียกฟั งก์ชน
display ได ้ด ้วยคาสงั่ glutPostRedisplay()
• glutPostRedisplay()
ั ทีใ่ ห ้ไป
– บอก GLUT ว่าเราต ้องการให ้มันเรียกฟั งก์ชน
กับ glutDisplayFunc ในลูปครัง้ ต่อไป
– ถ ้าเรียก glutPostRedisplay หลายครัง้ ก่อนลูปต่อไป
ั display จะถูกเรียกเพียงครัง้ เดียว
ฟั งก์ชน
แล ้วจะเรียก glutPostRedisplay
ทุกๆ X มิลลิวน
ิ าทีได ้อย่างไร?
• glutTimerFunc(unsigned int msecs,
void (*func)​(int value), value)
ั func ทีใ่ ห ้มาเป็ น argument ทีส
– เรียกฟั งก์ชน
่ อง
หลังจากเวลาผ่านไปได ้ msecs มิลลิวน
ิ าที
– func จะได ้รับ value ทีใ่ ห ้มาเป็ น argument ที่ 3 เป็ น
argument
– จะเรียก func เพียงครัง้ เดียวเท่านัน
้
– ดังนัน
้ ถ ้าต ้องการให ้เรียกเป็ นคาบๆ ใน func จะต ้องมี
การเรียก glutTimerFunc ให ้ตัวเองใหม่
ตัวอย่าง 1
void printInt(int value)
{
printf("Got an integer: %d\n", value);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutCreateWindow("glutTimerFunc Example 01");
glutDisplayFunc(display);
glutTimerFunc(2000, printInt, 123);
glutTimerFunc(3000, printInt, 456);
glutTimerFunc(4000, printInt, 789);
glutMainLoop();
}
ตัวอย่าง 2
void printAndReschedule(int interval)
{
printf("I'm printing this every %d milliseconds\n", interval);
glutTimerFunc(interval, printAndReschedule, interval);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutCreateWindow("glutTimerFunc Example 01");
glutDisplayFunc(display);
glutTimerFunc(0, printAndReschedule, 500);
glutTimerFunc(0, printAndReschedule, 1000);
glutTimerFunc(0, printAndReschedule, 2000);
glutMainLoop();
}
ANIMATION &
MVC DESIGN PATTERN
หลักการทา animation แบบ
Model-View-Controller
• เราแบ่งโปรแกรมของเราออกเป็ นสามสว่ น
– Model = สว่ นทีจ
่ ัดการกับข ้อมูล ในทีน
่ ค
ี้ อ
ื โมเดล
สามมิตห
ิ รือสองมิตท
ิ เี่ ราต ้องการแสดง
– View = สว่ นทีน
่ าโมเดลไปแสดง
– Controller = สว่ นทีท
่ าการเปลีย
่ นแปลงโมเดล ซงึ่
อาจเป็ นผลมาจากเวลาทีผ
่ า่ นไป หรือการสงั่ งาน
ของผู ้ใช ้
ั เจน
• มีการแบ่งหน ้าทีก
่ น
ั ชด
– Controller ทาหน ้าทีเ่ ปลีย
่ นแปลงโมเดลอย่างเดียว
ไม่มห
ี น ้าทีแ
่ สดง
– View ทาหน ้าทีแ
่ สดงโมเดลอย่างเดียว ไม่ม ี
เปลีย
่ นแปลงโมเดลเอง
หลักการทา animation แบบ
Model-View-Controller (ต่อ)
์ ใี่ ช ้ GLUT ของเรา
• ในโปรแกรมกราฟฟิ กสท
– Model = สว่ นทีเ่ ก็บข ้อมูลต่างๆ
– View = callback ของ glutDisplayFunc
– Controller = callback function อืน
่ ๆ
• callback ของ glutTimerFunc
้ ้ keyboard หรือ mouse
• callback สาหรับเวลาผู ้ใชใช
Animation ลูกบอลเด ้งกระทบ
กาแพง
• Model
– ข ้อมูลของลูกบอล
– ตาแหน่งของจุด
ศูนย์กลางลูกบอล
– ความเร็วของลูกบอล
– รัศมี
– สี
• ข ้อมูลลูกบอลควร
ประกาศไว ้เป็ น global
variable เพือ
่ ทีจ
่ ะได ้ใช ้
ั
ร่วมกันได ้หลายฟั งก์ชน
struct Ball
{
double x, y;
double vx, vy;
double radius;
double r, g, b;
};
Ball ball;
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
• View
– วาดลูกบอลเป็ นวงกลมทึบด ้วย OpenGL
void drawBall(Ball &b)
{
glColor3d(b.r, b.g, b.b);
glBegin(GL_TRIANGLE_FAN);
glVertex2d(b.x, b.y);
for(int i=0;i<CORNERS;i++)
{
double theta = 2*M_PI*i/CORNERS;
double x = b.x + b.radius * cos(theta);
double y = b.y + b.radius * sin(theta);
glVertex2d(x,y);
}
glVertex2d(b.x + b.radius, b.y);
glEnd();
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
• View (ต่อ)
ั
– สงั่ ให ้วาดลูกบอลใหม่ทก
ุ ครัง้ ทีม
่ ก
ี ารเรียกฟั งก์ชน
display
void display()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
drawBall(ball);
glFlush();
}
int main(int argc, char **argv)
{
...
glutDisplayFunc(display);
...
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
• Controller
– ทาให ้ลูกบอลเปลีย
่ นตาแหน่ง
็ ว่าลูกบอลชนกาแพงหรือไม่
– เชค
– ถ ้าชน ให ้เปลีย
่ นทิศทางการเคลือ
่ นทีข
่ องมันด ้วย
การเปลีย
่ นความเร็ว
ั ทีท
• ฟั งก์ชน
่ าหน ้าทีเ่ ป็ น controller จะถูกเรียก
เป็ นชว่ งๆ
– ใช ้ glutTimerFunc
– ต ้องลงทะเบียนตัวเองกับ glutTimerFunc ใหม่ทก
ุ
ครัง้ ทีถ
่ ก
ู เรียก
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void updateBall(Ball &b)
{
b.x += b.vx;
b.y += b.vy;
if (b.x + b.radius > 1)
{
b.x = 1 - b.radius;
b.vx = -fabs(b.vx);
}
if (b.x - b.radius < -1)
/* handle collision with left wall */
if (b.y + b.radius > 1)
/* handle collision with top wall */
if (b.y - b.radius < -1)
/* handle collision with bottom wall */
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void updateBall(Ball &b)
{
b.x += b.vx;
เคลือ
่ นทีล
่ ก
ู บอล
b.y += b.vy;
if (b.x + b.radius > 1)
{
b.x = 1 - b.radius;
b.vx = -fabs(b.vx);
}
if (b.x - b.radius < -1)
/* handle collision with left wall */
if (b.y + b.radius > 1)
/* handle collision with top wall */
if (b.y - b.radius < -1)
/* handle collision with bottom wall */
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void updateBall(Ball &b)
{
b.x += b.vx;
b.y += b.vy;
if (b.x + b.radius > 1)
{
b.x = 1 - b.radius;
b.vx = -fabs(b.vx);
}
if (b.x - b.radius < -1)
/* handle collision
if (b.y + b.radius > 1)
/* handle collision
if (b.y - b.radius < -1)
/* handle collision
}
็ ว่าชนกับกาแพงด ้านขวาหรือไม่
เชค
with left wall */
with top wall */
with bottom wall */
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void updateBall(Ball &b)
{
b.x += b.vx;
b.y += b.vy;
if (b.x + b.radius > 1)
{
b.x = 1 - b.radius;
b.vx = -fabs(b.vx);
}
if (b.x - b.radius < -1)
/* handle collision
if (b.y + b.radius > 1)
/* handle collision
if (b.y - b.radius < -1)
/* handle collision
}
้
ถ ้าชนให ้เปลีย
่ นทิศทางให ้วิง่ ไปด ้านซาย
with left wall */
with top wall */
with bottom wall */
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void updateBall(Ball &b)
{
b.x += b.vx;
b.y += b.vy;
if (b.x + b.radius > 1)
{
b.x = 1 - b.radius;
b.vx = -fabs(b.vx);
}
if (b.x - b.radius < -1)
/* handle collision with left wall */
if (b.y + b.radius > 1)
/* handle collision with top wall */
if (b.y - b.radius < -1)
/* handle collision with bottom wall */
}
โค ้ดของด ้านอืน
่ ๆ
ก็คล ้ายๆ กัน
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void animate(int param)
{
updateBall(ball);
glutTimerFunc(INTERVAL, animate, 0);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
...
glutTimerFunc(0, animate, 0);
...
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void animate(int param)
{
่ นโมเดลของลูกบอล (ทาให ้มันเคลือ
่ นที)่
updateBall(ball); เปลีย
glutTimerFunc(INTERVAL, animate, 0);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
...
glutTimerFunc(0, animate, 0);
...
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void animate(int param)
{
ั นีใ้ หม่อก
สงั่ ให ้เรียกฟั งก์ชน
ี ครัง้
updateBall(ball);
หลังจากเวลาผ่านไป
glutTimerFunc(INTERVAL, animate, 0); INTERVAL มิลลิวน
ิ าที
glutPostRedisplay();
}
int main(int argc, char **argv)
{
...
glutTimerFunc(0, animate, 0);
...
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void animate(int param)
{
updateBall(ball);
glutTimerFunc(INTERVAL, animate, 0);
glutPostRedisplay(); สงั่ ให ้วาดทัง้ ฉากใหม่
}
int main(int argc, char **argv)
{
...
glutTimerFunc(0, animate, 0);
...
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
void animate(int param)
{
updateBall(ball);
glutTimerFunc(INTERVAL, animate, 0);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
...
glutTimerFunc(0, animate, 0);
...
}
ลงทะเบียนให ้เรียก animate
เป็ นครัง้ แรกหลัง glutMainLoop
เริม
่ ทางาน (แล ้วมันจะจัดการให ้มัน
ถูกเรียกครัง้ ต่อๆ ไปเอง)
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutInitWindowSize(600,600);
glutCreateWindow("Bouncing Ball");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutTimerFunc(0, animate, 0);
ball.x = 0;
ball.y = 0;
ball.vx = 0.02;
ball.vy = 0.03;
ball.radius = 0.05;
ball.r = 1.0;
ball.g = 0.5;
ball.b = 0.5;
glutMainLoop();
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutInitWindowSize(600,600);
glutCreateWindow("Bouncing Ball");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutTimerFunc(0, animate, 0);
ball.x = 0;
ball.y = 0;
ball.vx = 0.02;
ball.vy = 0.03;
ball.radius = 0.05;
ball.r = 1.0;
ball.g = 0.5;
ball.b = 0.5;
glutMainLoop();
}
เริม
่ ต ้น GLUT
สร ้างวินโดว์
ั
ลงทะเบียนฟั งก์ชน
ฯลฯ
Animation ลูกบอลเด ้งกระทบ
กาแพง (ต่อ)
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutInitWindowSize(600,600);
glutCreateWindow("Bouncing Ball");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutTimerFunc(0, animate, 0);
ball.x = 0;
ball.y = 0;
ball.vx = 0.02;
ball.vy = 0.03;
ball.radius = 0.05;
ball.r = 1.0;
ball.g = 0.5;
ball.b = 0.5;
glutMainLoop();
}
กาหนดค่าเริม
่ ต ้นของลูกบอล
ดู demo
DOUBLE BUFFERING
Flickering
• ทาไมภาพมันกระพริบๆ (ภาษาฝรั่งเรียกว่า
flickering)
• จอภาพจะแสดงภาพใหม่เป็ นชว่ งๆ (สว่ นมาก
ความถีอ
่ ยูท
่ ี่ 60-72 เฮริ ต
์ ซ)์
• เวลาจอภาพ มันจะไปเอาข ้อมูลมาจาก
framebuffer
• การวาดภาพของเรามีหลายขัน
้ ตอน
ี า
– ล ้าง framebuffer ให ้เป็ นสด
– วาดลูกบอลทีละกลีบ
• เพราะฉะนัน
้ ข ้อมูลใน framebuffer บางเวลาจึง
่ าพทีส
ไม่ใชภ
่ มบูรณ์
Double Buffering
แก ้ไขได ้โดยการให ้มี framebuffer สองอัน
อันหนึง่ อยูห
่ ลัง อันหนึง่ อยูห
่ น ้า
เวลาวาดให ้วาดใส่ framebuffer ทีอ
่ ยูข
่ ้างหลัง
เวลาแสดงให ้เอา framebuffer ทีอ
่ ยูข
่ ้างหลังไป
แสดง
• ภาพทีแ
่ สดงจึงเป็ นภาพทีส
่ มบูรณ์เสมอ
• ไม่เกิด flickering
•
•
•
•
การใช ้ double buffering ใน GLUT
• ใช ้ GLUT_DOUBLE แทน GLUT_SINGLE ใน
glutInitDisplayMode
• ใช ้ glutSwapBuffers() แทน glFlush()
Animation ลูกบอลเด ้งกระทบ
กาแพง (แก ้ใหม่)
void display()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
drawBall(ball);
glFlush();
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (แก ้ใหม่)
void display()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
drawBall(ball);
glutSwapBuffers();
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (แก ้ใหม่)
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutInitWindowSize(600,600);
...
}
Animation ลูกบอลเด ้งกระทบ
กาแพง (แก ้ใหม่)
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600,600);
...
}
KEYBOARD INPUT
รับอินพุตจากแป้ นพิมพ์
• glutKeyboardFunc(void (*func)​(unsigned char
key, int x, int y))
ั ทีร่ ับ unsigned char และ int สองตัว
– ให ้ฟั งก์ชน
– key คือ ascii code ของปุ่ มทีก
่ ด
– x และ y คือตาแหน่งของ mouse
ตัวอย่าง 1
void printKey(unsigned char key, int x, int y)
{
printf("You type key %d. The mouse is at (%d, %d)\n", key, x, y);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
glutCreateWindow("glutKeyboardFunc Example");
glutDisplayFunc(display);
glutKeyboardFunc(printKey);
glutMainLoop();
}
ตัวอย่าง 2
•
•
•
•
ั 2
โปรแกรมลูกบอลเด ้งชนกาแพง เวอร์ชน
ตอนนีม
้ ล
ี ก
ู บอลได ้หลายลูกแล ้ว
กด space bar แล ้วมีลก
ู บอลเพิม
่
กด Esc เป็ นการออกจากโปรแกรม
ตัวอย่าง 2
void keyboard(unsigned char key, int x, int y)
{
if (key == ' ')
{
newRandomBall();
glutPostRedisplay();
}
else if (key == 27)
exit(0);
}
ดู demo
3D LINEAR ALGEBRA
เวกเตอร์สามมิต ิ
• ลาดับของจานวนจริงสามตัว
(x; y; z)
ั ลักษณ์: ตัวอักษรตัวพิมพ์เล็กหนา
• สญ
u; v; w
• เซตของเวกเตอร์สามมิต ิ
R3 = f (x; y; z) : x; y; z 2 Rg
• เวกเตอร์พเิ ศษ
x = (1; 0; 0); y = (0; 1; 0); z = (0; 0; 1); 0 = (0; 0; 0)
เวกเตอร์สามมิต ิ (ต่อ)
• ความหมาย
– จุดในสามมิต ิ
– ทิศทางในสามมิต ิ
x
x
x
x
y
y
O
z
y
O
z
z
y
z
ปฏิบัตก
ิ ารบนเวกเตอร์สามมิต ิ
• กาหนดให ้
u
= (x 1 ; y1 ; z1 )
v
= (x 2 ; y2 ; z2 )
• การบวกและลบเวกเตอร์
u + v = (x 1 + x 2 ; y1 + y2 ; z1 + z2 )
• การคูณเวกเตอร์ด ้วยสเกลาร์
cu = (cx 1 ; cx 2 ; cx 3 )
ปฏิบัตก
ิ ารบนเวกเตอร์สามมิต ิ (ต่อ)
• การบวก = เอาท ้ายต่อหัว
x
u+ v
v
O
u
z
y
ปฏิบัตก
ิ ารบนเวกเตอร์สามมิต ิ (ต่อ)
• การคูณด ้วยสเกลาร์ = การยืด/หด
x
c1 u
u
c2 u
z
O
y
Linear Combination
• ใหv้ 1; v 2; : : : ; v n
และc1; c2; : : : ; cn
เราเรียก
เป็ นเวกเตอร์ใดๆ
คือจานวนจริงใดๆ
c1 v 1 + c2 v 2 + : : : + cn v n
v 1; v 2; : : : ; v n
ว่า linear combination ของ
Linear Combination (ต่อ)
• เวกเตอร์สามมิตท
ิ ก
ุ เวกเตอร์เป็ น linear
combination ของ
x, y,
(x;และ
y; z) = zx(1; 0; 0) + y(0; 1; 0) + z(0; 0; 1) = xx + yy + zz
Span
• ถ ้าv 1; v 2; : : : ; v n
เป็ นเวกเตอร์ใดๆ
แล ้ว
f c1v 1 + c2v 2 + ¢¢¢+ cn v n : c1; c2; : : : ; cn 2 Rg
เราเรียกเซต
v 1; v 2; : : : ; v n
ว่า span ของ
Span (ต่อ)
•
•
•
•
•
•
•
Span ของ
Span ของ
Span ของ
Span ของ
Span ของ
Span ของ
Span ของ
x, y, และ z มีRค3า่ เท่ากับ
x มีคา่ เท่ากับแกน x
y มีคา่ เท่ากับแกน y
z มีคา่ เท่ากับแกน z
x และ y มีคา่ เท่ากับระนาบ xy
x และ z มีคา่ เท่ากับระนาบ xz
y และ z มีคา่ เท่ากับระนาบ yz
Linear Dependence
v 1า
; v 2; : : : ; v n
• เรากล่าวว่
เป็ นกลุม
่ ของเวกเตอร์ท ี่ linearly dependent
c1; c2; : : : ; cn
ถ ้ามีสเกลาร์
ทีม
่ ต
ี ัวใดตัวหนึง่ มีคา่
ไม่เท่ากับ 0
c1 v 1 + c2 v 2 + : : : + cn v n = 0
ทีท
่ าให ้
Linear Independence
• ตรงข ้ามกับ linear dependence
v 1า
; v 2; : : : ; v n
• เรากล่าวว่
เป็ นกลุม
่ ของเวกเตอร์ท ี่ linearly independent
ถ ้าค่าc1; c2; : : : ; cn
ทีท
่ าให ้
c1 v 1 + c2 v 2 + : : : + cn v n = 0
คือc1 = c2 = ¢¢¢= cn = 0 เท่านัน
้
Linear Independence (ต่อ)
• x, y, และ z --- linearly independent
• (1,2,0) และ (2,4,0) --- linearly dependent
เพราะ 2*(1,2,0) – (2,4,0) = (0,0,0)
• (1,0,1), (2,3,0), (2,1.5,1) --- linearly dependent
เพราะ (1,0,1) + 0.5*(2,3,0) – (2,1.5,1) = (0,0,0)
• (0,0,0) --- linearly dependent
เพราะ c(0,0,0) = (0,0,0) สาหรับค่า c ใดๆ ทีไ่ ม่เท่ากับ 0
้
เสนตรง
้
• ถ ้าu 6= 0 แล ้ว span ของ u คือเสนตรงที
ผ
่ า่ นจุด O
และ u
x
f cu : c 2 Rg
u
O
z
y
ระนาบ
• ถ ้า u และ v เป็ นเวกเตอร์ท ี่ linearly
independent กันแล ้ว
span ของ u และ v xคือระนาบทีผ
่ า่ นจุด O, u,
f c1u + c2v : c1; c2 2 Rg
และ v
u
O
y
v
z
ปริภม
ู เิ วกเตอร์
• ถ ้า u, v, และ w เป็ นเวกเตอร์ท ี่ linearly
independent กันแล ้ว span ของ u, v, และ w
เซตของเวกเตอร์สามมิ
ิ งั ้ หมด
x ตท
u
y
O
v
z
f c1 u + c2 v + c3 w : c1 ; c2 ; c3 2 Rg
Basis
• ถ ้า span ของ u, v, และ w
มีคา่ เท่ากับเซตของเวกเตอร์สามมิตท
ิ งั ้ หมด
เราเรียก u, v, และ w ว่าเป็ น basis ของปริภม
ู ิ
เวกเตอร์สามมิต ิ
Basis (ต่อ)
• x, y, และ z เป็ น basis ของปริภม
ู เิ วกเตอร์สาม
มิต ิ
• (1,1,0), (0,1,1), และ (1,0,1) ก็เป็ น basis
• แต่ (1,0,1), (2,3,0), (2,1.5,1) ไม่ใช ่
เพราะมันไม่ linearly independent
ผลคูณสเกลาร์
• ผลคูณสเกลาร์ (dot product)
u ¢v = x1x2 + y1y2 + z1z2
• ขนาดเวกเตอร์
kuk =
• สมบัตต
ิ า่ งๆ
p
1
x 21 + y12 + z12 = (u ¢u) 2
u ¢v = v ¢u
u ¢(v + w ) = u ¢v + u ¢w
u ¢(cv ) = c(u ¢v )
ku + v k2 = kuk2 + kv k2 + 2(u ¢v )
kcuk = ckuk
ผลคูณสเกลาร์ (ต่อ)
• สมบัต ิ
u ¢v = kukkvk cosµ
เมือ
่  คือมุมระหว่าง u กับ v
u

v
uอ
=อ
0
• u กับ v ตัง้ ฉากกันก็ต
่¢vเมื
่
เวกเตอร์หนึง่ หน่วย
• เวกเตอร์ทม
ี่ ข
ี นาดเท่ากับ 1
• kuk = 1
• ถ ้า u เป็ นเวกเตอร์หนึง่ หน่วยแล ้ว
u ¢v = kvk cosµ
คือความยาวของ v เมือ
่ แตก
แรงไปในทิศของ u
ผลคูณเวกเตอร์
• ผลคูณเวกเตอร์ (cross product)
u £ v = (y1 z2 ¡ y2 z1 ; z1 x 2 ¡ z2 x 1 ; x 1 y2 ¡ x 2 y1 )
= (y1 z2 ¡ y2 z1 )x + (z1 x 2 ¡ z2 x 1 )y + (x 1 y2 ¡ x 2 y1 )z
¯
¯
¯x y z ¯
¯
¯
¯
= ¯x 1 y1 z1 ¯
¯
¯x 2 y2 z2 ¯
•
•
u£ v
ตัง้ ฉากกับทัง้ u และ v
ku £ vk = kukkvk sin µ
u£ v

ผลคูณเวกเตอร์ (ต่อ)
คิดตามกฎมือขวา
u£ v
• ทิศทางของ
– เอามือขวาชไี้ ปตามทิศของ u ให ้ฝ่ ามือหันไปทาง v
– u £ v ตัง้ ฉากกับระนาบทีน
่ ย
ิ ามโดย u กับ v พุง่
ออกไปฝั่ งทีน
่ วิ้ โป้ งขวาอยู่
u
v
v
u £ v พุง่ เข ้ากระดาษ
u
u £ v พุง่ ออกกระดาษ
ผลคูณเวกเตอร์ (ต่อ)
• สมบัตต
ิ า่ งๆ
u£ v = ¡ v£ u
u £ (v + w ) = u £ v + u £ w
u £ (r v ) = (r u) £ v = r (u £ v )
การแปลง
การแปลง (Transformations)
• ตัวอย่าง
้ 1 หน่วย”
– “เลือ
่ นไปทางซาย
– “หมุนรอบแกน y 90 องศา”
– “ขยายขนาดตามแกน z 2 เท่า”
้ ไ่ หน?
• เอาไปใชที
– Modeling
– Animation
– Rendering Pipeline
ตัวอย่าง
• สมมติเรารู ้วิธส
ี ร ้างวงกลมรัศมี 1 หน่วย จุด
ศูนย์กลางอยูท
่ ี่ (0,0)
• อยากได ้วงกลมรัศมี 2 หน่วย จุดศูนย์กลางอยูท
่ ี่
เดิม
ขยาย 2 เท่า
ตัวอย่าง
• อยากได ้วงรีแกนเอกยาว 2 หน่วย แกนโทยาว 1
หน่วย
ขยาย 2 เท่าตามแกน x
ตัวอย่าง
• อยากได ้วงกลมรัศมี 0.5 หน่วย จุดศูนย์กลางอยู่
ทีจ
่ ด
ุ (1,1)
ย่อ 0.5 เท่า
เลือ
่ นแกน x และ y 1 หน่วย
การแปลงในสองมิต ิ
ั ทีส
• การแปลงในสองมิต ิ คือ ฟั งก์ชน
่ ง่ เวกเตอร์
(หรือจุด) สองมิตไิ ปยังเวกเตอร์สองมิต ิ
– สัญลักษณ์: ตัวอักษรภาษาอังกฤษตัวใหญ่ A, B, C,
D, …
– เวลานิ ยาม:
ื่ การแปลง
ชอ
A : (x; y) 7
! (y; ¡ x)
ั (y;
หรือจะเขียA((x;
นแบบฟัy))
งก์ช
ก็ได¡ ้ x)
=น
จุดที่ (x,y) ถูกสง่ ไปหา
ตัวอย่าง
B : (x; y) 7
! (x + 2; y + 3)
C : (x; y) 7
! (x + y; 0)
D : (x; y) 7
! (1:5x; 3y)
E : (x; y) 7
! (x; ex )
F : (x; y) 7
! C(D ((x; y)) = (1:5x + 3y; 0)
การแปลงเอกลักษณ์
• การแปลงเอกลักษณ์ (Identity Transformation)
คือ การแปลงทีส
่ ง่ จุดทุกจุดไปหาตัวมันเอง
I : (x; y) 7
! (x; y)
การแปลงเชงิ เสน้
• เรากล่าวว่าการแปลง A เป็ นการแปลงเชิงเส้น
(linear transformation) ถ ้ามันสอดคล ้องกับ
สมบัตต
ิ อ
่ ไปนี้
1. A(u + v ) = A(u) + A(v )
2. A(cu) = cA(u)
R2
สาหรับเวกเตอร์ u, v ใดๆ ใน
และค่าคงที่ c ใดๆ
ตัวอย่าง
• การแปลงเอกลักษณ์ I เป็ นการแปลงเชงิ เสน้
เพราะ
1. I (u + v ) = u + v = I (u) + I (v )
2. I (cu) = cu = cI (u)
A : (x; y) 7
! (y; ¡ x)
• การแปลงB : (x; y) 7
! (x + 2; y + 3)
เป็ นการแปลงเชงิ เสน้
ก็
•Bแต่
ารแปลง
ไม่ใ1))
ช่
((2;ก2))
= (4; 5) 6
= (6; 8) = B ((1; 1)) + B ((1;
การแปลงเชงิ เสน้ เพราะ
ข ้อสงั เกต
• ถ ้า A เป็ น linear transformation แล ้ว
A(0) = 0
เพราะ2A(0) = A(2 £ 0) = A(0)
้ ส
การแปลงเชงิ เสนที
่ าคัญ 2 ชนิด
• การย่อขยาย (Scaling)
• การหมุน (Rotation)
การย่อขยาย
• การย่อขยาย (Scaling) คือการแปลงทีอ
่ ยูใ่ นรูป
S®;¯ : (x; y) 7
! (®x; ¯y)
มีความหมายคือ
– ขยายในแนวแกน x เป็ นจานวน α เท่า
– ขยายในแนวแกน y เป็ นจานวน β เท่า
ตัวอย่าง
S1;1 ((x; y)) = (1x; 1y) = (x; y)
• เนือ
่ งจาก
ดังนัน
้ S1;1 = I
• S2;2((1; 3)) = (2; 6)
• S1;0:5 ((3; 10)) = (3; 5)
•
S1;2
การหมุน
• การหมุน (rotation) ในทีน
่ จ
ี้ ะต ้องกาหนดมุม θ
ิ
และเราจะหมุนทวนเข็มนาฬการอบจุ
ด origin ไป
เป็ นมุม θR µ
ั :ลั(x;
•R
สµญ
กษณ์
y) 7
! (x โดย
cosµ ¡ y sin µ; y cosµ + x sin µ)
x
µ
y
ตัวอย่าง
• I = R0 (หมุน 0 เรเดียนเท่ากับไม่หมุนเลย)
³
¼ ((1; 0)) =
R
•
6
•
p
´
³
´
¼
¼
3 1
cos ; sin
=
;
6
6
2 2
R ¼4
Linear Transformation และ Basis
• ให ้ x = (1,0) และให ้ y = (0,1)
เราได ้ว่าสาหรับจุด (x,y) ใดๆ
(x,y) = x(1,0) + y(0,1) = xx + yy
• ถ ้า A เป็ น linear transformation เราจะได ้ว่า
A((x; y)) = A(xx + yy )
= A(xx ) + A(yy )
= xA(x ) + yA(y )
Linear Transformation และ Basis
• กล่าวคือถ ้าเรารู ้ A(x) และ A(y) เราก็สามารถ
คานวณ A((x,y)) สาหรับเวกเตอร์ (x,y) ใดๆ ได ้
ทัง้ หมด
• พูดอีกแบบคือ linear transformation จะถูก
นิยามด ้วยค่าของมันที่ basis ของ vector space
้ ้วย
การแทนการแปลงเชงิ เสนด
เมตริกซ ์
• สมมติวา่ A(x) = (a,b) และ A(y) = (c,d)
จะได ้ว่า
A((x; y)) = x(ax + by ) + y(cx + dy )
= (ax + cy)x + (bx + dy)y
= (ax + cy; bx + dy)
้ ้วย
การแทนการแปลงเชงิ เสนด
· ¸
เมตริกซ ์
x
• ถ ้าเขียนคูล
่ าดับ (x,y) ด ้วย column vector
y
จะได ้ว่า
µ· ¸¶
·
¸
x
ax + cy
A
=
y
bx + dy
·
¸· ¸
a c x
=
b d y
้
• ฉะนัน
้ การแปลงเชงิ เสนสองมิ
ตค
ิ อ
ื เมตริกซ ์ 2x2
้ ้วย
การแทนการแปลงเชงิ เสนด
เมตริกซ ์
• สงั เกต
·
¸
a c
A=
b d
A(x)
้ ้วย
การแทนการแปลงเชงิ เสนด
เมตริกซ ์
• สงั เกต
·
¸
a c
A=
b d
A(y )
ตัวอย่าง
• I เป็ นการแปลงเชงิ เสน้ และ I(x) = (1,0), I(y)
= (0,1)
·
¸
1 0
ดังนัน
้
I =
0 1
เมตริกซเ์ อกลักษณ์
S®;¯ (x) = (®; 0); S®;¯ (y) = (0; ¯)
• เนือ
่ งจาก
ดังนัน
้
·
S®;¯
¸
® 0
=
0 ¯
ตัวอย่าง
• เนือ
่ งจาก
Rµ (x ) = (cosµ; sin µ)
Rµ (y ) = (¡ sin µ; cosµ)
ดังนัน
้
·
¸
cosµ ¡ sin µ
Rµ =
sin µ cosµ
การเลือ
่ นแกนขนาน
่
• การเลือนแกนขนาน
(translation) คือ การ
แปลงทีอ
่ ยูใ่ นรูป
Tu : v 7
! v+u
มีความหมายคือ ถ ้า u = (u1, u2) แล ้ว
เราจะเลือ
่ นรูปไปตามแกน x เท่ากับ u1 หน่วย
และเลือ
่ นรูปไปตามแกน y เท่ากับ u2 หน่วย
ตัวอย่าง
• I เป็ นการเลือ
่ นแกนขนาน เพราะ I(u) = u + 0
ดังนัน
้
I = T(0,0) (เขียนง่ายๆ ว่า T0,0)
่ ารแปลง
• T2,3 (0,0) = (2,3) ดังนัน
้ T2,3 ไม่ใชก
เชงิ เสน้
• กล่าวคือ ถ ้า u ไม่ใช ่ 0 แล ้ว Tu ไม่เป็ นการ
แปลงเชงิ เสน้ เนือ
่ งจาก Tu(0) = u ซงึ่ มีคา่ ไม่
เท่ากับ 0
ตัวอย่าง
•
T1;1
Composition
• Composition คือการนาเอาการแปลงสองอันมา
รวมให ้เป็ นอันเดียววิธห
ี นึง่
• ให ้ A กับ B เป็ นการแปลง composition ของมัน
คือการแปลง BA โดยที่
B A : (x; y) 7
! B (A((x; y))
กล่าวคือเป็ นการแปลงทีเ่ กิดขึน
้ จากการนา
เวกเตอร์ข ้อมูลเข ้าไปแปลงด ้วย A ก่อนแล ้วจึง
แปลงด ้วย B
ตัวอย่าง
• T0;1 R ¼2 คือการหมุน 90 องศาแล ้วเลือ
่ นทางแกน
y หนึง่ หน่วย
R ¼2
T0;1 R ¼2
T0;1
ข ้อสงั เกต
• ถ ้า A เป็ นการแปลงใดๆ แล ้ว IA = AI = A
AB 6
=้ว B A
• ระวัง! โดยทั่วไปแล
• ดู R ¼2 T0;1
T0;1
R T0;1
¼
2
R ¼2
การแปลงแอฟไฟน์
• เรากล่าวว่าการแปลง A เป็ นการแปลงแอฟไฟน์
(affine transformation) ถ ้า
A = Tu B
โดยที่ Tu เป็ นการเลือ
่ นแกนขนานและ B เป็ น
การแปลงเชงิ เสน้
ตัวอย่าง
• I เป็ นการแปลงแอฟไฟน์เพราะ I = T0,0I
• T0;1 R ¼2 เป็ นการแปลงแอฟไฟน์ (อย่างเห็นได ้
ั ¼2 )T0;1
ช
Rด
ิ
•
ก็Rเ¼ป็Tนการแปลงแอฟไฟน์
เ
ช
ง
เดี
ย
วกั
น
¼
0;1 (v ) = R 2 (v + (0; 1))
2
เพราะ
¼
¼
= R 2 (v ) + R 2 ((0; 1))
= R ¼2 (v ) + (¡ 1; 0)
= T¡
(v )
1;0 R ¼
2
ข ้อสงั เกต
้
• ถ ้า B เป็ นการแปลงเชงิ เสนแล
้ว BTu จะเป็ นการ
แปลงแอฟไฟน์เสมอ เนือ
่ งจาก
BTu (v) = B(v + u) = B(v) + B(u) = TB (u ) B(v)
กล่าวคือ
BTu = TB (u ) B
ข ้อสงั เกต
• เราสามารถพิสจ
ู น์ได ้ทานองเดียวกันว่า ถ ้าแต่ละ
ตั1ว;ของการแปลง
A
A 2; : : : ; A n¡ 1; A n
นการเลื
่ นแกนขนานหรือ
A n A n ¡ เป็
1 ¢¢¢A
2A 1 อ
การแปลงเชงิ
้
เสนแล
้ว การแปลง
จะเป็ นการ
แปลงแอฟไฟน์
• ดังนัน
้ การแปลงแอฟไฟน์จงึ เป็ นกลุม
่ ของการ
แปลงทีร่ วม
– การย่อขยาย
– การหมุน
Homogeneous Coordinates
• Homogeneous coordinates เป็ นวิธก
ี ารแทนจุด
สองมิตด
ิ ้วยเวกเตอร์สามมิตแ
ิ บบหนึง่ โดยที่
เวกเตอร์ (x,y,w) หมายถึงจุด (x/w,y/w) ถ ้า w ≠ 0
• ตัวอย่าง
– (1,2,1) หมายถึงจุด (1,2)
่ เดียวกัน
– (2,4,2) หมายถึงจุด (1,2) เชน
– (w,2w,w) ก็หมายถึงจุด (1,2) สาหรับค่า w ใดๆ
การแทนการแปลงแอฟไฟน์ด ้วย
เมตริกซ ์
A = Tu B
• สมมติวา่ เรามีการแปลงแอฟไฟน์
·
¸
· ¸
โดยที่
a c
e
B=
b d
;
u=
µ· ¸¶
·
¸· ¸
จะได ้ว่า x
a c x
A
=
y
b d y
·
ax + cy +
=
bx + dy +
f
· ¸
e
+
f
¸
e
f
การแทนการแปลงแอฟไฟน์ด ้วย
เมตริกซ ์
• ให ้
2
3
a c e
N = 4b d f 5
0 0 1
เมือ
่ เราคูณ N ด ้วย (x,y,1) ซงึ่ เป็ น
homogeneous coordiate ของ (x,y) จะได ้ว่า
2 3 2
32 3 2
x
a c e x
ax + cy +
N 4 y 5 = 4 b d f 5 4 y 5 = 4 bx + dy +
1
0 0 1 1
1
homogeneous coordinate ของA ((x; y))
3
e
f5
การแทนการแปลงแอฟไฟน์ด ้วย
เมตริกซ ์
• ฉะนัน
้ affine transform คือเมตริกซ ์ 3x3 ทีแ
่ ถว
ล่างเท่ากับ (0,0,1)
การแทนการแปลงแอฟไฟน์ด ้วย
เมตริกซ ์
• สงั เกต
2
3
a c e
A = 4b d f 5
0 0 1
A(x) ¡ u = B (x)
การแทนการแปลงแอฟไฟน์ด ้วย
เมตริกซ ์
• สงั เกต
2
3
a c e
A = 4b d f 5
0 0 1
A(y ) ¡ u = B (y )
การแทนการแปลงแอฟไฟน์ด ้วย
เมตริกซ ์
• สงั เกต
2
3
a c e
A = 4b d f 5
0 0 1
u = A(0)
ตัวอย่าง
•
•
•
•
T0;1 R ¼2 ((0; 0)) = (0; 1)
T0;1 R ¼2 ((1; 0)) ¡ (0; 1) = (0; 2) ¡ (0; 1) = (0; 1)
T0;1R ¼2 ((0; 1)) ¡ (0; 1) = (¡ 1; 1) ¡ (0; 1) = (¡ 1; 0)
ดังนัน
้
2
T0;1 R ¼2
3
0 ¡ 1 0
= 4 1 0 15
0 0 1
์ องการแปลงแอฟไฟน์ท ี่
เมตริกซข
สาคัญ
2
S®;¯
3
® 0 0
= 4 0 ¯ 05
0 0 1
2
3
1 0 u1
Tu = 4 0 1 u2 5
0 0 1
2
3
cosµ ¡ sin µ 0
R µ = 4 sin µ cosµ 05
0
0
1
2
3
1 0 0
I = 4 0 1 05
0 0 1
Composition และเมตริกซ ์
• Composition คือการคูณเมตริกซ ์
• ตัวอย่าง
2
T0;1 R ¼2
32
3 2
3
1 0 0 0 ¡ 1 0
0 ¡ 1 0
= 4 0 1 15 4 1 0 05 = 4 1 0 15
0 0 1 0 0 1
0 0 1
การแปลงผันกลับ
• การแปลงผันกลับ (inverse) ของการแปลง A
คือการแปลง A-1 ทีท
่ าให ้
AA ¡ 1 = A ¡ 1A = I
่ y) 7
A : เช
(x;น
! (x; 0)
• การแปลงบางตัวไม่ม ี inverse
• การแปลงแอฟไฟน์ A จะมี inverse ก็ตอ
่ เมือ
่
det (A)
=อีก
0นัยหนึง่ คือ
์ อง A มี inverse
เมตริกซข
พูด6
การแปลงผันกลับของการแปลงแอฟ
ไฟน์ทส
ี่ าคัญ
2
¡
S®;¯
¢¡
1
3¡
® 0 0
= 4 0 ¯ 05
0 0 1
2
¡
Tu
¢¡
1
3¡
1 0 u1
= 4 0 1 u2 5
0 0 1
1
21
®
= 40
0
1
2
0
1
¯
0
3
0
05 = S 1 ; 1
® ¯
1
3
1 0 ¡ u1
= 4 0 1 ¡ u2 5 = T¡
0 0
1
u
การแปลงผันกลับของการแปลงแอฟ
ไฟน์ทส
ี่ าคัญ
2
¡
Rµ
¢¡
1
3¡ 1
cosµ ¡ sin µ 0
= 4 sin µ cosµ 05
0
0
1
2
3
¡ cosµ ¡ sin µ 0
= 4 sin µ ¡ cosµ 05
0
0
1
2
3
cos(¡ µ) ¡ sin(¡ µ) 0
cos(¡ µ) 05 = R ¡
= 4 sin(¡ µ)
0
0
1
µ