@@ -204,9 +204,14 @@ THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {
204204/**************************************************************
205205 * Utils shape对象的工具集
206206 **************************************************************/
207-
208207THREE . Shape . Utils = {
209-
208+ /*
209+ ///triangulateShape方法将传递的顶点数组(参数contour)和镂空(孔洞)数组(参数holes)三角化.
210+ */
211+ ///<summary>triangulateShape</summary>
212+ ///<param name ="contour" type="Vector3Array">拉伸几何体的顶点数据.</param>
213+ ///<param name ="holes" type="Vector3Array">镂空(孔洞)顶点数据.</param>
214+ ///<returns type="Vector3Array">返回围绕形状的顶点索引.</returns>
210215 triangulateShape : function ( contour , holes ) {
211216
212217 function point_in_segment_2D_colin ( inSegPt1 , inSegPt2 , inOtherPt ) {
@@ -226,6 +231,16 @@ THREE.Shape.Utils = {
226231 }
227232 }
228233
234+ /*
235+ ///intersect_segments_2D方法返回两条线段的交点.
236+ */
237+ ///<summary>intersect_segments_2D</summary>
238+ ///<param name ="inSeg1Pt1" type="Vector2">要检查交点的第一条线的起始点.</param>
239+ ///<param name ="inSeg1Pt2" type="Vector2">要检查交点的第一条线的结束点.</param>
240+ ///<param name ="inSeg2Pt1" type="Vector2">要检查交点的第二条线的起始点.</param>
241+ ///<param name ="inSeg2Pt2" type="Vector2">要检查交点的第二条线的结束点.</param>
242+ ///<param name ="inExcludeAdjacentSegs" type="boolean">是否排除相邻的线段.</param>
243+ ///<returns type="Vector2Array">二维向量数组.</returns>
229244 function intersect_segments_2D ( inSeg1Pt1 , inSeg1Pt2 , inSeg2Pt1 , inSeg2Pt2 , inExcludeAdjacentSegs ) {
230245 var EPSILON = 0.0000000001 ;
231246
@@ -238,68 +253,71 @@ THREE.Shape.Utils = {
238253 var limit = seg1dy * seg2dx - seg1dx * seg2dy ;
239254 var perpSeg1 = seg1dy * seg1seg2dx - seg1dx * seg1seg2dy ;
240255
241- if ( Math . abs ( limit ) > EPSILON ) { // not parallel
256+ if ( Math . abs ( limit ) > EPSILON ) { // not parallel //两条线不平行
242257
243258 var perpSeg2 ;
244259 if ( limit > 0 ) {
245- if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) return [ ] ;
260+ if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) return [ ] ; //返回空数组
246261 perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy ;
247- if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) return [ ] ;
262+ if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) return [ ] ; //返回空数组
248263 } else {
249- if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) return [ ] ;
264+ if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) return [ ] ; //返回空数组
250265 perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy ;
251- if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) return [ ] ;
266+ if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) return [ ] ; //返回空数组
252267 }
253268
254269 // i.e. to reduce rounding errors
255270 // intersection at endpoint of segment#1?
271+ // 交点位于第一条线的端点
256272 if ( perpSeg2 == 0 ) {
257273 if ( ( inExcludeAdjacentSegs ) &&
258- ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return [ ] ;
274+ ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return [ ] ; //返回空数组
259275 return [ inSeg1Pt1 ] ;
260276 }
261277 if ( perpSeg2 == limit ) {
262278 if ( ( inExcludeAdjacentSegs ) &&
263- ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return [ ] ;
279+ ( ( perpSeg1 == 0 ) || ( perpSeg1 == limit ) ) ) return [ ] ; //返回空数组
264280 return [ inSeg1Pt2 ] ;
265281 }
266282 // intersection at endpoint of segment#2?
283+ // 交点位于第二条线的端点
267284 if ( perpSeg1 == 0 ) return [ inSeg2Pt1 ] ;
268285 if ( perpSeg1 == limit ) return [ inSeg2Pt2 ] ;
269286
270287 // return real intersection point
288+ // 返回真正的交点
271289 var factorSeg1 = perpSeg2 / limit ;
272290 return [ { x : inSeg1Pt1 . x + factorSeg1 * seg1dx ,
273291 y : inSeg1Pt1 . y + factorSeg1 * seg1dy } ] ;
274292
275- } else { // parallel or colinear
293+ } else { // parallel or colinear 平行或共线
276294 if ( ( perpSeg1 != 0 ) ||
277- ( seg2dy * seg1seg2dx != seg2dx * seg1seg2dy ) ) return [ ] ;
295+ ( seg2dy * seg1seg2dx != seg2dx * seg1seg2dy ) ) return [ ] ; //返回空数组
278296
279- // they are collinear or degenerate
280- var seg1Pt = ( ( seg1dx == 0 ) && ( seg1dy == 0 ) ) ; // segment1 ist just a point?
281- var seg2Pt = ( ( seg2dx == 0 ) && ( seg2dy == 0 ) ) ; // segment2 ist just a point?
282- // both segments are points
297+ // they are collinear or degenerate 两条线共线或则无效
298+ var seg1Pt = ( ( seg1dx == 0 ) && ( seg1dy == 0 ) ) ; // segment1 ist just a point? 第一条线只是一个点
299+ var seg2Pt = ( ( seg2dx == 0 ) && ( seg2dy == 0 ) ) ; // segment2 ist just a point? 第二条线只是一个点
300+ // both segments are points 两条线都是点
283301 if ( seg1Pt && seg2Pt ) {
284302 if ( ( inSeg1Pt1 . x != inSeg2Pt1 . x ) ||
285- ( inSeg1Pt1 . y != inSeg2Pt1 . y ) ) return [ ] ; // they are distinct points
286- return [ inSeg1Pt1 ] ; // they are the same point
303+ ( inSeg1Pt1 . y != inSeg2Pt1 . y ) ) return [ ] ; // they are distinct points 两个点不共点,返回空数组
304+ return [ inSeg1Pt1 ] ; // they are the same point 共点
287305 }
288- // segment#1 is a single point
306+ // segment#1 is a single point 第一条线段是一个点
289307 if ( seg1Pt ) {
290- if ( ! point_in_segment_2D_colin ( inSeg2Pt1 , inSeg2Pt2 , inSeg1Pt1 ) ) return [ ] ; // but not in segment#2
308+ if ( ! point_in_segment_2D_colin ( inSeg2Pt1 , inSeg2Pt2 , inSeg1Pt1 ) ) return [ ] ; // but not in segment#2 不在第二条线段内,返回空数组
291309 return [ inSeg1Pt1 ] ;
292310 }
293- // segment#2 is a single point
311+ // segment#2 is a single point 第二条线是一个点
294312 if ( seg2Pt ) {
295- if ( ! point_in_segment_2D_colin ( inSeg1Pt1 , inSeg1Pt2 , inSeg2Pt1 ) ) return [ ] ; // but not in segment#1
313+ if ( ! point_in_segment_2D_colin ( inSeg1Pt1 , inSeg1Pt2 , inSeg2Pt1 ) ) return [ ] ; // but not in segment#1 不在第一条线段内,返回空数组
296314 return [ inSeg2Pt1 ] ;
297315 }
298316
299- // they are collinear segments, which might overlap
317+ // they are collinear segments, which might overlap 两条线共线,有可能重叠.
300318 var seg1min , seg1max , seg1minVal , seg1maxVal ;
301319 var seg2min , seg2max , seg2minVal , seg2maxVal ;
302- if ( seg1dx != 0 ) { // the segments are NOT on a vertical line
320+ if ( seg1dx != 0 ) { // the segments are NOT on a vertical line 线不是垂直线
303321 if ( inSeg1Pt1 . x < inSeg1Pt2 . x ) {
304322 seg1min = inSeg1Pt1 ; seg1minVal = inSeg1Pt1 . x ;
305323 seg1max = inSeg1Pt2 ; seg1maxVal = inSeg1Pt2 . x ;
@@ -314,7 +332,7 @@ THREE.Shape.Utils = {
314332 seg2min = inSeg2Pt2 ; seg2minVal = inSeg2Pt2 . x ;
315333 seg2max = inSeg2Pt1 ; seg2maxVal = inSeg2Pt1 . x ;
316334 }
317- } else { // the segments are on a vertical line
335+ } else { // the segments are on a vertical line
318336 if ( inSeg1Pt1 . y < inSeg1Pt2 . y ) {
319337 seg1min = inSeg1Pt1 ; seg1minVal = inSeg1Pt1 . y ;
320338 seg1max = inSeg1Pt2 ; seg1maxVal = inSeg1Pt2 . y ;
@@ -350,8 +368,17 @@ THREE.Shape.Utils = {
350368 }
351369 }
352370
371+ /*
372+ ///isPointInsideAngle方法判断第四个参数是否在前三个参数组成的三角形内.
373+ */
374+ ///<summary>isPointInsideAngle</summary>
375+ ///<param name ="inVertex" type="int">顶点索引.</param>
376+ ///<param name ="inLegFromPt" type="int">上一个顶点索引.</param>
377+ ///<param name ="inLegToPt" type="int">下一个顶点索引.</param>
378+ ///<param name ="inOtherPt" type="int">孔洞顶点索引.</param>
379+ ///<returns type="boolean">true 或者 false.</returns>
353380 function isPointInsideAngle ( inVertex , inLegFromPt , inLegToPt , inOtherPt ) {
354- // The order of legs is important
381+ // The order of legs is important 参数的排列顺序非常重要.
355382
356383 var EPSILON = 0.0000000001 ;
357384
@@ -380,14 +407,29 @@ THREE.Shape.Utils = {
380407 }
381408 }
382409
383-
410+ /*
411+ ///removeHoles方法从拉伸几何体中删除孔洞.
412+ */
413+ ///<summary>removeHoles</summary>
414+ ///<param name ="contour" type="Vector3Array">拉伸几何体的顶点数据.</param>
415+ ///<param name ="holes" type="Vector3Array">镂空(孔洞)顶点数据.</param>
416+ ///<returns type="Object">返回没有镂空(孔洞)的拉伸几何体.</returns>
384417 function removeHoles ( contour , holes ) {
385418
386419 var shape = contour . concat ( ) ; // work on this shape
387420 var hole ;
388421
422+ /*
423+ ///isCutLineInsideAngles方法返回当前索引所指的图形顶点在镂空顶点,以及前一个顶点,后一个顶点组成的三角形内.
424+ // 或者当前索引所指的镂空顶点在图形顶点,以及前一个顶点,后一个顶点组成的三角形内,true为真.
425+ */
426+ ///<summary>isCutLineInsideAngles</summary>
427+ ///<param name ="inShapeIdx" type="int">拉伸几何体的顶点数据.</param>
428+ ///<param name ="inHoleIdx" type="int">镂空(孔洞)顶点数据.</param>
429+ ///<returns type="boolean">true 或者 false.</returns>
389430 function isCutLineInsideAngles ( inShapeIdx , inHoleIdx ) {
390431 // Check if hole point lies within angle around shape point
432+ // 检查镂空(孔洞)的顶点在
391433 var lastShapeIdx = shape . length - 1 ;
392434
393435 var prevShapeIdx = inShapeIdx - 1 ;
@@ -403,6 +445,7 @@ THREE.Shape.Utils = {
403445 }
404446
405447 // Check if shape point lies within angle around hole point
448+ // 检查图形顶点位于环绕镂空(孔洞)的三角形内.
406449 var lastHoleIdx = hole . length - 1 ;
407450
408451 var prevHoleIdx = inHoleIdx - 1 ;
@@ -417,11 +460,18 @@ THREE.Shape.Utils = {
417460 return false ;
418461 }
419462
420- return true ;
463+ return true ; //
421464 }
422-
465+ /*
466+ ///intersectsShapeEdge方法检查镂空(孔洞)与形状边界是否有交点,true为真.
467+ */
468+ ///<summary>isCutLineInsideAngles</summary>
469+ ///<param name ="inShapeIdx" type="int">拉伸几何体的顶点数据.</param>
470+ ///<param name ="inHoleIdx" type="int">镂空(孔洞)顶点数据.</param>
471+ ///<returns type="boolean">true 或者 false.</returns>
423472 function intersectsShapeEdge ( inShapePt , inHolePt ) {
424473 // checks for intersections with shape edges
474+ // 检查镂空(孔洞)与形状边界是否有交点.
425475 var sIdx , nextIdx , intersection ;
426476 for ( sIdx = 0 ; sIdx < shape . length ; sIdx ++ ) {
427477 nextIdx = sIdx + 1 ; nextIdx %= shape . length ;
@@ -433,9 +483,16 @@ THREE.Shape.Utils = {
433483 }
434484
435485 var indepHoles = [ ] ;
436-
486+ /*
487+ ///intersectsShapeEdge方法检查当前的镂空(孔洞)是否是否与其它镂空(孔洞)边界相交,true为真.
488+ */
489+ ///<summary>isCutLineInsideAngles</summary>
490+ ///<param name ="inShapeIdx" type="int">拉伸几何体的顶点数据.</param>
491+ ///<param name ="inHoleIdx" type="int">镂空(孔洞)顶点数据.</param>
492+ ///<returns type="boolean">true 或者 false.</returns>
437493 function intersectsHoleEdge ( inShapePt , inHolePt ) {
438494 // checks for intersections with hole edges
495+ // 检查当前的镂空(孔洞)是否是否与其它镂空(孔洞)边界相交.
439496 var ihIdx , chkHole ,
440497 hIdx , nextIdx , intersection ;
441498 for ( ihIdx = 0 ; ihIdx < indepHoles . length ; ihIdx ++ ) {
@@ -471,26 +528,30 @@ THREE.Shape.Utils = {
471528 }
472529
473530 // search for shape-vertex and hole-vertex,
531+ // 搜索形状的顶点和镂空(孔洞)顶点
474532 // which can be connected without intersections
533+ // 哪些可以连接并无交点.
475534 for ( shapeIndex = minShapeIndex ; shapeIndex < shape . length ; shapeIndex ++ ) {
476535
477536 shapePt = shape [ shapeIndex ] ;
478537 holeIndex = - 1 ;
479538
480539 // search for hole which can be reached without intersections
540+ // 搜索镂空(孔洞)的顶点,哪些可以到达并没有交点.
481541 for ( var h = 0 ; h < indepHoles . length ; h ++ ) {
482542 holeIdx = indepHoles [ h ] ;
483543
484544 // prevent multiple checks
545+ // 避免多次检查
485546 cutKey = shapePt . x + ":" + shapePt . y + ":" + holeIdx ;
486547 if ( failedCuts [ cutKey ] !== undefined ) continue ;
487548
488549 hole = holes [ holeIdx ] ;
489550 for ( var h2 = 0 ; h2 < hole . length ; h2 ++ ) {
490551 holePt = hole [ h2 ] ;
491- if ( ! isCutLineInsideAngles ( shapeIndex , h2 ) ) continue ;
492- if ( intersectsShapeEdge ( shapePt , holePt ) ) continue ;
493- if ( intersectsHoleEdge ( shapePt , holePt ) ) continue ;
552+ if ( ! isCutLineInsideAngles ( shapeIndex , h2 ) ) continue ; //如果孔洞顶点不在切线内
553+ if ( intersectsShapeEdge ( shapePt , holePt ) ) continue ; //如果与图形的边相交.
554+ if ( intersectsHoleEdge ( shapePt , holePt ) ) continue ; //如果与镂空(空洞)的边相交.
494555
495556 holeIndex = h2 ;
496557 indepHoles . splice ( h , 1 ) ;
@@ -509,15 +570,15 @@ THREE.Shape.Utils = {
509570
510571 break ;
511572 }
512- if ( holeIndex >= 0 ) break ; // hole-vertex found
573+ if ( holeIndex >= 0 ) break ; // hole-vertex found 找到镂空顶点
513574
514- failedCuts [ cutKey ] = true ; // remember failure
575+ failedCuts [ cutKey ] = true ; // remember failure //添加切割线顶点索引
515576 }
516- if ( holeIndex >= 0 ) break ; // hole-vertex found
577+ if ( holeIndex >= 0 ) break ; // hole-vertex found //找到镂空(孔洞)顶点
517578 }
518579 }
519580
520- return shape ; /* shape with no holes */
581+ return shape ; /* shape with no holes */ // 返回不包含镂空(孔洞)的形状.
521582 }
522583
523584
@@ -526,18 +587,19 @@ THREE.Shape.Utils = {
526587 allPointsMap = { } ;
527588
528589 // To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
590+ // 将孔洞的顶点按照图形原来坐标顺序,偏移索引,这是首先能做的.
529591
530- var allpoints = contour . concat ( ) ;
592+ var allpoints = contour . concat ( ) ; //声明数组,存放合并后的顶点数组.
531593
532- for ( var h = 0 , hl = holes . length ; h < hl ; h ++ ) {
594+ for ( var h = 0 , hl = holes . length ; h < hl ; h ++ ) { //遍历镂空(孔洞)的顶点
533595
534- Array . prototype . push . apply ( allpoints , holes [ h ] ) ;
596+ Array . prototype . push . apply ( allpoints , holes [ h ] ) ; //将镂空(孔洞)的顶点压入所有顶点数组中.
535597
536598 }
537599
538600 //console.log( "allpoints",allpoints, allpoints.length );
539601
540- // prepare all points map
602+ // prepare all points map 准备所有的顶点的哈希表.
541603
542604 for ( i = 0 , il = allpoints . length ; i < il ; i ++ ) {
543605
@@ -554,12 +616,14 @@ THREE.Shape.Utils = {
554616 }
555617
556618 // remove holes by cutting paths to holes and adding them to the shape
557- var shapeWithoutHoles = removeHoles ( contour , holes ) ;
619+ // 删除镂空(孔洞),并将孔洞的作为实体的一部分.
620+ var shapeWithoutHoles = removeHoles ( contour , holes ) ; //调用removeHoles方法.
558621
559- var triangles = THREE . FontUtils . Triangulate ( shapeWithoutHoles , false ) ; // True returns indices for points of spooled shape
622+ var triangles = THREE . FontUtils . Triangulate ( shapeWithoutHoles , false ) ; // True returns indices for points of spooled shape 真正返回围绕形状的顶点索引.
560623 //console.log( "triangles",triangles, triangles.length );
561624
562625 // check all face vertices against all points map
626+ // 检查所有的面顶点顺序与所有顶点的哈希表一致.
563627
564628 for ( i = 0 , il = triangles . length ; i < il ; i ++ ) {
565629
@@ -581,7 +645,7 @@ THREE.Shape.Utils = {
581645
582646 }
583647
584- return triangles . concat ( ) ;
648+ return triangles . concat ( ) ; //返回围绕形状的顶点索引.
585649
586650 } ,
587651 /*
0 commit comments