nodePtr leftRotation(nodePtr t) { nodePtr t2 = t->right; t->right = t2->left; t2->left = t; t2 = fixN(t2); return t2; }
bool poly::giftwrap(){ if (surface.size() != 0) surface.clear(); // sort by x coordinate sortPoints(0); // first points is minimum x point p1 = points[0]; point* p1_ptr = &points[0]; // 2nd point is found by 2d giftwrap in xy plane double maxDot = -1.; point p2; point* p2_ptr; for (int i=1;i<points.size();i++){ point delta = points[i] - p1; delta.setX(2,0.); delta.makeUnit(); double dDot = delta * point(0,1,0); std::cout << delta << " * " << points[i] << " : " << dDot << std::endl; if (maxDot < dDot){ maxDot = dDot; p2 = points[i]; p2_ptr = &points[i]; } else if (dDot == maxDot) if ( (points[i] - p1).mag() < p2.mag()){ maxDot = dDot; p2 = points[i]; p2_ptr = &points[i]; } } std::cout << p1 << " " << p2 << std::endl; // project into plane defined by edge // between the first two points point dp = p2 - p1; dp.makeUnit(); // origin in projected space point p0 = p1 - dp * (dp*p1); std::vector<point> pp; for (int i=1;i<points.size();i++) if (points[i] != p2) pp.push_back(points[i] - dp * (dp*points[i]) - p0); // find all possible pairs of points std::vector<point> ppairs1; std::vector<point> ppairs2; for (int i=0;i<pp.size();i++) for (int j=i+1;j<pp.size();j++){ ppairs1.push_back(pp[i]); ppairs2.push_back(pp[j]); } pp.clear(); // find the two points in this space // with the largest opening angle point pp1, pp2; double minDot = 2.; for (int i=0;i<ppairs1.size();i++){ double dDot = (ppairs1[i]*ppairs2[i])/(ppairs1[i].mag()*ppairs2[i].mag()); if (dDot < minDot){ minDot = dDot; pp1 = ppairs1[i]; pp2 = ppairs2[i]; } else if (dDot == minDot) if ( (ppairs1[i]-ppairs2[i]).mag() < (pp1-pp2).mag()){ minDot = dDot; pp1 = ppairs1[i]; pp2 = ppairs2[i]; } } ppairs1.clear(); ppairs2.clear(); // find the poitns in original space // that match the points at large angles // these are the first two triangles for (int i=0;i<points.size();i++){ point mPP = points[i] - dp*(dp*points[i]) - p0; if (mPP==pp1 || mPP==pp2) surface.push_back(tri(*p1_ptr,*p2_ptr,points[i])); } if (!markEdges()) return false; // for (int j=0;j<surface.size();j++) // std::cout << "surface["<<j<< "] : " << surface[j] << std::endl; // std::cout << std::endl; while (isSurfaceOpen()){ edge mE; point mP; for (int i=0;i<surface.size();i++){ if (!surface[i].getUnconnected(mE, mP)) continue; dp = mE(1) - mE(0); dp.makeUnit(); p0 = mE(1) - dp*(dp*mE(1)); point mPP = mP - dp*(dp*mP) - p0; mPP = -mPP/(mPP.mag()); std::vector<point> ppoints; for (int j=0;j<points.size();j++){ if (surface[i].hasPoint(points[j])) continue; ppoints.push_back(points[j] - dp *(dp*points[j]) - p0); } double maxDot = -2.; point nPP; // find most colinear for (int j=0;j<ppoints.size();j++){ double dDot = (ppoints[j]*mPP)/ppoints[j].mag(); if (dDot > maxDot){ maxDot = dDot; nPP = ppoints[j]; } // if there are planar points, take the closest one else if (dDot == maxDot) if ( ppoints[j].mag() < nPP.mag()){ maxDot = dDot; nPP = ppoints[j]; } } ppoints.clear(); for (int j=0;j<points.size();j++) if (nPP == points[j] - dp*(dp*points[j]) - p0) surface.push_back(tri(mE(0),mE(1),points[j])); // for (int j=0;j<surface.size();j++) // std::cout << "surface["<<j<< "] : " << surface[j] << std::endl; // std::cout << std::endl; if (!markEdges()) { return false; //unmarkEdges(); //surface.pop_back(); //for (int j=0;j<surface.size();j++) //std::cout << "surface["<<j<< "] : " << surface[j] << std::endl; //std::cout << std::endl; //continue; } break; } } calcCenter(); fixN(); return true; }