בעת פיתוח משחקים חינוכיים, מתן משוב מדויק ומשמעותי הוא קריטי לשימור המעורבות של המשתמש. במאמר זה, אשתף כיצד יישמנו מערכת חישוב גאוגרפית עבור Flagle Explorer, משחק ניחוש דגלים שעוזר למשתמשים ללמוד גיאוגרפיה עולמית דרך משוב אינטראקטיבי.
אתגר טכני
הדרישות העיקריות שלנו היו:
- חישובי מרחקים מדויקים בין כל שני נקודות על פני כדור הארץ
- חישובי כיוון מדויקים להכוונה כיוונית
- ניקוד קרבה נורמליזציה
- ביצועים בזמן אמת למשוב מיידי
פרטי יישום
1. מבנה נתונים בסיסי
ראשית, הגדרנו את ממשק הנקודה הגאוגרפית הבסיסי שלנו:
export interface GeoPoint {
lat: number; // Latitude in degrees
lon: number; // Longitude in degrees
}
2. יישום חישובי מרחק
יישמנו את נוסחת הוורזין לחישוב מרחקים על פני קו גדול:
export function calculateDistance(point1: GeoPoint, point2: GeoPoint): number {
// Early return for identical points
if (point1.lat === point2.lat && point1.lon === point2.lon) {
return 0;
}
const R = 6371000; // Earth's radius in meters
// Convert to radians
const dLat = (point2.lat - point1.lat) * Math.PI / 180;
const dLon = (point2.lon - point1.lon) * Math.PI / 180;
const lat1 = point1.lat * Math.PI / 180;
const lat2 = point2.lat * Math.PI / 180;
// Haversine formula
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon/2) * Math.sin(dLon/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return (R * c) / 1000; // Convert to kilometers
}
3. מערכת חישוב כיוונים
פיתחנו מערכת חישוב כיוונים מתקדמת שהופכת מתמטיקה זוויתית מורכבת לאינדיקטורים כיווניים ידידותיים למשתמש:
export function calculateOrientation(point1: GeoPoint, point2: GeoPoint): number {
if (point1.lat === point2.lat && point1.lon === point2.lon) return 0;
// Convert to radians
const lat1 = point1.lat * Math.PI / 180;
const lat2 = point2.lat * Math.PI / 180;
const dLon = (point2.lon - point1.lon) * Math.PI / 180;
// Calculate bearing
const y = Math.sin(dLon) * Math.cos(lat2);
const x = Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
let bearing = Math.atan2(y, x) * 180 / Math.PI;
return (bearing + 360) % 360;
}
4. מיפוי כיוונים ידידותי למשתמש
כדי להפוך את חישובי הכיוונים לידידותיים יותר, אנו ממפים אותם לאמוג'ים כיווניים:
export function calculateOrientationEmoji(point1: GeoPoint, point2: GeoPoint): string {
const orientation = calculateOrientation(point1, point2);
// Map angles to 8-direction compass
if (orientation >= 337.5 || orientation < 22.5) return '⬆️';
if (orientation >= 22.5 && orientation < 67.5) return '↗️';
if (orientation >= 67.5 && orientation < 112.5) return '➡️';
if (orientation >= 112.5 && orientation < 157.5) return '↘️';
if (orientation >= 157.5 && orientation < 202.5) return '⬇️';
if (orientation >= 202.5 && orientation < 247.5) return '↙️';
if (orientation >= 247.5 && orientation < 292.5) return '⬅️';
return '↖️';
}
שיקולי ביצועים
- חזרות מוקדמות: אנו מבצעים חזרות מוקדמות עבור נקודות זהות כדי למנוע חישובים מיותרים.
- אופטימיזציה מתמדת: רדיוס כדור הארץ והמרות ממעלות לרדיאנים מחושבות מראש.
- שליטה על דיוק: המספרים מעוגלים למספר העשרוני המתאים כדי לאזן בין דיוק לביצועים.
טיפול בשגיאות ומקרים קיצוניים
היישום שלנו מטפל בכמה מקרים קיצוניים:
- נקודות זהות
- נקודות אנטיפולאריות
- נקודות בקוטביים
- חישובי חציית קו התאריך
אסטרטגיית בדיקה
ביצענו בדיקות מקיפות המכסות:
- חישובי מרחקים ידועים בין ערים גדולות
- מקרים קצהיים בקטרים ובקו התאריך הבינלאומי
- חישובי כיוון לנקודות קרדינליות ואינטר-קרדינליות
- בינוי ביצועים למשוב בזמן אמת
יישום בפועל
המערכת הזו יושם בהצלחה ב- Flagle Explorer, עובד על אלפי חישובים יומיומיים עם:
- זמן תגובה ממוצע < 5 מילישניות
- דיוק של 99.99% בהשוואה לחישובים המקוריים
- אף באגים קשורים לחישובים שאומרו בהפקה
אופטימיזציות עתידיות
אנו מבצעים בדיקות מספר שיפורים:
- מימוש WebAssembly לחישובים מורכבים
- אחסון למסלולים שחושבים בתדירות
- עיבוד בצמיתות לחישובי נקודות מרובות
- אינטגרציה עם נתוני גובה קרקע
מסקנה
בניית מערכת חישוב גיאוגרפית דורשת שיקול דעת זהיר לגבי דיוק מתמטי, אופטימיזציה של ביצועים וחוויית משתמש. היישום שלנו בTypeScript מאזן בהצלחה בין הגורמים הללו תוך שמירה על קריאות ותחזוקת הקוד.
רוצים לראות את החישובים האלה בפעולה? אתם יכולים לנסות אותם בFlagle Explorer ולצפות כיצד מדדי המרחק והכיוון מנחים אתכם דרך הגיאוגרפיה העולמית!
מאגר קוד
היישום המלא זמין בGitHub שלנו. הנה מדריך התחלה מהירה:
import { calculateDistance, calculateOrientationEmoji } from 'the-library/geo';
const london: GeoPoint = { lat: 51.5074, lon: -0.1278 };
const tokyo: GeoPoint = { lat: 35.6762, lon: 139.6503 };
const distance = calculateDistance(london, tokyo);
const direction = calculateOrientationEmoji(london, tokyo);
console.log(`Tokyo is ${distance}km ${direction} from London`);
יישום זה הוכיח את עצמו כעמיד בייצור, מטפל במיליוני חישובים תוך שמירה על ביצועים גבוהים וסטנדרטי דיוק.
Source:
https://dzone.com/articles/geographic-distance-calculator-using-typescript