@@ -32,6 +32,19 @@ function computeNormal(v1, v2, v3, n) {
32
32
}
33
33
}
34
34
35
+ function interpolationDerivs ( derivs ) {
36
+ // Order: [dN1/dr, dN2/dr, dN3/dr, dN1/ds, dN2/ds, dN3/ds]
37
+ // r-derivatives
38
+ derivs [ 0 ] = - 1.0 ;
39
+ derivs [ 1 ] = 1.0 ;
40
+ derivs [ 2 ] = 0.0 ;
41
+
42
+ // s-derivatives
43
+ derivs [ 3 ] = - 1.0 ;
44
+ derivs [ 4 ] = 0.0 ;
45
+ derivs [ 5 ] = 1.0 ;
46
+ }
47
+
35
48
function intersectWithTriangle ( p1 , q1 , r1 , p2 , q2 , r2 , tolerance = 1e-6 ) {
36
49
let coplanar = false ;
37
50
const pt1 = [ ] ;
@@ -228,6 +241,7 @@ function intersectWithTriangle(p1, q1, r1, p2, q2, r2, tolerance = 1e-6) {
228
241
export const STATIC = {
229
242
computeNormalDirection,
230
243
computeNormal,
244
+ interpolationDerivs,
231
245
intersectWithTriangle,
232
246
} ;
233
247
@@ -240,6 +254,7 @@ function vtkTriangle(publicAPI, model) {
240
254
model . classHierarchy . push ( 'vtkTriangle' ) ;
241
255
242
256
publicAPI . getCellDimension = ( ) => 2 ;
257
+
243
258
publicAPI . intersectWithLine = ( p1 , p2 , tol , x , pcoords ) => {
244
259
const outObj = {
245
260
subId : 0 ,
@@ -338,6 +353,17 @@ function vtkTriangle(publicAPI, model) {
338
353
return outObj ;
339
354
} ;
340
355
356
+ /**
357
+ * Evaluates whether the specified point is inside (1), outside (0), or
358
+ * indeterminate (-1) for the cell; computes parametric coordinates, sub-cell
359
+ * ID (if applicable), squared distance to the cell (and closest point if
360
+ * requested), and interpolation weights for the cell.
361
+ *
362
+ * @param {Vector3 } x The x point coordinate.
363
+ * @param {Vector3 } closestPoint The closest point coordinate.
364
+ * @param {Vector3 } pcoords The parametric coordinates.
365
+ * @param {Number[] } weights The number of weights.
366
+ */
341
367
publicAPI . evaluatePosition = ( x , closestPoint , pcoords , weights ) => {
342
368
// will return obj
343
369
const outObj = { subId : 0 , dist2 : 0 , evaluation : - 1 } ;
@@ -526,6 +552,13 @@ function vtkTriangle(publicAPI, model) {
526
552
return outObj ;
527
553
} ;
528
554
555
+ /**
556
+ * Determine global coordinates (x) from the given subId and parametric
557
+ * coordinates.
558
+ * @param {Vector3 } pcoords The parametric coordinates.
559
+ * @param {Vector3 } x The x point coordinate.
560
+ * @param {Number[] } weights The number of weights.
561
+ */
529
562
publicAPI . evaluateLocation = ( pcoords , x , weights ) => {
530
563
const p0 = [ ] ;
531
564
const p1 = [ ] ;
@@ -544,6 +577,10 @@ function vtkTriangle(publicAPI, model) {
544
577
weights [ 2 ] = pcoords [ 1 ] ;
545
578
} ;
546
579
580
+ /**
581
+ * Get the distance of the parametric coordinate provided to the cell.
582
+ * @param {Vector3 } pcoords The parametric coordinates.
583
+ */
547
584
publicAPI . getParametricDistance = ( pcoords ) => {
548
585
let pDist ;
549
586
let pDistMax = 0.0 ;
@@ -567,6 +604,119 @@ function vtkTriangle(publicAPI, model) {
567
604
}
568
605
return pDistMax ;
569
606
} ;
607
+
608
+ /**
609
+ * Get the derivatives of the triangle strip.
610
+ * @param {Number } subId - The sub-id of the triangle.
611
+ * @param {Vector3 } pcoords - The parametric coordinates.
612
+ * @param {Number[] } values - The values at the points.
613
+ * @param {Number } dim - The dimension.
614
+ * @param {Number[] } derivs - The derivatives.
615
+ */
616
+ publicAPI . derivatives = ( subId , pcoords , values , dim , derivs ) => {
617
+ const x0 = [ ] ;
618
+ const x1 = [ ] ;
619
+ const x2 = [ ] ;
620
+ model . points . getPoint ( 0 , x0 ) ;
621
+ model . points . getPoint ( 1 , x1 ) ;
622
+ model . points . getPoint ( 2 , x2 ) ;
623
+
624
+ const n = [ ] ;
625
+ const v10 = [ ] ;
626
+ const v20 = [ ] ;
627
+ const v = [ ] ;
628
+ computeNormal ( x0 , x1 , x2 , n ) ;
629
+
630
+ for ( let i = 0 ; i < 3 ; i ++ ) {
631
+ v10 [ i ] = x1 [ i ] - x0 [ i ] ;
632
+ v [ i ] = x2 [ i ] - x0 [ i ] ;
633
+ }
634
+
635
+ vtkMath . cross ( n , v10 , v20 ) ;
636
+
637
+ const lenX = vtkMath . normalize ( v10 ) ; // check for degenerate triangle
638
+
639
+ if ( lenX <= 0.0 || vtkMath . normalize ( v20 ) <= 0.0 ) {
640
+ // degenerate
641
+ for ( let j = 0 ; j < dim ; j ++ ) {
642
+ for ( let i = 0 ; i < 3 ; i ++ ) {
643
+ derivs [ j * dim + i ] = 0.0 ;
644
+ }
645
+ }
646
+ return ;
647
+ }
648
+
649
+ // 2D coordinates
650
+ const v0 = [ 0 , 0 ] ;
651
+ const v1 = [ lenX , 0 ] ;
652
+ const v2 = [ vtkMath . dot ( v , v10 ) , vtkMath . dot ( v , v20 ) ] ;
653
+
654
+ const functionDerivs = new Array ( 6 ) ;
655
+ interpolationDerivs ( functionDerivs ) ;
656
+
657
+ // Compute Jacobian: Jacobian is constant for a triangle.
658
+ const J = [ v1 [ 0 ] - v0 [ 0 ] , v1 [ 1 ] - v0 [ 1 ] , v2 [ 0 ] - v0 [ 0 ] , v2 [ 1 ] - v0 [ 1 ] ] ;
659
+
660
+ // Compute inverse Jacobian (expects flat array)
661
+ const JI = new Array ( 4 ) . fill ( 0.0 ) ;
662
+ vtkMath . invertMatrix ( J , JI , 2 ) ; // returns flat array [JI00, JI01, JI10, JI11]
663
+
664
+ // Compute derivatives
665
+ for ( let j = 0 ; j < dim ; j ++ ) {
666
+ let sum0 = 0.0 ;
667
+ let sum1 = 0.0 ;
668
+ for ( let i = 0 ; i < 3 ; i ++ ) {
669
+ sum0 += functionDerivs [ i ] * values [ dim * i + j ] ;
670
+ sum1 += functionDerivs [ 3 + i ] * values [ dim * i + j ] ;
671
+ }
672
+ const dBydx = sum0 * JI [ 0 ] + sum1 * JI [ 1 ] ;
673
+ const dBydy = sum0 * JI [ 2 ] + sum1 * JI [ 3 ] ;
674
+
675
+ // Transform into global system (dot product with global axes)
676
+ derivs [ 3 * j ] = dBydx * v10 [ 0 ] + dBydy * v20 [ 0 ] ;
677
+ derivs [ 3 * j + 1 ] = dBydx * v10 [ 1 ] + dBydy * v20 [ 1 ] ;
678
+ derivs [ 3 * j + 2 ] = dBydx * v10 [ 2 ] + dBydy * v20 [ 2 ] ;
679
+ }
680
+ } ;
681
+
682
+ /**
683
+ * Get the nearest cell boundary to the specified parametric
684
+ * coordinates and whether the point is inside or outside the cell.
685
+ * @param {Number } subId The sub-id of the cell.
686
+ * @param {Vector3 } pcoords The parametric coordinates.
687
+ * @param {Vector2 } pts The points of the cell.
688
+ */
689
+ publicAPI . cellBoundary = ( subId , pcoords , pts ) => {
690
+ const t1 = pcoords [ 0 ] - pcoords [ 1 ] ;
691
+ const t2 = 0.5 * ( 1.0 - pcoords [ 0 ] ) - pcoords [ 1 ] ;
692
+ const t3 = 2.0 * pcoords [ 0 ] + pcoords [ 1 ] - 1.0 ;
693
+
694
+ // compare against three lines in parametric space that divide element
695
+ // into three pieces
696
+ if ( t1 >= 0.0 && t2 >= 0.0 ) {
697
+ pts [ 0 ] = model . pointsIds [ 0 ] ;
698
+ pts [ 1 ] = model . pointsIds [ 1 ] ;
699
+ } else if ( t2 < 0.0 && t3 >= 0.0 ) {
700
+ pts [ 0 ] = model . pointsIds [ 1 ] ;
701
+ pts [ 1 ] = model . pointsIds [ 2 ] ;
702
+ } // ( t1 < 0.0 && t3 < 0.0 )
703
+ else {
704
+ pts [ 0 ] = model . pointsIds [ 2 ] ;
705
+ pts [ 1 ] = model . pointsIds [ 0 ] ;
706
+ }
707
+
708
+ if (
709
+ pcoords [ 0 ] < 0.0 ||
710
+ pcoords [ 1 ] < 0.0 ||
711
+ pcoords [ 0 ] > 1.0 ||
712
+ pcoords [ 1 ] > 1.0 ||
713
+ 1.0 - pcoords [ 0 ] - pcoords [ 1 ] < 0.0
714
+ ) {
715
+ return false ; // outside of triangle
716
+ }
717
+
718
+ return true ; // inside triangle
719
+ } ;
570
720
}
571
721
572
722
// ----------------------------------------------------------------------------
0 commit comments