Path: blob/main/public/games/files/garbage-collector/js/geometry/intersection.js
1036 views
/*globals define*/1define([2'utils'3], function( Utils ) {4'use strict';56/**7* Return if the two axis-aligned bounding-boxes intersect.8*/9function aabb( a, b ) {10return a.xmin <= b.xmax &&11a.xmax >= b.xmin &&12a.ymin <= b.ymax &&13a.ymax >= b.ymin;14}1516function linesParameter( x0, y0, x1, y1, x2, y2, x3, y3 ) {17var det = ( x1 - x0 ) * ( y3 - y2 ) - ( x3 - x2 ) * ( y1 - y0 );18if ( !det ) {19return null;20}2122return ( ( x3 - x2 ) * ( y0 - y2 ) - ( y3 - y2 ) * ( x0 - x2 ) ) / det;23}2425function lines( x0, y0, x1, y1, x2, y2, x3, y3 ) {26var t = linesParameter( x0, y0, x1, y1, x2, y2, x3, y3 );27return Utils.lerp2d( x0, y0, x1, y1, t );28}2930function segmentsParameter( x0, y0, x1, y1, x2, y2, x3, y3 ) {31var s = linesParameter( x0, y0, x1, y1, x2, y2, x3, y3 ),32t = linesParameter( x2, y2, x3, y3, x0, y0, x1, y1 );3334if ( s === null || t === null ) {35return null;36}3738if ( 0 > s || s > 1 ||390 > t || t > 1 ) {40return null;41}4243return t;44}4546function segments( x0, y0, x1, y1, x2, y2, x3, y3 ) {47var t = segmentsParameter( x0, y0, x1, y1, x2, y2, x3, y3 );48return Utils.lerp2d( x0, y0, x1, y1, t );49}5051function lineCircleParameter( x0, y0, x1, y1, cx, cy, r ) {52var dx = x1 - x0,53dy = y1 - y0;5455// Transform line to circle space.56x0 -= cx;57y0 -= cy;5859// Compute coefficients.60var a = ( dx * dx ) + ( dy * dy );61var b = 2 * ( x0 * dx + y0 * dy );62var c = ( x0 * x0 ) + ( y0 * y0 ) - ( r * r );6364// Compute discriminant.65var d = b * b - 4 * a * c;6667// No intersection.68if ( d < 0 ) {69return [];70}7172// One intersection.73if ( !d ) {74return [ -b / ( 2 * a ) ];75}7677d = Math.sqrt( d );7879// Two intersections.80return [81( -b - d ) / ( 2 * a ),82( -b + d ) / ( 2 * a )83];84}8586function lineCircle( x0, y0, x1, y1, cx, cy, r ) {87return lineCircleParameter( x0, y0, x1, y1, cx, cy, r ).map(function( t ) {88return Utils.lerp2d( x0, y0, x1, y1, t );89});90}9192function segmentCircleParameter( x0, y0, x1, y1, cx, cy, r ) {93return lineCircleParameter( x0, y0, x1, y1, cx, cy, r ).filter(function( t ) {94return 0 <= t && t <= 1;95});96}9798function segmentCircle( x0, y0, x1, y1, cx, cy, r ) {99return segmentCircleParameter( x0, y0, x1, y1, cx, cy, r ).map(function( t ) {100return Utils.lerp2d( x0, y0, x1, y1, t );101});102}103104function closestPointOnLineParameter( x, y, x0, y0, x1, y1 ) {105var dx = x1 - x0,106dy = y1 - y0;107108// Check for line degeneracy.109if ( !dx && !dy ) {110return null;111}112113var lengthSquared = dx * dx + dy * dy;114115return ( ( x - x0 ) * ( x1 - x0 ) + ( y - y0 ) * ( y1 - y0 ) ) / lengthSquared;116}117118function closestPointOnLine( x, y, x0, y0, x1, y1 ) {119var t = closestPointOnLineParameter( x, y, x0, y0, x1, y1 );120return Utils.lerp2d( x0, y0, x1, y1, t );121}122123function closestPointOnSegment( x, y, x0, y0, x1, y1 ) {124var t = closestPointOnLineParameter( x, y, x0, y0, x1, y1 );125126if ( 0 > t ) {127return {128x: x0,129y: y0130};131}132133if ( t > 1 ) {134return {135x: x1,136y: y1137};138}139140return Utils.lerp2d( x0, y0, x1, y1, t );141}142143function closestPointOnCircle( x, y, cx, cy, radius ) {144var angle = Utils.angleFrom( cx, cy, x, y );145return {146x: cx + Math.cos( angle ) * radius,147y: cy + Math.sin( angle ) * radius148};149}150151return {152aabb: aabb,153154linesParameter: linesParameter,155lines: lines,156157segmentsParameter: segmentsParameter,158segments: segments,159160lineCircleParameter: lineCircleParameter,161lineCircle: lineCircle,162163segmentCircleParameter: segmentCircleParameter,164segmentCircle: segmentCircle,165166closestPointOnLineParameter: closestPointOnLineParameter,167closestPointOnLine: closestPointOnLine,168closestPointOnSegment: closestPointOnSegment,169170closestPointOnCircle: closestPointOnCircle171};172});173174175