2D manhattan diagram
float mindist = 999999.9; int index = -1; for(int i = 0; i< npoints(1); i++) { vector pos = point(1, 'P', i); //float distance = sqrt(pow(pos.x - @P.x, 2)+pow(pos.z - @P.z,2)); float distance = abs(pos.x - @P.x)+abs( pos.z - @P.z); if(mindist > distance) { mindist = distance; index = i; } } i@val = index; f@dist = mindist;
int offset = -1; int vts[] = primvertices(0, @primnum); //i[]@vts = vts; int vt0 = vts[0]; int pt0 = vertexpoint(0, vt0); int val0 = point(0, 'val', pt0); for(int i = 0; i<len(vts); i++) { int vt = vts[i]; int pt = vertexpoint(0, vt); int val = point(0, 'val', pt); int vt1 = vts[(i+1) % len(vts)]; int pt1 = vertexpoint(0, vt1); int val1 = point(0, 'val', pt1); if(offset == -1 && val != val1) { offset = i; // get times when suffer different area value. } append(vals, val); }
vals = sort(vals); int nvals[] = array(vals[0]); // fill first element value. for(int i = 0; i<len(vals)-1; i++) { int val1 = vals[i]; int val2 = vals[i+1]; if(val1 != val2) { append(nvals, val2); } } i[]@nvals = nvals; int poly = -1; // this condition defines the sequance of connecting line. int count; // polygon count if(len(nvals) == 1) { setprimattrib(0, 'val', @primnum, nvals[0]); } else { removeprim(0, @primnum, 1); for(int i = offset; i<=len(vts) + offset; i++) { int vt1 = vts[i % len(vts)]; int vt2 = vts[(i+1) % len(vts)]; int pt1 = vertexpoint(0, vt1); int pt2 = vertexpoint(0, vt2); vector pos1 = point(0, 'P', pt1); vector pos2 = point(0, 'P', pt2); int val1 = point(0, 'val', pt1); int val2 = point(0, 'val', pt2); if(val1 != val2) { int m_pt = addpoint(0, (pos1 + pos2)/2); if(poly < 0) { poly = addprim(0, 'poly'); addvertex(0, poly, m_pt); setprimattrib(0, 'val', poly, val2); count = 1; } else { addvertex(0, poly, m_pt); count++; if(len(nvals) >= 3 && count == 3) { setprimgroup(0, 'triangle', poly, 1); } poly = addprim(0, 'poly'); setprimattrib(0, 'val', poly, val2); addvertex(0, poly, m_pt); count = 1; } } if(poly >= 0) { count++; addvertex(0, poly, pt2); } } }
接下来,需要单独处理破洞的地方。先拾取生成好的模型面,翻转180度,用于填充 holes。
vector cen_pos = getbbox_center(0, itoa(@primnum)); int pts[] = primpoints(0, @primnum); for(int i = 0; i<len(pts); i++) { vector pos = point(0, 'P', pts[i]); matrix mat = ident(); rotate(mat, $PI, {0,1,0}); pos -= cen_pos; pos *= mat; pos += cen_pos; setpointattrib(0, 'P', pts[i], pos ); } setprimattrib(0, 'val', @primnum, i@val);