קובייה , המחלקה CCube
הגענו לתלת ממד! מכאן נוכל להתחיל ללמוד את הנושא שלשמו פתחנו ספר זה. קובייה , האובייקט התלת ממדי הקלאסי , מורכבת משש (6 ) פאות שוות הניצבות זו לזו , ועוד שמונה(8) קודקודים ,כל קודקוד משותף לשלוש פאות. כמו כן כל פאה (פוליגון) מוגדרת ע"י ארבע(4) נקודות. תיאור זה אינו הגדרה הנדסית אלא הנחיות עבורנו לבנייה נכונה של הקובייה.
כלל ברזל ראשון : רוצים לצייר על המסך ? התחילו על דף חלק בעזרת עיפרון ומחק.
נכון , אין סבלנות. אך רק יחידי סגולה ניחנים במתנה "ראיה במרחב" רובכם וגם אני, לא. במקרים כאלה אנו נעזרים בלוגיקה של שלב אחר שלב . וזה עובד. בדרך זו תכננתי ושרטטתי הרבה חלקי מכונות מסובכים כמו גם אובייקטים גרפיים. הנה לכם קובייה:
y
2 3
6 7 -z
x 1 0
5 4
והנה קבוצות קדקודים המרכיבים כל פוליגון:
{4, 5, 6, 7}; front facet (polygon)
{1, 2, 6, 5}; right facet
{0, 1, 5, 4}; bottom facet
{0, 3, 2, 1}; rear facet
{0, 4, 7, 3}; left facet
{2, 3, 7, 6}; upper facet
טיילו עם האצבע על קבוצת קודקודים . מסקנה : האצבע נוסעת נגד כיוון השעון. וכך נאכלס את מערך הנקודות של כל פוליגון. glut אוהב את "הכיוון המתמטי החיובי" כלומר נגד כיוון השעון. נכון , אפשר לכיוון השני (בכל כיוון חייבים לשמור על אחידות) אך אז יש להוסיף פקודות CW(Clockwise) או CCW(Counter Clockwise) .מיותר.
ועוד משהו : כל נקודה 0..7 מופיעה בשלוש קבוצות שונות.
נבחר לנו מקצוע באורך 1 ונבנה את קוביית היחידה כך שנקודה 0 מונחת בראשית הצירים.
נבנה מחלקה חדשה CCube היורשת מהמחלקה CModel .
נגדיר את המשתנה polygon כמצביע על מערך באורך 6 .כל איבר פאה.
SetNumOfPolygons(6);
נאתחל את 4 הנקודות של כל פוליגון:
for(int i=0; i<numofpolygons; i++)
polygon[i].SetNumberOfPoints(4);
נא לא לשכוח את ההירארכיה:
כל איבר במערך polygon הוא מערך בשם points של 4 נקודות. הפעולות שביצענו מקצות זיכרון למשתנים. שכחתם לבצע זאת ,יתכן שהקומפיילר לא יגלה זאת ,רק בזמן ריצה תקבלו תוצאות בסגנון : Un Expected Results .
עכשיו אפשר להגדיר קואורדינטות של כל נקודה בכל פוליגון. למשל rear facet המתחיל בראשית הצירים:
//rear facet
z y x נקודה מספר פוליגון מספר 1
polygon[1].SetPointCoordinates(0, 0 , 0, 0);
polygon[1].SetPointCoordinates(1, 0 , 1, 0);
polygon[1].SetPointCoordinates(2, 1 , 1, 0);
polygon[1].SetPointCoordinates(3, 1 , 0, 0);
כל המשטח (ארבעת הנקודות) בצבע green
b g r נקודה מספר פוליגון מספר 1
polygon[1].SetPointColor(0, 0 , 1 , 0);
polygon[1].SetPointColor(1, 0 , 1 , 0);
polygon[1].SetPointColor(2, 0 , 1 , 0);
polygon[1].SetPointColor(3, 0 , 1 , 0);
חשוב: במערך polygon שישה איברים : 0..7 ובמערך points ארבעה איברים 0..3 . בדוגמא שלעיל polygon[1] הוא הפוליגון השני. לפניכם שני הקבצים cube.h, cube.cpp במלואם.
בהמשך תבנו אובייקטים שכאלה בעצמכם!
#pragma once
#include "Model.h"
class CCube : public CModel
{
public:
CCube(void);
~CCube(void);
};
#include "Cube.h"
CCube::CCube(void)
{
SetNumOfPolygons(6);
for(int i=0; i<numofpolygons; i++)
polygon[i].SetNumberOfPoints(4);
//front facet
polygon[0].SetPointCoordinates(0,0,0,1);
polygon[0].SetPointCoordinates(1,1,0,1);
polygon[0].SetPointCoordinates(2,1,1,1);
polygon[0].SetPointCoordinates(3,0,1,1);
polygon[0].SetPointColor(0,1,0,0);//color red
polygon[0].SetPointColor(1,1,0,0);
polygon[0].SetPointColor(2,1,0,0);
polygon[0].SetPointColor(3,1,0,0);
//rear facet
polygon[1].SetPointCoordinates(0,0,0,0);
polygon[1].SetPointCoordinates(1,0,1,0);
polygon[1].SetPointCoordinates(2,1,1,0);
polygon[1].SetPointCoordinates(3,1,0,0);
polygon[1].SetPointColor(0,0,1,0);//color green
polygon[1].SetPointColor(1,0,1,0);
polygon[1].SetPointColor(2,0,1,0);
polygon[1].SetPointColor(3,0,1,0);
//left facet
polygon[2].SetPointCoordinates(0,0,0,0);
polygon[2].SetPointCoordinates(1,0,0,1);
polygon[2].SetPointCoordinates(2,0,1,1);
polygon[2].SetPointCoordinates(3,0,1,0);
polygon[2].SetPointColor(0,0,0,1);//color blue
polygon[2].SetPointColor(1,0,0,1);
polygon[2].SetPointColor(2,0,0,1);
polygon[2].SetPointColor(3,0,0,1);
//right facet
polygon[3].SetPointCoordinates(0,1,0,0);
polygon[3].SetPointCoordinates(1,1,1,0);
polygon[3].SetPointCoordinates(2,1,1,1);
polygon[3].SetPointCoordinates(3,1,0,1);
polygon[3].SetPointColor(0,1,0,1);//color red+blue
polygon[3].SetPointColor(1,1,0,1);
polygon[3].SetPointColor(2,1,0,1);
polygon[3].SetPointColor(3,1,0,1);
//bottom facet
polygon[4].SetPointCoordinates(0,0,0,0);
polygon[4].SetPointCoordinates(1,1,0,0);
polygon[4].SetPointCoordinates(2,1,0,1);
polygon[4].SetPointCoordinates(3,0,0,1);
polygon[4].SetPointColor(0,0,1,1);//color green+blue
polygon[4].SetPointColor(1,0,1,1);
polygon[4].SetPointColor(2,0,1,1);
polygon[4].SetPointColor(3,0,1,1);
//upper facet
polygon[5].SetPointCoordinates(0,0,1,0);
polygon[5].SetPointCoordinates(1,0,1,1);
polygon[5].SetPointCoordinates(2,1,1,1);
polygon[5].SetPointCoordinates(3,1,1,0);
polygon[5].SetPointColor(0,1,1,0);//color red+green
polygon[5].SetPointColor(1,1,1,0);
polygon[5].SetPointColor(2,1,1,0);
polygon[5].SetPointColor(3,1,1,0);
TranslateZ(-10);//לא לשכוח "לדחוף" את האובייקט לתוך המסך
}
CCube::~CCube(void)
{
}
עכשיו אתם בטח רוצים להציג את הקובייה על המסך , ערכו את השינויים הבאים בקובץ init.cpp והריצו:
#include "Cube.h" //הכללת הקובץ
CCube cube; //אובייקט קובייה
.
.
.
void MyDraw()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glutPostRedisplay();
//==============================================
//mannage game
//screen.ActivateScreen();
//mng.DrawGame();
//עיגול
//igul.DrawPoly();
//igul.RotateSelfX(0.05);
//קובייה
cube.DrawPoly();
cube.RotateSelfX(0.1);
cube.RotateSelfY(0.1);
cube.RotateSelfZ(0.1);
.
.
.
והקובייה מצוירת ומסתובבת סביב שלושת הצירים דרך מרכזה.
העיגול לא מופיע כי זה בהערה. אז מה , כל פעם נוציא / נכניס אובייקט להערה ? ברור שזו לא שיטה. במשחק אמיתי ישנם הרבה אובייקטים וכל אובייקט מוצג ו"משוחק" בתורו. נעשה זאת בעזרת "מנהל משחק". כלומר נבנה מחלקה ובה כל האובייקטים וחוקי המשחק.
מצוידים במחלקת קובייה אפשר להתחיל לחשוב על לוח דמקה / שח המורכב מ- 64 קוביות. לא ניצור חלילה 64 מחלקות קובייה אלא מערך דו ממדי של 8X8 קוביות. למשל כך:
CCube GameBoard[8][8];
המערך כולו מטיפוס המחלקה CCube שבנינו.