1 2 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);
}
|