| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 
 | function int getNearPointId(vector sideDir; vector lineDir; int ptnum; int otherpt){int neibs[] = neighbours(0, ptnum);
 if(len(neibs) == 1){
 return neibs[0];
 }
 else{
 vector thispos = point(0, "P", ptnum);
 float minAngle = 6.28;
 int minId = neibs[0];
 foreach(int id; neibs){
 if(id == otherpt){
 continue;
 }
 vector otherPos = point(0, "P", id);
 vector toDir = normalize(otherPos - thispos);
 float dotLine = dot(toDir, -lineDir);
 float dotDir = dot(toDir, sideDir);
 float acos = acos(dotLine);
 if(dotDir < 0){
 acos = 6.28 - acos;
 }
 if(acos < minAngle){
 minAngle = acos;
 minId = id;
 }
 }
 return minId;
 
 }
 
 }
 
 //left: isleft = 1; right : isleft = 0;
 function vector getGuideDir(int ptstart; int ptend; int isLeft){
 vector pos1 = point(0, "P", ptstart);
 vector pos2 = point(0, "P", ptend);
 
 vector toVec = normalize(pos2 - pos1);
 vector up = {0,1,0};
 if(isLeft > 0.5){
 return cross(up, toVec);
 }else{
 return cross(toVec, up);
 }
 }
 
 function vector2 solveIntersection(vector start1; vector start2; vector dir1; vector dir2){
 
 vector2 dir1xz, dir2xz;
 dir1xz.x = dir1.x;
 dir1xz.y = dir1.z;
 dir2xz.x = dir2.x;
 dir2xz.y = dir2.z;
 if(abs(dot(normalize(dir1xz), normalize(dir2xz))) > 0.9999){
 vector2 rtresult;
 rtresult.x = (start1.x + start2.x) / 2;
 rtresult.y = (start1.z + start2.z) / 2;
 return rtresult;
 }
 vector2 start1xz, start2xz;
 start1xz.x = start1.x;
 start1xz.y = start1.z;
 start2xz.x = start2.x;
 start2xz.y = start2.z;
 
 float t2 = ( start1xz.x * dir1xz.y - start1xz.y * dir1xz.x + start2xz.y * dir1xz.x - start2xz.x * dir1xz.y) / ( dir2xz.x * dir1xz.y - dir2xz.y * dir1xz.x);
 vector2 result = start2xz + t2 * dir2xz;
 return result;
 }
 
 function vector getOffsetPosition(int pt1; int ptmid; int pt2; float offsetDist1; float offsetDist2; vector dirGuide){
 vector pos1 = point(0, "P", pt1);
 vector posmid = point(0, "P", ptmid);
 vector pos2 = point(0, "P", pt2);
 
 vector to1 = normalize(pos1 - posmid);
 vector to2 = normalize(pos2 - posmid);
 
 vector cross1 = cross(to1, dirGuide);
 vector cross2 = cross(to2, dirGuide);
 
 cross1.x = 0;
 cross1.z = 0;
 cross2.x = 0;
 cross2.z = 0;
 
 vector offsetVec1 = cross(cross1, to1);
 vector offsetVec2 = cross(cross2, to2);
 
 vector start1 = posmid + offsetDist1 * normalize(offsetVec1);
 vector start2 = posmid + offsetDist2 * normalize(offsetVec2);
 
 vector2 resultVecXZ = solveIntersection(start1, start2, to1, to2);
 vector resultVec;
 resultVec.x = resultVecXZ.x;
 resultVec.z = resultVecXZ.y;
 resultVec.y = (start1.y + start2.y) / 2;
 return resultVec;
 }
 
 int pts[] = primpoints(0, @primnum);
 //printf("lens %sn", len(pts));
 float width = 0.02;
 
 if(len(pts) == 2){
 vector pos1 = point(0, "P", pts[0]);
 vector pos2 = point(0, "P", pts[1]);
 
 vector linedir = normalize(pos2 - pos1);
 vector up = {0,1,0};
 vector leftDir = getGuideDir(pts[0], pts[1], 1);
 vector rightDir = getGuideDir(pts[0], pts[1], 0);
 
 int ptidleftnear2 = getNearPointId(leftDir, linedir, pts[1], pts[0]);
 int ptidleftnear1 = getNearPointId(leftDir, -linedir, pts[0], pts[1]);
 
 vector ln2Dir = getGuideDir(pts[1], ptidleftnear2, 1);
 vector ln1Dir = getGuideDir(ptidleftnear1, pts[0], 1);
 
 int ptidrightnear2 = getNearPointId(rightDir, linedir, pts[1], pts[0]);
 int ptidrightnear1 = getNearPointId(rightDir, -linedir, pts[0], pts[1]);
 
 vector rn2Dir = getGuideDir(pts[1], ptidrightnear2, 0);
 vector rn1Dir = getGuideDir(ptidrightnear1, pts[0], 0);
 
 vector left1 = getOffsetPosition(ptidleftnear1, pts[0], pts[1], width, width, ln1Dir + leftDir);
 vector left2 = getOffsetPosition(pts[0], pts[1], ptidleftnear2, width, width, ln2Dir + leftDir);
 vector right1 = getOffsetPosition(ptidrightnear1, pts[0], pts[1], width, width, rn1Dir + rightDir);
 vector right2 = getOffsetPosition(pts[0], pts[1], ptidrightnear2, width, width, rn2Dir + rightDir);
 
 int addleft1 = addpoint(0, left1);
 int addleft2 = addpoint(0, left2);
 
 @ptidleftnear1 = ptidleftnear1;
 @ptidleftnear2 = ptidleftnear2;
 @pos1 = pts[0];
 @pos2 = pts[1];
 int addright1 = addpoint(0, right1);
 int addright2 = addpoint(0, right2);
 
 addprim(0, "poly", addleft1, addleft2, addright2, addright1);
 
 }
 
 
 |