בפוסט הקודם הצגתי את הלוגו החדש של המבצע המתוכנן הבא (מבצע חיפוש כלה שמנמנה ומאד נשית). ציינתי שכתבתי תוכנית ++C ייעודית לשם כך. בעקבות זאת שאל אותי (בתגובות) הבלוגר חסר מעש באיזו סיפריה השתמשתי ליצירת אותה תוכנית. עניתי לו שהשתמשתי בספריה פחות או יותר סטנדרטית ושאת יישום התלת-מימד כתבתי בעיקר בעצמי. הנה שוב הלוגו-אנימציה לתזכורת:
ההסבר הבא, אני מניח לא יעניין את מי שאין לו הבנה בסיסית בתיכנות, אז יש לו/ה אישור ממני לדלג (רק הפעם...
) על קריאת הפוסט הזה. אנסה להסביר פה בקצרה (השעה כבר קצת מאוחרת) כיצד השתמשתי בטכניקת ה-ray casting ליצירת החלק התלת-מימדי.
יצירתי מעין "מפה" בה ציירתי "קירות" (ה"מפה" כפי שיובהר עוד מעט היא בעצם מעין מערך דו-מימדי). עתה כשנמצאים באיזה מקום וצופים ממנו בזווית מסויימת, שולחים קרניים (לפי עיקרון הפרספקטיבה) עד שהן נתקלות ב"קיר". למשל בציור הבא, אנחנו בוחרים את כל הקרניים שעוברות דרך נקודות הישר (או אם תרצו "קו המבט") S (האדום) וכל קרן/נקודה כזו קשורה לעמודת פיקסלים אנכית שתופיע לאחר מכן על המסך. הקירות מסומנים בציור הבא ב-W1, W2 וכו'. "גבולות הגיזרה" שלנו הן הקרניים E1 ו-E2. נסתכל למשל על הקרן ("קרן" (מלשון "קרן אור"), למעשה זהו פשוט קו ישר) V1. היא מתחילה לנוע מהקו S עד שנתקלת בקיר כלשהו. בציור זהו קיר W3.
נסתכל עכשיו על האזור התחום בקו אפור מקווקו בציור הנ"ל. כאמור היישום של המפה הנ"ל הוא מעין מערך דו-מימדי. נקודות הקיר, מכילות צמדי מספרים (נקודות שהן "ריק" יכולות להכיל למשל צמדי אפסים). המספר הראשון הוא מספר הקיר, השני הוא מספר העמודה בקיר. מספר הקיר בעצם אומר לנו איזו מפת סיביות (bitmap, קרי תמונה לעניינו) צריכה להיות מצויירת (יש מערך אחר שמקשר בין מספר מפת הסיביות לשם הקובץ שמכיל אותה) ואילו מספר העמודה אומר לנו איזו עמודה מתוכה צריכה להיות מצויירת עבור הקרן הספציפית הזו. למשל בציור הבא, הקרן V1 לעיל פגעה בתא שתכולתו (3,3) משמע קיר מספר 3 ועמודה מספר 3 מתוך מפת הסיביות המתאימה:

בדוגמא הזו אנחנו טוענים לזכרון את מפת הסיביות שמקושרת למספר 3 (אלא אם כן כבר טענו אותה קודם והיא עדיין בזכרון) ומציירים על המסך את עמודה מספר 3 מתוכה, כלומר קו אנכי אחד. לפי המרחק שעברה הקרן V1, אנחנו יודעים מה הפרספקטיבה הנכונה לצייר את העמודה, כלומר רחוק יותר משמע עמודה קצרה יותר ולהיפך קרוב יותר, משמע עמודה ארוכה יותר. את החלקים בעמודה שלא נצבעו, מעל ומתחת, אנחנו צובעים במקרה זה בצבע צהוב לתקרה ואפור לרצפה.
זה ב"גדול" ההסבר ליישום שלי. לא מאד מסובך, אבל גם לא טרוויאלי. זו כמובן טכניקה ידועה (אני לא המצאתי אותה.. רק יישמתי יישום משלי (אפשר ליצור יישום שיהיה יעיל יותר הן מבחינת זמן ריצה והן מבחינת ניצול זיכרון, למשל אם הקירות מופיעים רק במקומות מסויימים ואז המפה מבחינת הקרניים דלילה יותר, אבל לצרכים שלי, מה שעשיתי גם אם לא בהכרח הכי יעיל, הספיק)).
לילה טוב לכם/ן קוראי וקוראותי החביבים והחביבות.