ShapeUtils.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { Earcut } from './Earcut.js';
  2. class ShapeUtils {
  3. // calculate area of the contour polygon
  4. static area( contour ) {
  5. const n = contour.length;
  6. let a = 0.0;
  7. for ( let p = n - 1, q = 0; q < n; p = q ++ ) {
  8. a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
  9. }
  10. return a * 0.5;
  11. }
  12. static isClockWise( pts ) {
  13. return ShapeUtils.area( pts ) < 0;
  14. }
  15. static triangulateShape( contour, holes ) {
  16. const vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ]
  17. const holeIndices = []; // array of hole indices
  18. const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ]
  19. removeDupEndPts( contour );
  20. addContour( vertices, contour );
  21. //
  22. let holeIndex = contour.length;
  23. holes.forEach( removeDupEndPts );
  24. for ( let i = 0; i < holes.length; i ++ ) {
  25. holeIndices.push( holeIndex );
  26. holeIndex += holes[ i ].length;
  27. addContour( vertices, holes[ i ] );
  28. }
  29. //
  30. const triangles = Earcut.triangulate( vertices, holeIndices );
  31. //
  32. for ( let i = 0; i < triangles.length; i += 3 ) {
  33. faces.push( triangles.slice( i, i + 3 ) );
  34. }
  35. return faces;
  36. }
  37. }
  38. function removeDupEndPts( points ) {
  39. const l = points.length;
  40. if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
  41. points.pop();
  42. }
  43. }
  44. function addContour( vertices, contour ) {
  45. for ( let i = 0; i < contour.length; i ++ ) {
  46. vertices.push( contour[ i ].x );
  47. vertices.push( contour[ i ].y );
  48. }
  49. }
  50. export { ShapeUtils };
粤ICP备19079148号