C++Creative CodeProgramming Language

Creative Coding ด้วย C++ และ openFrameworks การเขียนโปรแกรมเบื้องต้น

จากบทความก่อนหน้า Creative Coding ด้วย C++ บน Visual Studio 2022 และ openFrameWorks ที่มีการติดตั้งโปรแกรมเรียบร้อยแล้ว ในรอบนี้เราจะมาเขียนโปรแกรมเบื้องต้นกันด้วยภาษา C++

เรามาเริ่มที่การเขียนโปรแกรมคอมพิวเตอร์กราฟิก 2มิติกันก่อน สิ่งแรกที่เราต้องเข้าใจคือ Computer Graphics Coordinates จริงๆ เป็นหนึ่งในวิชา เรขภาพคอมพิวเตอร์ (Computer Graphic) ปัจจุบันเน้นการใช้เครื่องมือไปหมดแล้วไม่ค่อยเข้าใจหลักของ คณิตศาสตร์ และฟิสิกส์ ไปจนถึง อัลกอริทึม

Computer Graphics Coordinates

ในโลกของคอมพิวเตอร์กราฟิกส์ พิกัด (Coordinates) คือ ค่าตัวเลขที่ใช้ระบุตำแหน่งของจุดหรือวัตถุบนหน้าจอหรือในพื้นที่สามมิติ โดยทั่วไปจะใช้ระบบพิกัดคาร์ทีเซียน (Cartesian coordinate system)

ระบบพิกัดคาร์ทีเซียน

ระบบนี้จะใช้แกนสองแกน (ในพื้นที่สองมิติ) หรือสามแกน (ในพื้นที่สามมิติ) ที่ตั้งฉากกัน

  • แกน X: แกนนอน
  • แกน Y: แกนตั้ง
  • แกน Z: แกนลึก (ในพื้นที่สามมิติ)

จุดตัดของแกนทั้งสอง (หรือสาม) เรียกว่า จุดกำเนิด (Origin) ซึ่งโดยทั่วไปจะมีพิกัด (0, 0) หรือ (0, 0, 0) ตำแหน่งของจุดใดๆ บนหน้าจอหรือในพื้นที่สามมิติ จะถูกระบุด้วยค่าตัวเลขตามแกน X, Y และ Z เช่น จุด (2, 3) หมายถึง จุดที่อยู่ห่างจากจุดกำเนิดไปทางแกน X 2 หน่วย และห่างจากจุดกำเนิดไปทางแกน Y 3 หน่วย

การทำงานของพิกัดในคอมพิวเตอร์กราฟิกส์

พิกัดมีบทบาทสำคัญในการสร้างและจัดการรูปภาพในคอมพิวเตอร์กราฟิกส์ โดยจะใช้พิกัดในการ:

  • กำหนดตำแหน่งของวัตถุ: เช่น กำหนดตำแหน่งของจุดยอด (Vertex) ของรูปหลายเหลี่ยม ตำแหน่งของจุดเริ่มต้นและจุดสิ้นสุดของเส้นตรง หรือตำแหน่งของศูนย์กลางของวงกลม
  • ควบคุมการแปลงทางเรขาคณิต: เช่น การเลื่อนตำแหน่ง (Translation) การหมุน (Rotation) การปรับขนาด (Scaling)
  • สร้างเอฟเฟกต์ต่างๆ: เช่น การบิดเบือน (Distortion) การให้แสงเงา (Shading)

ตัวอย่างการใช้งาน

  • ในการวาดเส้นตรง โปรแกรมจะใช้พิกัดของจุดเริ่มต้นและจุดสิ้นสุดในการสร้างเส้นตรงบนหน้าจอ (จุด เส้น ระนาบ) องค์ประกอบศิลป์ไหมละ (Vertex, Edge, Faces)
  • ในการสร้างแบบจำลองสามมิติ โปรแกรมจะใช้พิกัดในการกำหนดตำแหน่งของจุดยอดของรูปหลายเหลี่ยมที่ประกอบกันเป็นแบบจำลอง
  • ในการสร้างภาพเคลื่อนไหว โปรแกรมจะเปลี่ยนแปลงพิกัดของวัตถุในแต่ละเฟรม ทำให้เกิดการเคลื่อนไหวของวัตถุ กลายเป็นแอนิเมชัน

ชนิดของระบบพิกัด

นอกจากระบบพิกัดคาร์ทีเซียนแล้ว ยังมีระบบพิกัดอื่นๆ ที่ใช้ในคอมพิวเตอร์กราฟิกส์ เช่น

  • ระบบพิกัดเชิงขั้ว (Polar coordinate system) ใช้ระยะทางจากจุดกำเนิดและมุมจากแกนอ้างอิงในการระบุตำแหน่งของจุด
  • ระบบพิกัดทรงกลม (Spherical coordinate system) ใช้ระยะทางจากจุดกำเนิด มุมจากแกนอ้างอิงในแนวราบ และมุมจากแกนอ้างอิงในแนวตั้งในการระบุตำแหน่งของจุด

ซึ่ง 2 ตัวหลังนี้คงไม่ได้พูดถึงเท่าไรในบทความนี้ครับ

มาเริ่มต้นเขียนโปรแกรมกัน ให้ไปที่ Solution ของเราแล้วเปิดไฟล์ ofApp.cpp (มาจาก openframeworksApp) เปิดไฟล์นี้ขึ้นมาแล้วเขียนโปรแกรมดังนี้:

void ofApp::draw(){
    ofDrawCircle(250,300,150);
}

ภาษา C++ โดยใช้ไลบรารี openFrameworks (OF) ซึ่งเป็นไลบรารี โดย

void ofApp::draw(){ ... }

นี่คือฟังก์ชัน draw() ซึ่งเป็นส่วนหนึ่งของคลาส ofApp ใน openFrameworks ฟังก์ชันนี้จะถูกเรียกซ้ำ ๆ เพื่อวาดภาพกราฟิกบนหน้าจอ โค้ดที่อยู่ภายในวงเล็บปีกกา {} จะเป็นคำสั่งที่ใช้ในการวาดภาพ

ofDrawCircle(250, 300, 150);

นี่คือฟังก์ชันจากไลบรารี openFrameworks ที่ใช้สำหรับวาดวงกลม พารามิเตอร์สามตัวในวงเล็บ มีความหมายดังนี้

  • 250: พิกัด X ของจุดศูนย์กลางวงกลม (ระยะห่างจากขอบซ้ายของหน้าจอ)
  • 300: พิกัด Y ของจุดศูนย์กลางวงกลม (ระยะห่างจากขอบบนของหน้าจอ)
  • 150: รัศมีของวงกลม

โค้ดนี้จะวาดวงกลมที่มีจุดศูนย์กลางอยู่ที่พิกัด (250, 300) และมีรัศมี 150 พิกเซล บนหน้าจอ ทุกครั้งที่ฟังก์ชัน draw() ถูกเรียก วงกลมนี้ก็จะถูกวาดซ้ำ ทำให้เห็นเป็นวงกลมคงที่บนหน้าจอ

เขียนเพิ่มเล็กน้อย:

ofSetColor(255, 0, 0);
ofDrawRectangle(500, 300, 90, 90);

เป็นการเปลี่ยนสีของวงกลมให้กลายเป็นสีเขียว

มาลองศึกษาถึงการประกาศตัวแปรในภาษา C++ กันหน่อย ให้เปิดไฟล์ header library คือ ofApp.h ครับ

ประกาศตัวแปรต่อไปนี้:

int myGlobalVar;

ไฟล์ ofApp.h จะเป็นดังนี้

class ofApp : public ofBaseApp{

    public:
        void setup();
        void update();
        void draw();

        void keyPressed(int key);
        void keyReleased(int key);
        void mouseMoved(int x, int y );
        void mouseDragged(int x, int y, int button);
        void mousePressed(int x, int y, int button);
        void mouseReleased(int x, int y, int button);
        void mouseEntered(int x, int y);
        void mouseExited(int x, int y);
        void windowResized(int w, int h);
        void dragEvent(ofDragInfo dragInfo);
        void gotMessage(ofMessage msg);

        int myGlobalVar;
       
};

กลับไปที่ ไฟล์ ofApp.cpp แล้วเพิ่มในฟังก์ชัน setup() ดังนี้:

void ofApp::setup(){
    myGlobalVar = 2350;
}

เพิ่มคำสั่งในฟังก์ชัน draw() ใหม่

void ofApp::draw(){
    ofBackground(255); // ตั้งค่าพื้นหลังเป็นสีขาว
    // กำหนดขนาดและตำแหน่งของรูปทรง
    float size = 200;
    float centerX = ofGetWidth() / 2;
    float centerY = ofGetHeight() / 2;
    // คำนวณพิกัดของจุดยอดแต่ละจุด
    ofPoint p1(centerX, centerY - size);
    ofPoint p2(centerX + size * cos(PI / 6), centerY - size * sin(PI / 6));
    ofPoint p3(centerX + size * cos(PI / 6), centerY + size * sin(PI / 6));
    ofPoint p4(centerX, centerY + size);
    ofPoint p5(centerX - size * cos(PI / 6), centerY + size * sin(PI / 6));
    ofPoint p6(centerX - size * cos(PI / 6), centerY - size * sin(PI / 6));
    ofPoint p7(centerX, centerY);

    // วาดเส้นเชื่อมต่อจุดต่างๆ
  
}

วาดรูปหกเหลี่ยมบนหน้าจอ มาดูคำอธิบายทีละส่วนกัน:

1. ofBackground(255);

  • บรรทัดนี้ใช้สำหรับตั้งค่าสีพื้นหลังของหน้าจอเป็นสีขาว ค่า 255 หมายถึงสีขาวในระบบ RGB (Red, Green, Blue)

2. กำหนดขนาดและตำแหน่ง

  • float size = 200; กำหนดตัวแปร size ซึ่งเป็นตัวกำหนดขนาดของรูปหกเหลี่ยม ในที่นี้คือ 200 พิกเซล
  • float centerX = ofGetWidth() / 2; คำนวณพิกัด X ของจุดศูนย์กลางหน้าจอ โดยใช้ฟังก์ชัน ofGetWidth() เพื่อดึงความกว้างของหน้าจอ แล้วหารด้วย 2
  • float centerY = ofGetHeight() / 2; คำนวณพิกัด Y ของจุดศูนย์กลางหน้าจอ ในลักษณะเดียวกัน

3. คำนวณพิกัดจุดยอด

  • ส่วนนี้ใช้ ofPoint ในการกำหนดพิกัดของจุดยอดทั้ง 7 จุดของรูปหกเหลี่ยม (รวมจุดศูนย์กลาง) โดยใช้ตรีโกณมิติในการคำนวณตำแหน่งของจุดยอดแต่ละจุด โดยอ้างอิงจากจุดศูนย์กลาง และขนาดของรูปหกเหลี่ยม
  • p1 ถึง p6 คือจุดยอดของหกเหลี่ยม โดยใช้มุม PI/6 (30 องศา) ในการคำนวณตำแหน่ง
  • p7 คือจุดศูนย์กลางของหกเหลี่ยม
ofDrawLine()

ส่วนนี้เป็นการวาดเส้นเชื่อมต่อ, ใช้ฟังก์ชัน ofDrawLine() เพื่อวาดเส้นเชื่อมต่อระหว่างจุดยอดต่างๆ เพื่อสร้างรูปหกเหลี่ยม เราลองเขียนดังนี้:

    ofSetColor(0); // ตั้งค่าสีเส้นเป็นสีดำ
    ofSetLineWidth(2); // ตั้งค่าความหนาของเส้น

    ofDrawLine(p1, p2);
    ofDrawLine(p2, p3);
    ofDrawLine(p3, p4);
    ofDrawLine(p4, p5);
    ofDrawLine(p5, p6);
    ofDrawLine(p6, p1);

    ofDrawLine(p1, p7);
    ofDrawLine(p2, p7);
    ofDrawLine(p3, p7);
    ofDrawLine(p4, p7);
    ofDrawLine(p5, p7);
    ofDrawLine(p6, p7);

    ofDrawLine(p2, p5);
    ofDrawLine(p3, p6);

เราจะได้เส้นกราฟิกสวยๆ ปรากฏมากมายให้เราได้ลองทำดูได้เลยครับ

Asst. Prof. Banyapon Poolsawas

อาจารย์ประจำสาขาวิชาการออกแบบเชิงโต้ตอบ และการพัฒนาเกม วิทยาลัยครีเอทีฟดีไซน์ & เอ็นเตอร์เทนเมนต์เทคโนโลยี มหาวิทยาลัยธุรกิจบัณฑิตย์ ผู้ก่อตั้ง บริษัท Daydev Co., Ltd, (เดย์เดฟ จำกัด)

Related Articles

Back to top button

Adblock Detected

เราตรวจพบว่าคุณใช้ Adblock บนบราวเซอร์ของคุณ,กรุณาปิดระบบ Adblock ก่อนเข้าอ่าน Content ของเรานะครับ, ถือว่าช่วยเหลือกัน