import { add , distance2 , set , sub , v2 , dot , scale , distance , copy , normalize , Vector2 } from "./v2" ; import { collideCircleCircle } from "./collide-circle-circle" ; import { VelocityDerivable } from "./common-types" ; const edgeDir = v2 ( ) ; const edge = v2 ( ) ; const prevEdge = v2 ( ) ; const hypo = v2 ( ) ; const epDiff = v2 ( ) ; const correction = v2 ( ) ; const collisionPoint = v2 ( ) ; const tunnelPoint = v2 ( ) ; const ep = { cpos : v2 ( ) , ppos : v2 ( ) } ; const epBefore = { cpos : v2 ( ) , ppos : v2 ( ) } ; export function collideCircleEdge ( circle , radius3 , mass3 , endpoint1 , mass1 , endpoint2 , mass2 , preserveInertia , damping ) { sub ( edge , endpoint2 . cpos , endpoint1 . cpos ) ; normalize ( edgeDir , edge ) ; sub ( hypo , circle . cpos , endpoint1 . cpos ) ; const projection = dot ( edge , hypo ) ; const maxDot = dot ( edge , edge ) ; const edgeMag = Math . sqrt ( maxDot ) ; if ( projection < 0 || projection > maxDot ) return ; const t = projection / maxDot ; const u = 1 - t ; scale ( collisionPoint , edgeDir , t * edgeMag ) ; add ( collisionPoint , collisionPoint , endpoint1 . cpos ) ; const dist = distance ( collisionPoint , circle . cpos ) ; if ( dist > radius3 ) return ; const standinMass1 = u * mass3 ; const standinMass2 = t * mass3 ; const standin1 = { cpos : v2 ( ) , ppos : v2 ( ) } ; const standin2 = { cpos : v2 ( ) , ppos : v2 ( ) } ; scale ( standin1 . cpos , edgeDir , t * edgeMag ) ; sub ( standin1 . cpos , circle . cpos , standin1 . cpos ) ; scale ( standin1 . ppos , edgeDir , t * edgeMag ) ; sub ( standin1 . ppos , circle . ppos , standin1 . ppos ) ; scale ( standin2 . cpos , edgeDir , u * edgeMag ) ; add ( standin2 . cpos , circle . cpos , standin2 . cpos ) ; scale ( standin2 . ppos , edgeDir , u * edgeMag ) ; add ( standin2 . ppos , circle . ppos , standin2 . ppos ) ; const standin1Before = { cpos : v2 ( ) , ppos : v2 ( ) } ; const standin2Before = { cpos : v2 ( ) , ppos : v2 ( ) } ; copy ( standin1Before . cpos , standin1 . cpos ) ; copy ( standin1Before . ppos , standin1 . ppos ) ; copy ( standin2Before . cpos , standin2 . cpos ) ; copy ( standin2Before . ppos , standin2 . ppos ) ; const edgeRadius = 0 ; collideCircleCircle ( standin1 , radius3 , standinMass1 , endpoint1 , edgeRadius , mass1 , preserveInertia , damping ) ; collideCircleCircle ( standin2 , radius3 , standinMass2 , endpoint2 , edgeRadius , mass2 , preserveInertia , damping ) ; const standin1Delta = { cpos : v2 ( ) , ppos : v2 ( ) } ; const standin2Delta = { cpos : v2 ( ) , ppos : v2 ( ) } ; sub ( standin1Delta . cpos , standin1 . cpos , standin1Before . cpos ) ; sub ( standin2Delta . cpos , standin2 . cpos , standin2Before . cpos ) ; scale ( standin1Delta . cpos , standin1Delta . cpos , u ) ; scale ( standin2Delta . cpos , standin2Delta . cpos , t ) ; add ( circle . cpos , circle . cpos , standin1Delta . cpos ) ; add ( circle . cpos , circle . cpos , standin2Delta . cpos ) ; if ( ! preserveInertia ) return ; sub ( standin1Delta . ppos , standin1 . ppos , standin1Before . ppos ) ; sub ( standin2Delta . ppos , standin2 . ppos , standin2Before . ppos ) ; scale ( standin1Delta . ppos , standin1Delta . ppos , u ) ; scale ( standin2Delta . ppos , standin2Delta . ppos , t ) ; add ( circle . ppos , circle . ppos , standin1Delta . ppos ) ; add ( circle . ppos , circle . ppos , standin2Delta . ppos ) ; } type Particle = { mass : number ; radius : number ; } & VelocityDerivable ; function snapshotDebug ( name , particles = [ ] , points = [ ] ) { const cvs = document . createElement ( "canvas" ) ; const ctx = cvs . getContext ( "2d" ) ! ; document . body . appendChild ( cvs ) ; cvs . width = 800 ; cvs . height = 800 ; for ( let i = 0 ; i < particles . length ; i ++ ) { const particle = particles [ i ] ; ctx . fillStyle = "rgba(255, 0, 0, 0.5)" ; ctx . beginPath ( ) ; ctx . arc ( particle . ppos . x , particle . ppos . y , particle . radius , 0 , Math . PI * 2 , false ) ; ctx . fill ( ) ; ctx . fillStyle = "rgba(0, 0, 0, 0.5)" ; ctx . beginPath ( ) ; ctx . arc ( particle . cpos . x , particle . cpos . y , particle . radius , 0 , Math . PI * 2 , false ) ; ctx . fill ( ) ; } for ( let i = 0 ; i < points . length ; i ++ ) { const [ name , point ] = points [ i ] ; ctx . fillStyle = "purple" ; ctx . fillRect ( point . x , point . y , 1 , 1 ) ; ctx . fillText ( `${ name } (${ point . x },${ point . y })` , point . x + 1 , point . y + 1 ) ; } ctx . fillStyle = "black" ; ctx . fillText ( name , 10 , 10 ) ; }