void PointKDTree::sortPoints(std::vector<Point *> & sortedPoints) const { if(root->lo == NULL && root->hi == NULL && (int)root->points.size()!=0) { for(int i =0; i<(int)root->points.size(); i++) { sortedPoints.push_back(root->points[i]); } } else { sortPoints(root->lo, sortedPoints); sortPoints(root->hi, sortedPoints); } }
void PointKDTree::sortPoints(Node *node, std::vector<Point *> & sortedPoints) const { if(node->lo ==NULL && node->hi == NULL && (int)node->points.size()!=0) { for(int i =0; i<(int)node->points.size(); i++) { sortedPoints.push_back(node->points[i]); } } else { sortPoints(node->lo, sortedPoints); sortPoints(node->hi, sortedPoints); } }
///======================================================================================= void CPSFloatCurveFunctor::setCtrlPoint(uint index, const CCtrlPoint &ctrlPoint) { nlassert(ctrlPoint.Date >= 0 && ctrlPoint.Date <= 1); _CtrlPoints[index] = ctrlPoint; sortPoints(); updateTab(); }
void PointEditor::mouseUp (const MouseEvent& e) { if (selectedPoint > -1) { if (points.size() == 2) sortPoints(); repaint(); } }
ofVec3f &ofxFace::calculateNormal() { sortPoints(); ofxVertex *v0 = getVertex(0); ofxVertex *v1 = getVertex(1); ofxVertex *v2 = getVertex(2); ofVec3f v20 = v2->getPos() - v0->getPos(); ofVec3f v10 = v1->getPos() - v0->getPos(); normal = v20.getCrossed(v10).normalized(); return normal; }
inline void sortPoints( int numPoints, PointParam points[], int sortDimension) { if(numPoints>1) { /* Find the point array's median along the split dimension: */ typename PointParam::Scalar median=points[numPoints/2-1][sortDimension]; /* Perform one Quicksort-like sweep of the array to separate it into left and right: */ int l=0; int r=numPoints-1; while(true) { while(l<numPoints&&points[l][sortDimension]<median) ++l; while(r>=0&&points[r][sortDimension]>median) --r; if(l<r) { Misc::swap(points[l],points[r]); ++l; --r; } else break; } /* Recurse on the left and right arrays: */ sortPoints(r+1,points,sortDimension); sortPoints(numPoints-(r+1),points+(r+1),sortDimension); } }
void PointEditor::mouseDown (const MouseEvent& e) { int verticalPoint = getVerticalPoint(e.x); if (verticalPoint > -1) { points[verticalPoint].y = e.y; selectedPoint = verticalPoint; } else { selectedPoint = getSelectedPoint(e.x, e.y); if (selectedPoint == -1) { addPoint (e.x, e.y); sortPoints(); sendChangeMessage(); } } repaint(); }
void TextBox::Render( Point pos, bool selected ) { const Rect& rect = this->GetRect(); const Point r = rect.Offset(pos); Control::RenderBase(pos, selected); int w,h; Drawing().GetResolution(w,h); // TODO: tweak clip region a little Drawing().PushClipRegion( r.x+2, r.y, m_text_area.w-5, m_text_area.h ); int j; int sz=0; if(!m_lines.empty()) { // selection std::string piece = m_lines[m_cursor.y].text.utf8_substr(0, m_position.x, m_password); if(m_update_viewport) { sz = m_style.font->GetTextSize(piece); m_viewport_offset.x = sz; m_update_viewport = false; } else { sz = m_viewport_offset.x; } // draw selection if there is one if(m_anchor.x != -1) { j=0; Point p1,p2; sortPoints(p1,p2); int yy=m_position.y; for( auto i = m_lines.begin()+yy; i != m_lines.end(); i++,j++,yy++) { if(5+j*m_line_height+i->h > rect.h) break; if(yy < p1.y || yy > p2.y) continue; if(yy == p1.y && p1.y == p2.y) { std::string pd = m_lines[yy].text.utf8_substr(p1.x, p2.x-p1.x, m_password); std::string pd1 = m_lines[yy].text.utf8_substr(0, p1.x, m_password); int selw = m_style.font->GetTextSize( pd ); int selw1 = m_style.font->GetTextSize( pd1 ); Drawing().FillRect( r.x-sz+5+selw1, r.y+5+j*m_line_height, selw, i->h, m_selection_color); } else if(yy == p1.y) { std::string pd = m_lines[yy].text.utf8_substr(p1.x, std::string::npos, m_password); int selw = m_style.font->GetTextSize( pd ); Drawing().FillRect( r.x-sz+5+i->w-selw, r.y+5+j*m_line_height, selw, i->h, m_selection_color); } else if(yy == p2.y) { std::string pd = m_lines[yy].text.utf8_substr(0, p2.x, m_password); int selw = m_style.font->GetTextSize( pd ); Drawing().FillRect( r.x-sz+5, r.y+5+j*m_line_height, selw, i->h, m_selection_color); } else { Drawing().FillRect( r.x-sz+5, r.y+5+j*m_line_height, i->w, i->h, m_selection_color); } } } // placeholder or text if(!isActive() && m_lines.size() == 1 && !m_placeholder.text.empty() && m_lines[0].text.empty() ) { Drawing().TexRect( r.x+5, r.y+5, m_placeholder.w, m_placeholder.h, m_placeholder.tex); } else { j=0; if(m_position.y < m_lines.size()) { for( auto i = m_lines.begin()+m_position.y; i != m_lines.end(); i++,j++) { if(5+j*m_line_height+i->h > rect.h) break; if(i->h <= 1) continue; Drawing().TexRect( r.x-sz+5, r.y+5+j*m_line_height, i->w, i->h, i->tex); } } } } // cursor if(isActive() && !m_readonly && (m_cursor_blink_counter += getDeltaTime()) > m_cursor_blinking_rate && m_cursor.y >= m_position.y && m_cursor.y-m_position.y < rect.h/m_line_height) { if(m_cursor_blink_counter > 2*m_cursor_blinking_rate) { m_cursor_blink_counter = 0; } if(m_cursor.x >= m_position.x && m_cursor.x <= m_lines[m_cursor.y].text.utf8_size()) { // std::string piece = m_lines[m_cursor.y].text.utf8_substr(m_position.x, m_cursor.x-m_position.x, m_password); std::string piece = m_lines[m_cursor.y].text.utf8_substr(0, m_cursor.x, m_password); Drawing().Rect(m_style.font->GetTextSize( piece )+r.x-sz+5, (m_cursor.y-m_position.y)*m_line_height+r.y+5, 1, m_line_height, 0xffffffff); } } Drawing().PopClipRegion(); RenderWidget(pos,selected); }
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; }
vector<Snap*>* makeJobListFromFile(string filePath, int interpMethod, bool doSortPoint, int innPoints,float voxtabsize[3],float stepLength) { vector<Snap*>* ret = new vector<Snap*>(); Snap* current; Snap* previous = NULL; ifstream infile(filePath.c_str()); string line; int i = 0; int sizeCp = 0; double x,y,z; int nPoints = innPoints; getline(infile, line); istringstream streamLine(line); streamLine >> sizeCp; Point* tabControl = new Point[sizeCp]; while (getline(infile, line)) { istringstream streamLine(line); if(!(streamLine >> x>> y>> z)) { break; } tabControl[i].SetX(x); tabControl[i].SetY(y); tabControl[i].SetZ(z); i++; } infile.close(); if(doSortPoint) sortPoints(tabControl,sizeCp); if(stepLength != 0.0) { float pathLength = estimatePathLength(tabControl,sizeCp); nPoints = (int)(pathLength / stepLength); } switch(interpMethod){ case INTERP_DIRECT: { ret = direct(tabControl,ret,sizeCp); break; } case INTERP_BEZIER: { ret = BezierCurveByBernstein(tabControl,ret,sizeCp,nPoints); break; } case INTERP_HERMIT: { ret = hermit(tabControl,ret,sizeCp,nPoints); break; } } for(int j = 0 ; j < ret->size()-1 ; j++) { for(int i = 0 ; i < 3 ; i++) { ret->at(j)->direction[i] = ret->at(j+1)->position[i] - ret->at(j)->position[i]; } ret->at(j)->normalize(ret->at(j)->direction); } for(int i = 0 ; i < 3 ; i++) { ret->back()->direction[i] = ret->at(ret->size()-2)->direction[i]; } ret->at(0)->up[0] = -1.0; ret->at(0)->up[0] = 1.0; ret->at(0)->up[0] = 1.0; ret->at(0)->initFirstSnap(); for(int j = 0 ; j < ret->size()-1 ; j++) { doubleReflectionAlgorithm(ret->at(j),ret->at(j+1)); } for(int i = 0 ; i < 3 ; i++) { ret->back()->up[i] = ret->at(ret->size()-2)->up[i]; ret->back()->cross[i] = ret->at(ret->size()-2)->cross[i]; } return ret; }
int gEnvelopeChannel::handle(int e) { /* Adding an action: no further checks required, just record it on frame * mx*pParent->zoom. Deleting action is trickier: find the active * point and derive from it the corresponding frame. */ int ret = 0; int mx = Fl::event_x()-x(); // mouse x int my = Fl::event_y()-y(); // mouse y switch (e) { case FL_ENTER: { ret = 1; break; } case FL_MOVE: { selectedPoint = getSelectedPoint(); redraw(); ret = 1; break; } case FL_LEAVE: { draggedPoint = -1; selectedPoint = -1; redraw(); ret = 1; break; } case FL_PUSH: { /* left click on point: drag * right click on point: delete * left click on void: add */ if (Fl::event_button1()) { if (selectedPoint != -1) { draggedPoint = selectedPoint; } else { /* top & border fix */ if (my > h()-8) my = h()-8; if (mx > pParent->coverX-x()) mx = pParent->coverX-x(); if (range == RANGE_FLOAT) { /* if this is the first point ever, add other two points at the beginning * and the end of the range */ if (points.size() == 0) { addPoint(0, 0, 1.0f, 0, 1); recorder::rec(pParent->chan->index, type, 0, 0, 1.0f); addPoint(G_Mixer.totalFrames, 0, 1.0f, pParent->coverX, 1); recorder::rec(pParent->chan->index, type, G_Mixer.totalFrames, 0, 1.0f); } /* line between 2 points y = (x-a) / (b-a); a = h() - 8; b = 1 */ int frame = mx * pParent->zoom; float value = (my - h() + 8) / (float) (1 - h() + 8); addPoint(frame, 0, value, mx, my); recorder::rec(pParent->chan->index, type, frame, 0, value); recorder::sortActions(); sortPoints(); } else { /// TODO } mainWin->keyboard->setChannelWithActions((gSampleChannel*)pParent->chan->guiChannel); // update mainWindow redraw(); } } else { /* right click on point 0 or point size-1 deletes the entire envelope */ if (selectedPoint != -1) { if (selectedPoint == 0 || (unsigned) selectedPoint == points.size()-1) { recorder::clearAction(pParent->chan->index, type); points.clear(); } else { recorder::deleteAction(pParent->chan->index, points.at(selectedPoint).frame, type, false); recorder::sortActions(); points.erase(points.begin() + selectedPoint); } mainWin->keyboard->setChannelWithActions((gSampleChannel*)pParent->chan->guiChannel); // update mainWindow redraw(); } } ret = 1; break; } case FL_RELEASE: { if (draggedPoint != -1) { if (points.at(draggedPoint).x == previousXPoint) { //gLog("nothing to do\n"); } else { int newFrame = points.at(draggedPoint).x * pParent->zoom; /* x edge correction */ if (newFrame < 0) newFrame = 0; else if (newFrame > G_Mixer.totalFrames) newFrame = G_Mixer.totalFrames; /* vertical line check */ int vp = verticalPoint(points.at(draggedPoint)); if (vp == 1) newFrame -= 256; else if (vp == -1) newFrame += 256; /* delete previous point and record a new one */ recorder::deleteAction(pParent->chan->index, points.at(draggedPoint).frame, type, false); if (range == RANGE_FLOAT) { float value = (points.at(draggedPoint).y - h() + 8) / (float) (1 - h() + 8); recorder::rec(pParent->chan->index, type, newFrame, 0, value); } else { /// TODO } recorder::sortActions(); points.at(draggedPoint).frame = newFrame; draggedPoint = -1; selectedPoint = -1; } } ret = 1; break; } case FL_DRAG: { if (draggedPoint != -1) { /* y constraint */ if (my > h()-8) points.at(draggedPoint).y = h()-8; else if (my < 1) points.at(draggedPoint).y = 1; else points.at(draggedPoint).y = my; /* x constraint * constrain the point between two ends (leftBorder-point, point-point, * point-rightBorder). First & last points cannot be shifted on x */ if (draggedPoint == 0) points.at(draggedPoint).x = x()-8; else if ((unsigned) draggedPoint == points.size()-1) points.at(draggedPoint).x = pParent->coverX; else { int prevPoint = points.at(draggedPoint-1).x; int nextPoint = points.at(draggedPoint+1).x; if (mx <= prevPoint) points.at(draggedPoint).x = prevPoint; else if (mx >= nextPoint) points.at(draggedPoint).x = nextPoint; //else // points.at(draggedPoint).x = mx; else { if (pParent->gridTool->isOn()) points.at(draggedPoint).x = pParent->gridTool->getSnapPoint(mx)-1; else points.at(draggedPoint).x = mx; } } redraw(); } ret = 1; break; } } return ret; }
///======================================================================================= void CPSFloatCurveFunctor::addControlPoint(const CCtrlPoint &ctrlPoint) { _CtrlPoints.push_back(ctrlPoint); sortPoints(); updateTab(); }