1
- import { isNumber } from "@thi.ng/checks/is-number" ;
2
1
import type { MultiFn2O } from "@thi.ng/defmulti" ;
3
2
import { defmulti } from "@thi.ng/defmulti/defmulti" ;
4
3
import type { IShape , IntersectionResult , PCLike } from "@thi.ng/geom-api" ;
@@ -17,13 +16,18 @@ import {
17
16
import { intersectRayAABB , intersectRayRect } from "@thi.ng/geom-isec/ray-rect" ;
18
17
import { testRectCircle } from "@thi.ng/geom-isec/rect-circle" ;
19
18
import { testAabbAabb , testRectRect } from "@thi.ng/geom-isec/rect-rect" ;
20
- import { dist2 , type Vec } from "@thi.ng/vectors" ;
19
+ import type { Vec } from "@thi.ng/vectors" ;
20
+ import { dist2 } from "@thi.ng/vectors/dist" ;
21
+ import { distSq2 } from "@thi.ng/vectors/distsq" ;
22
+ import { magSq2 } from "@thi.ng/vectors/magsq" ;
23
+ import { normalize2 } from "@thi.ng/vectors/normalize" ;
24
+ import { sub2 } from "@thi.ng/vectors/sub" ;
21
25
import type { AABB } from "./api/aabb.js" ;
22
26
import type { Circle } from "./api/circle.js" ;
23
27
import type { Group } from "./api/group.js" ;
24
28
import type { Line } from "./api/line.js" ;
25
29
import type { Plane } from "./api/plane.js" ;
26
- import type { Ray } from "./api/ray.js" ;
30
+ import { Ray } from "./api/ray.js" ;
27
31
import type { Rect } from "./api/rect.js" ;
28
32
import type { Sphere } from "./api/sphere.js" ;
29
33
import { __dispatch2 } from "./internal/dispatch.js" ;
@@ -43,6 +47,7 @@ export interface IntersectOpts {
43
47
* Currently supported pairs:
44
48
*
45
49
* - {@link Circle} / {@link Circle }
50
+ * - {@link Line } / {@link Group }
46
51
* - {@link Line } / {@link Line }
47
52
* - {@link Line } / {@link Polygon }
48
53
* - {@link Line } / {@link Polyline }
@@ -96,6 +101,27 @@ export const intersects: MultiFn2O<
96
101
"circle-circle" : ( a : Circle , b : Circle ) =>
97
102
intersectCircleCircle ( a . pos , b . pos , a . r , b . r ) ,
98
103
104
+ "line-group" : (
105
+ { points : [ a , b ] } : Line ,
106
+ group : Group ,
107
+ opts ?: Partial < IntersectOpts >
108
+ ) => {
109
+ const dir = sub2 ( [ ] , b , a ) ;
110
+ const max = magSq2 ( dir ) ;
111
+ const res = intersects (
112
+ new Ray ( a , normalize2 ( null , dir ) ) ,
113
+ group ,
114
+ opts
115
+ ) ;
116
+ if ( res === NONE ) return res ;
117
+ res . isec = res . isec ! . filter ( ( p ) => distSq2 ( a , p ) <= max ) ;
118
+ if ( res . isec . length ) {
119
+ res . alpha = dist2 ( a , res . isec ! [ 0 ] ) ;
120
+ return res ;
121
+ }
122
+ return NONE ;
123
+ } ,
124
+
99
125
"line-line" : ( { points : a } : Line , { points : b } : Line ) =>
100
126
intersectLineLine ( a [ 0 ] , a [ 1 ] , b [ 0 ] , b [ 1 ] ) ,
101
127
@@ -114,22 +140,26 @@ export const intersects: MultiFn2O<
114
140
"ray-circle" : ( ray : Ray , sphere : Sphere ) =>
115
141
intersectRayCircle ( ray . pos , ray . dir , sphere . pos , sphere . r ) ,
116
142
117
- "ray-group" : ( ray : Ray , { children } : Group , opts ?: IntersectOpts ) => {
143
+ "ray-group" : (
144
+ ray : Ray ,
145
+ { children } : Group ,
146
+ opts ?: Partial < IntersectOpts >
147
+ ) => {
118
148
let minD = Infinity ;
119
149
const points : Vec [ ] = [ ] ;
120
150
const all = opts ?. all ;
151
+ let inside = false ;
121
152
for ( let child of children ) {
122
153
let $res = intersects ( ray , child , opts ) ;
123
154
if ( $res . type !== IntersectionType . INTERSECT ) continue ;
124
- const single = isNumber ( $res . isec ! [ 0 ] ) ;
125
- const first = single ? < Vec > $res . isec : ( < Vec [ ] > $res . isec ) [ 0 ] ;
155
+ if ( $res . inside ) inside = true ;
156
+ const first = $res . isec ! [ 0 ] ;
126
157
const alpha =
127
158
$res . alpha !== undefined
128
159
? $res . alpha
129
160
: dist2 ( ray . pos , first ) ;
130
161
if ( all ) {
131
- if ( single ) points . push ( first ) ;
132
- else points . push ( ...( < Vec [ ] > $res . isec ) ) ;
162
+ points . push ( ...$res . isec ! ) ;
133
163
minD = Math . min ( minD , alpha ) ;
134
164
} else if ( alpha < minD ) {
135
165
minD = alpha ;
@@ -141,6 +171,7 @@ export const intersects: MultiFn2O<
141
171
type : IntersectionType . INTERSECT ,
142
172
isec : points ,
143
173
alpha : minD ,
174
+ inside,
144
175
}
145
176
: NONE ;
146
177
} ,
0 commit comments