Skip to content

Commit a80da0c

Browse files
committed
finished shape.js
finished shape.js
1 parent 5f5cee1 commit a80da0c

2 files changed

Lines changed: 108 additions & 44 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ src
5151
¦ ¦ CurvePath.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - -100%
5252
¦ ¦ Gyroscope.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0%
5353
¦ ¦ Path.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -100%
54-
¦ ¦ Shape.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0%
54+
¦ ¦ Shape.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -100%
5555
¦ ¦
5656
¦ --curves
5757
¦ ¦ ArcCurve.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0%

src/extras/core/Shape.js

Lines changed: 107 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,14 @@ THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {
204204
/**************************************************************
205205
* Utils shape对象的工具集
206206
**************************************************************/
207-
208207
THREE.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

Comments
 (0)