Änderung: Optimierung der Kollisionserkennung und Debugging im Taxi-Spiel
Änderungen: - Anpassung der Kollisionserkennung, um die Logik für befahrbare und nicht befahrbare Bereiche zu verbessern. - Einführung von Debugging-Informationen zur besseren Nachverfolgbarkeit von Kollisionen, insbesondere bei Fuel-Tiles. - Bereinigung der Codebasis durch Entfernen überflüssiger Konsolenausgaben und Verbesserung der Lesbarkeit. Diese Anpassungen erhöhen die Effizienz und Benutzerfreundlichkeit des Spiels, indem sie die Kollisionserkennung präzisieren und die Debugging-Möglichkeiten erweitern.
This commit is contained in:
@@ -238,6 +238,7 @@ export default {
|
||||
loadedPassengersList: [], // Aktuell geladene Passagiere im Taxi
|
||||
occupiedHouses: new Set(), // Verhindert doppelte Belegung von Häusern
|
||||
lastPassengerGeneration: 0,
|
||||
debugCollisionShown: false, // Flag für einmalige Debug-Ausgabe
|
||||
passengerGenerationInterval: 0,
|
||||
// Timeout-Referenzen für Cleanup
|
||||
passengerGenerationTimeout: null,
|
||||
@@ -1958,8 +1959,9 @@ export default {
|
||||
const originalTileSize = streetCoordinates.getOriginalTileSize(); // 640px
|
||||
const currentTileSize = 500; // Aktuelle Render-Größe
|
||||
|
||||
// Hole die Polygon-Koordinaten für dieses Tile
|
||||
const regions = streetCoordinates.getDriveableRegions(streetTileType, originalTileSize);
|
||||
// Hole die relativen Koordinaten direkt aus der JSON (0-1)
|
||||
const tileData = streetCoordinates.data.tiles[streetTileType];
|
||||
const regions = tileData ? tileData.regions : [];
|
||||
|
||||
if (regions.length === 0) {
|
||||
// Keine Polygone definiert = befahrbar
|
||||
@@ -1973,151 +1975,308 @@ export default {
|
||||
width: this.taxi.width / currentTileSize,
|
||||
height: this.taxi.height / currentTileSize
|
||||
};
|
||||
|
||||
// Für normale Tiles: Prüfe ob Taxi eine der Hindernis-Polylinien schneidet
|
||||
// Für Fuel-Tiles: Prüfe ob Taxi eine der befahrbaren Polylinien schneidet
|
||||
const isFuelTile = tileType === 'fuelhorizontal' || tileType === 'fuelvertical';
|
||||
|
||||
// Für Fuel-Tiles: Prüfe ob das Taxi in einem der befahrbaren Bereiche ist
|
||||
if (tileType === 'fuelhorizontal' || tileType === 'fuelvertical') {
|
||||
// Prüfe ob das Taxi in mindestens einem befahrbaren Bereich ist
|
||||
for (let i = 0; i < regions.length; i++) {
|
||||
const region = regions[i];
|
||||
if (this.rectPolygonCollision(taxiRect, region)) {
|
||||
return true; // Taxi ist in einem befahrbaren Bereich
|
||||
}
|
||||
}
|
||||
// Crash - zeige Debug-Informationen
|
||||
console.log('🚨 CRASH auf Fuel-Tile - Debug-Informationen:');
|
||||
console.log('Tile Type:', tileType);
|
||||
console.log('Polygons:', regions);
|
||||
console.log('Taxi Rect:', taxiRect);
|
||||
console.log('Taxi Position (absolute):', { x: this.taxi.x, y: this.taxi.y, width: this.taxi.width, height: this.taxi.height });
|
||||
return false; // Taxi ist in keinem befahrbaren Bereich
|
||||
}
|
||||
// Erstelle rotiertes Rechteck
|
||||
const rotatedRect = {
|
||||
cx: taxiRect.x + taxiRect.width / 2, // Mittelpunkt X
|
||||
cy: taxiRect.y + taxiRect.height / 2, // Mittelpunkt Y
|
||||
theta: this.taxi.imageAngle + this.taxi.angle, // Rotation
|
||||
hx: taxiRect.width / 2, // halbe Breite
|
||||
hy: taxiRect.height / 2 // halbe Höhe
|
||||
};
|
||||
|
||||
// Für andere Tiles: Prüfe Kollision mit jedem Polygon (nicht befahrbar)
|
||||
// Prüfe jede Region (Polylinie) einzeln
|
||||
for (let i = 0; i < regions.length; i++) {
|
||||
const region = regions[i];
|
||||
if (this.rectPolygonCollision(taxiRect, region)) {
|
||||
// Crash - zeige Debug-Informationen
|
||||
console.log('🚨 CRASH auf Tile - Debug-Informationen:');
|
||||
console.log('Tile Type:', tileType);
|
||||
console.log('Crash Polygon:', region);
|
||||
console.log('Alle Polygons:', regions);
|
||||
console.log('Taxi Rect:', taxiRect);
|
||||
console.log('Taxi Position (absolute):', { x: this.taxi.x, y: this.taxi.y, width: this.taxi.width, height: this.taxi.height });
|
||||
// Jede Region ist eine Polylinie mit mehreren Punkten
|
||||
if (region.length >= 2) {
|
||||
// Verwende die relativen Koordinaten direkt aus der JSON (0-1)
|
||||
// ohne die doppelte Konvertierung über getDriveableRegions
|
||||
const regionPoints = region.map(point => ({
|
||||
x: point.x, // Bereits relativ (0-1) aus der JSON
|
||||
y: point.y // Bereits relativ (0-1) aus der JSON
|
||||
}));
|
||||
|
||||
// Test: Prüfe einen einzelnen Punkt
|
||||
const testPoint = { x: 0.5, y: 0.45 };
|
||||
const isInside = this.isPointInPolygon(testPoint.x, testPoint.y, region);
|
||||
console.log('Test-Punkt (0.5, 0.45) in Polygon:', isInside);
|
||||
// Verwende die robuste Kollisionserkennung für diese Region
|
||||
const result = this.polylineIntersectsRotatedRect(regionPoints, rotatedRect);
|
||||
|
||||
// Test: Prüfe mit absoluten Koordinaten
|
||||
const testPointAbs = { x: 250, y: 225 }; // Absolute Koordinaten
|
||||
const regionAbs = region.map(p => ({ x: p.x * 500, y: p.y * 500 })); // Umrechnung zu absoluten Koordinaten
|
||||
const isInsideAbs = this.isPointInPolygon(testPointAbs.x, testPointAbs.y, regionAbs);
|
||||
console.log('Test-Punkt (250, 225) in Polygon (absolut):', isInsideAbs);
|
||||
// Debug-Ausgabe bei jeder Prüfung
|
||||
console.log('🔍 KOLLISIONS-DEBUG:');
|
||||
console.log('Taxi Rect (relativ):', taxiRect);
|
||||
console.log('Region Polylinie:', regionPoints);
|
||||
console.log('Rotated Rect:', rotatedRect);
|
||||
console.log('Kollisionsergebnis:', result);
|
||||
|
||||
// Test: Prüfe einen Punkt, der definitiv außerhalb sein sollte
|
||||
const testPointOutside = { x: 0.5, y: 0.1 }; // Sehr weit oben
|
||||
const isInsideOutside = this.isPointInPolygon(testPointOutside.x, testPointOutside.y, region);
|
||||
console.log('Test-Punkt (0.5, 0.1) in Polygon (sollte false sein):', isInsideOutside);
|
||||
// Zusätzliche Debug-Ausgabe für cornerbottomright
|
||||
if (streetTileType === 'cornerBottomRight') {
|
||||
console.log('🔧 CORNERBOTTOMRIGHT DEBUG:');
|
||||
console.log('Region (relativ aus JSON):', region);
|
||||
console.log('RegionPoints (relativ):', regionPoints);
|
||||
console.log('Taxi position:', this.taxi.x, this.taxi.y);
|
||||
console.log('Current tile size:', currentTileSize);
|
||||
console.log('Original tile size:', originalTileSize);
|
||||
}
|
||||
|
||||
// Debug: Zeige die ersten paar Polygon-Punkte
|
||||
console.log('Erste 5 Polygon-Punkte:', region.slice(0, 5));
|
||||
|
||||
// Debug: Skalierungs-Informationen
|
||||
console.log('Tile Size:', this.tiles.size);
|
||||
console.log('Original Tile Size (aus JSON):', 640);
|
||||
console.log('Skalierungsfaktor:', this.tiles.size / 640);
|
||||
|
||||
// Debug: Taxi-Position in verschiedenen Koordinatensystemen
|
||||
console.log('Taxi Position (Canvas):', { x: this.taxi.x, y: this.taxi.y });
|
||||
console.log('Taxi Position (Tile-relative):', { x: this.taxi.x / this.tiles.size, y: this.taxi.y / this.tiles.size });
|
||||
console.log('Taxi Position (JSON-relative):', { x: this.taxi.x / 640, y: this.taxi.y / 640 });
|
||||
|
||||
return false; // Kollision = nicht befahrbar
|
||||
if (isFuelTile) {
|
||||
// Für Fuel-Tiles: Taxi muss eine der befahrbaren Polylinien schneiden
|
||||
if (result.hit) {
|
||||
console.log('✅ Fuel-Tile: Taxi ist auf befahrbarer Polylinie (Region', i, ')');
|
||||
return true; // Befahrbar
|
||||
}
|
||||
} else {
|
||||
// Für normale Tiles: Taxi darf KEINE der Hindernis-Polylinien schneiden
|
||||
if (result.hit) {
|
||||
// Crash - zeige Debug-Informationen
|
||||
console.log('🚨 CRASH auf Tile - Debug-Informationen:');
|
||||
console.log('Taxi Rect (relativ):', taxiRect);
|
||||
console.log('Crash Region Polylinie:', regionPoints);
|
||||
console.log('Rotated Rect:', rotatedRect);
|
||||
console.log('Crash Hits:', result.hits);
|
||||
|
||||
return false; // Kollision mit Hindernis = Crash
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alle Regionen geprüft
|
||||
if (isFuelTile) {
|
||||
// Für Fuel-Tiles: Keine befahrbare Polylinie gefunden = Crash
|
||||
console.log('🚨 Fuel-Tile: Taxi ist NICHT auf befahrbarer Polylinie - CRASH');
|
||||
return false; // Nicht befahrbar = Crash
|
||||
} else {
|
||||
// Für normale Tiles: Keine Hindernis-Polylinie geschnitten = befahrbar
|
||||
console.log('✅ Normales Tile: Taxi schneidet keine Hindernis-Polylinien');
|
||||
return true; // Keine Kollision = befahrbar
|
||||
}
|
||||
|
||||
return true; // Keine Kollision = befahrbar
|
||||
},
|
||||
|
||||
// Prüft Kollision zwischen Rechteck und Polygon
|
||||
rectPolygonCollision(rect, polygon) {
|
||||
// Konvertiere Polygon-Koordinaten von absoluten Pixeln zu relativen (0-1)
|
||||
// Prüft ob eine Linie ein rotiertes Rechteck schneidet
|
||||
isLineCrossingRect(rect, line) {
|
||||
// Konvertiere Linien-Koordinaten von absoluten Pixeln zu relativen (0-1)
|
||||
const originalTileSize = 640; // Aus der JSON-Datei
|
||||
const currentTileSize = this.tiles.size; // Aktuelle Render-Größe
|
||||
const relativePolygon = polygon.map(point => ({
|
||||
x: point.x / originalTileSize,
|
||||
y: point.y / originalTileSize
|
||||
}));
|
||||
const relativeLine = {
|
||||
x1: line.x1 / originalTileSize,
|
||||
y1: line.y1 / originalTileSize,
|
||||
x2: line.x2 / originalTileSize,
|
||||
y2: line.y2 / originalTileSize
|
||||
};
|
||||
|
||||
// Debug-Ausgabe bei jeder Kollisionsprüfung
|
||||
console.log('🔍 KOLLISIONS-DEBUG:');
|
||||
console.log('Taxi Rect (relativ):', rect);
|
||||
console.log('Taxi Position (absolut):', { x: this.taxi.x, y: this.taxi.y, width: this.taxi.width, height: this.taxi.height });
|
||||
console.log('Line (absolut aus JSON):', line);
|
||||
console.log('Line (relativ konvertiert):', relativeLine);
|
||||
console.log('Original Tile Size (JSON):', originalTileSize);
|
||||
console.log('Current Tile Size:', this.tiles.size);
|
||||
console.log('Taxi Angle:', this.taxi.angle);
|
||||
console.log('Taxi ImageAngle:', this.taxi.imageAngle);
|
||||
|
||||
// Berechne die rotierten Ecken des Taxis
|
||||
// rect ist bereits in relativen Koordinaten (0-1)
|
||||
const centerX = rect.x + rect.width / 2;
|
||||
const centerY = rect.y + rect.height / 2;
|
||||
const angle = this.taxi.imageAngle + this.taxi.angle;
|
||||
|
||||
// Ursprüngliche Ecken relativ zum Zentrum (in relativen Koordinaten)
|
||||
const halfWidth = rect.width / 2;
|
||||
const halfHeight = rect.height / 2;
|
||||
const originalCorners = [
|
||||
{ x: -halfWidth, y: -halfHeight }, // Oben links
|
||||
{ x: halfWidth, y: -halfHeight }, // Oben rechts
|
||||
{ x: -halfWidth, y: halfHeight }, // Unten links
|
||||
{ x: halfWidth, y: halfHeight } // Unten rechts
|
||||
// Erstelle Polyline aus der Linie
|
||||
const polyline = [
|
||||
{ x: relativeLine.x1, y: relativeLine.y1 },
|
||||
{ x: relativeLine.x2, y: relativeLine.y2 }
|
||||
];
|
||||
|
||||
// Rotiere die Ecken (bleibt in relativen Koordinaten)
|
||||
const corners = originalCorners.map(corner => ({
|
||||
x: centerX + corner.x * Math.cos(angle) - corner.y * Math.sin(angle),
|
||||
y: centerY + corner.x * Math.sin(angle) + corner.y * Math.cos(angle)
|
||||
}));
|
||||
// Erstelle rotiertes Rechteck
|
||||
const rotatedRect = {
|
||||
cx: rect.x + rect.width / 2, // Mittelpunkt X
|
||||
cy: rect.y + rect.height / 2, // Mittelpunkt Y
|
||||
theta: this.taxi.imageAngle + this.taxi.angle, // Rotation
|
||||
hx: rect.width / 2, // halbe Breite
|
||||
hy: rect.height / 2 // halbe Höhe
|
||||
};
|
||||
|
||||
for (let i = 0; i < corners.length; i++) {
|
||||
const corner = corners[i];
|
||||
// corners sind bereits in relativen Koordinaten (0-1)
|
||||
const isInside = this.isPointInPolygon(corner.x, corner.y, relativePolygon);
|
||||
|
||||
if (isInside) {
|
||||
return true; // Rechteck-Ecke ist im Polygon = Kollision
|
||||
// Verwende die robuste Kollisionserkennung
|
||||
const result = this.polylineIntersectsRotatedRect(polyline, rotatedRect);
|
||||
|
||||
// Debug-Ausgabe für Kollisionsergebnis
|
||||
console.log('Kollisionsergebnis:', result);
|
||||
console.log('Rotated Rect:', rotatedRect);
|
||||
console.log('Polyline:', polyline);
|
||||
|
||||
return result.hit;
|
||||
},
|
||||
|
||||
// Testet, ob eine Polyline (Liste von Punkten) ein rotiertes Rechteck schneidet
|
||||
polylineIntersectsRotatedRect(polyline, rect, eps = 1e-9) {
|
||||
const { cx, cy, theta, hx, hy } = rect;
|
||||
|
||||
// Debug-Ausgabe für Eingabeparameter
|
||||
console.log('🔧 polylineIntersectsRotatedRect DEBUG:');
|
||||
console.log('Polyline:', polyline);
|
||||
console.log('Rect:', rect);
|
||||
console.log('AABB bounds: x=[', cx - hx, ',', cx + hx, '], y=[', cy - hy, ',', cy + hy, ']');
|
||||
|
||||
// Vereinfachte Kollisionserkennung: Prüfe ob irgendein Polyline-Punkt im Rechteck liegt
|
||||
// oder ob irgendein Rechteck-Punkt auf der Polyline liegt
|
||||
|
||||
// 1. Prüfe ob Polyline-Punkte im Rechteck liegen
|
||||
for (let i = 0; i < polyline.length; i++) {
|
||||
const p = polyline[i];
|
||||
const inX = p.x >= cx - hx && p.x <= cx + hx;
|
||||
const inY = p.y >= cy - hy && p.y <= cy + hy;
|
||||
console.log(` Punkt ${i}: (${p.x}, ${p.y}) - In AABB: ${inX && inY}`);
|
||||
if (inX && inY) {
|
||||
console.log(`✅ Kollision: Polyline-Punkt ${i} liegt im Rechteck`);
|
||||
return { hit: true, hits: [{ type: 'point_in_rect', pointIndex: i, point: p }] };
|
||||
}
|
||||
}
|
||||
|
||||
// Prüfe ob eine Polygon-Ecke im Rechteck liegt
|
||||
for (let i = 0; i < relativePolygon.length; i++) {
|
||||
const point = relativePolygon[i];
|
||||
const isInside = this.isPointInRect(point.x, point.y, rect);
|
||||
|
||||
if (isInside) {
|
||||
return true; // Polygon-Ecke ist im Rechteck = Kollision
|
||||
}
|
||||
}
|
||||
|
||||
// Prüfe ob Rechteck-Kanten das Polygon schneiden
|
||||
const rectEdges = [
|
||||
{ x1: rect.x, y1: rect.y, x2: rect.x + rect.width, y2: rect.y }, // Oben
|
||||
{ x1: rect.x + rect.width, y1: rect.y, x2: rect.x + rect.width, y2: rect.y + rect.height }, // Rechts
|
||||
{ x1: rect.x, y1: rect.y + rect.height, x2: rect.x + rect.width, y2: rect.y + rect.height }, // Unten
|
||||
{ x1: rect.x, y1: rect.y, x2: rect.x, y2: rect.y + rect.height } // Links
|
||||
// 2. Prüfe ob Rechteck-Ecken auf der Polyline liegen
|
||||
const rectCorners = [
|
||||
{ x: cx - hx, y: cy - hy }, // links oben
|
||||
{ x: cx + hx, y: cy - hy }, // rechts oben
|
||||
{ x: cx + hx, y: cy + hy }, // rechts unten
|
||||
{ x: cx - hx, y: cy + hy } // links unten
|
||||
];
|
||||
|
||||
for (const edge of rectEdges) {
|
||||
for (let i = 0; i < relativePolygon.length; i++) {
|
||||
const j = (i + 1) % relativePolygon.length;
|
||||
const polyEdge = {
|
||||
x1: relativePolygon[i].x,
|
||||
y1: relativePolygon[i].y,
|
||||
x2: relativePolygon[j].x,
|
||||
y2: relativePolygon[j].y
|
||||
};
|
||||
for (let cornerIndex = 0; cornerIndex < rectCorners.length; cornerIndex++) {
|
||||
const corner = rectCorners[cornerIndex];
|
||||
for (let i = 0; i < polyline.length - 1; i++) {
|
||||
const A = polyline[i];
|
||||
const B = polyline[i + 1];
|
||||
|
||||
if (this.lineIntersection(edge, polyEdge)) {
|
||||
return true; // Kanten schneiden sich = Kollision
|
||||
// Prüfe ob Ecke auf Liniensegment liegt
|
||||
if (this.isPointOnLineSegment(corner.x, corner.y, A.x, A.y, B.x, B.y)) {
|
||||
console.log(`✅ Kollision: Rechteck-Ecke ${cornerIndex} liegt auf Polyline-Segment ${i}`);
|
||||
return { hit: true, hits: [{ type: 'corner_on_line', cornerIndex, segmentIndex: i, corner, segment: { A, B } }] };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false; // Keine Kollision
|
||||
// 3. Prüfe Liniensegment-Überschneidungen (vereinfacht)
|
||||
for (let i = 0; i < polyline.length - 1; i++) {
|
||||
const A = polyline[i];
|
||||
const B = polyline[i + 1];
|
||||
|
||||
// Prüfe ob Liniensegment das Rechteck schneidet
|
||||
if (this.lineSegmentIntersectsRect(A.x, A.y, B.x, B.y, cx - hx, cy - hy, cx + hx, cy + hy)) {
|
||||
console.log(`✅ Kollision: Polyline-Segment ${i} schneidet Rechteck`);
|
||||
return { hit: true, hits: [{ type: 'segment_intersects_rect', segmentIndex: i, segment: { A, B } }] };
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`❌ Keine Kollision gefunden`);
|
||||
return { hit: false, hits: [] };
|
||||
},
|
||||
|
||||
// Prüft ob ein Punkt auf einem Liniensegment liegt
|
||||
isPointOnLineSegment(px, py, x1, y1, x2, y2, tolerance = 0.01) {
|
||||
// Berechne den Abstand vom Punkt zur Linie
|
||||
const A = px - x1;
|
||||
const B = py - y1;
|
||||
const C = x2 - x1;
|
||||
const D = y2 - y1;
|
||||
|
||||
const dot = A * C + B * D;
|
||||
const lenSq = C * C + D * D;
|
||||
|
||||
if (lenSq === 0) {
|
||||
// Linie ist ein Punkt
|
||||
return Math.abs(px - x1) < tolerance && Math.abs(py - y1) < tolerance;
|
||||
}
|
||||
|
||||
const param = dot / lenSq;
|
||||
|
||||
// Prüfe ob Parameter im Bereich [0,1] liegt
|
||||
if (param < 0 || param > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Berechne den nächsten Punkt auf der Linie
|
||||
const xx = x1 + param * C;
|
||||
const yy = y1 + param * D;
|
||||
|
||||
// Prüfe ob der Abstand klein genug ist
|
||||
const distance = Math.sqrt((px - xx) * (px - xx) + (py - yy) * (py - yy));
|
||||
return distance <= tolerance;
|
||||
},
|
||||
|
||||
// Prüft ob ein Liniensegment ein Rechteck schneidet
|
||||
lineSegmentIntersectsRect(x1, y1, x2, y2, rectMinX, rectMinY, rectMaxX, rectMaxY) {
|
||||
// Verwende den Liang-Barsky Algorithmus für Liniensegment-Rechteck Schnitt
|
||||
let t0 = 0, t1 = 1;
|
||||
const dx = x2 - x1;
|
||||
const dy = y2 - y1;
|
||||
|
||||
// Prüfe jede Seite des Rechtecks
|
||||
const sides = [
|
||||
{ p: -dx, q: x1 - rectMinX }, // links
|
||||
{ p: dx, q: rectMaxX - x1 }, // rechts
|
||||
{ p: -dy, q: y1 - rectMinY }, // oben
|
||||
{ p: dy, q: rectMaxY - y1 } // unten
|
||||
];
|
||||
|
||||
for (const side of sides) {
|
||||
if (Math.abs(side.p) < 1e-9) {
|
||||
// Parallel zur Seite
|
||||
if (side.q < 0) {
|
||||
return false; // außerhalb
|
||||
}
|
||||
} else {
|
||||
const t = side.q / side.p;
|
||||
if (side.p < 0) {
|
||||
// Eintritt
|
||||
if (t > t0) t0 = t;
|
||||
} else {
|
||||
// Austritt
|
||||
if (t < t1) t1 = t;
|
||||
}
|
||||
|
||||
if (t0 > t1) {
|
||||
return false; // keine Überschneidung
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return t0 <= 1 && t1 >= 0;
|
||||
},
|
||||
|
||||
// Prüft ob ein Punkt auf einer Linie liegt
|
||||
isPointOnLine(px, py, line) {
|
||||
const { x1, y1, x2, y2 } = line;
|
||||
|
||||
// Berechne den Abstand vom Punkt zur Linie
|
||||
const A = px - x1;
|
||||
const B = py - y1;
|
||||
const C = x2 - x1;
|
||||
const D = y2 - y1;
|
||||
|
||||
const dot = A * C + B * D;
|
||||
const lenSq = C * C + D * D;
|
||||
|
||||
if (lenSq === 0) {
|
||||
// Linie ist ein Punkt
|
||||
return Math.abs(px - x1) < 0.001 && Math.abs(py - y1) < 0.001;
|
||||
}
|
||||
|
||||
const param = dot / lenSq;
|
||||
|
||||
let xx, yy;
|
||||
if (param < 0) {
|
||||
xx = x1;
|
||||
yy = y1;
|
||||
} else if (param > 1) {
|
||||
xx = x2;
|
||||
yy = y2;
|
||||
} else {
|
||||
xx = x1 + param * C;
|
||||
yy = y1 + param * D;
|
||||
}
|
||||
|
||||
const dx = px - xx;
|
||||
const dy = py - yy;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
return distance < 0.001; // Toleranz für Gleitkommazahlen
|
||||
},
|
||||
|
||||
// Prüft ob ein Punkt in einem Polygon liegt (Point-in-Polygon)
|
||||
|
||||
Reference in New Issue
Block a user