/* * Add an edge to a ring of edges. */ static void splice(edge * a, edge * b, point * v) { edge *next; /* b must be the unnattached edge and a must be the previous ccw edge to b. */ if (Org(a) == v) { next = Onext(a); Onext(a) = b; } else { next = Dnext(a); Dnext(a) = b; } if (Org(next) == v) Oprev(next) = b; else Dprev(next) = b; if (Org(b) == v) { Onext(b) = next; Oprev(b) = a; } else { Dnext(b) = next; Dprev(b) = a; } }
/* * Remove an edge. */ static void delete_edge(edge * e) { point *u, *v; /* Cache origin and destination. */ u = Org(e); v = Dest(e); /* Adjust entry points. */ if (u->entry_pt == e) u->entry_pt = e->onext; if (v->entry_pt == e) v->entry_pt = e->dnext; /* Four edge links to change */ if (Org(e->onext) == u) e->onext->oprev = e->oprev; else e->onext->dprev = e->oprev; if (Org(e->oprev) == u) e->oprev->onext = e->onext; else e->oprev->dnext = e->onext; if (Org(e->dnext) == v) e->dnext->oprev = e->dprev; else e->dnext->dprev = e->dprev; if (Org(e->dprev) == v) e->dprev->onext = e->dnext; else e->dprev->dnext = e->dnext; free_edge(e); }
/* * Creates a new edge and adds it to two rings of edges. */ static edge *join(edge * a, point * u, edge * b, point * v, side s) { edge *e; /* u and v are the two vertices which are being joined. a and b are the two edges associated with u and v res. */ e = make_edge(u, v); if (s == side::left) { if (Org(a) == u) splice(Oprev(a), e, u); else splice(Dprev(a), e, u); splice(b, e, v); } else { splice(a, e, u); if (Org(b) == v) splice(Oprev(b), e, v); else splice(Dprev(b), e, v); } return e; }
static void divide(point * p_sorted[], int l, int r, edge ** l_ccw, edge ** r_cw) { int n; edge *l_ccw_l, *r_cw_l, *l_ccw_r, *r_cw_r, *l_tangent; edge *a, *b, *c; n = r - l + 1; if (n == 2) { /* Bottom of the recursion. Make an edge */ *l_ccw = *r_cw = make_edge(p_sorted[l], p_sorted[r]); } else if (n == 3) { /* Bottom of the recursion. Make a triangle or two edges */ double c_p; a = make_edge(p_sorted[l], p_sorted[l + 1]); b = make_edge(p_sorted[l + 1], p_sorted[r]); splice(a, b, p_sorted[l + 1]); c_p = Cross_product_3p(p_sorted[l], p_sorted[l + 1], p_sorted[r]); if (c_p > 0.0) { /* Make a triangle */ c = join(a, p_sorted[l], b, p_sorted[r], side::right); *l_ccw = a; *r_cw = b; } else if (c_p < 0.0) { /* Make a triangle */ c = join(a, p_sorted[l], b, p_sorted[r], side::left); *l_ccw = c; *r_cw = c; } else { /* Points are collinear, no triangle */ *l_ccw = a; *r_cw = b; } } else if (n > 3) { /* Continue to divide */ /* Calculate the split point */ int split = (l + r) / 2; /* Divide */ divide(p_sorted, l, split, &l_ccw_l, &r_cw_l); divide(p_sorted, split + 1, r, &l_ccw_r, &r_cw_r); /* Merge */ merge(r_cw_l, p_sorted[split], l_ccw_r, p_sorted[split + 1], &l_tangent); /* The lower tangent added by merge may have invalidated l_ccw_l or r_cw_r. Update them if necessary. */ if (Org(l_tangent) == p_sorted[l]) l_ccw_l = l_tangent; if (Dest(l_tangent) == p_sorted[r]) r_cw_r = l_tangent; /* Update edge refs to be passed back */ *l_ccw = l_ccw_l; *r_cw = r_cw_r; } }
void CAutoPFAView::ZoomScrollSizes(const CRect &rc,BOOL bFit )//调整窗口可视区域使得大小和rc相当 { CRect rcView; GetClientRect(&rcView); CSize szTol(rc.Size()); CPoint Org(rc.left,rc.top); CSize szDoc; double dDocX; double dDocY; szDoc = GetTotalSize(); dDocX = szDoc.cx / m_Scale; dDocY = szDoc.cy / m_Scale; if(bFit) { if(szTol.cx<rcView.Size().cx) { szTol.cx = rcView.Size().cx; } if(szTol.cy<rcView.Size().cy) { szTol.cy = rcView.Size().cy; } } float x= float(rcView.Size().cx)/(szTol.cx); float y= float(rcView.Size().cy)/(szTol.cy); if(x>y) m_Scale = y; else m_Scale = x; szDoc.cx = m_Scale * dDocX; szDoc.cy = m_Scale * dDocY; if(szDoc.cx <= rcView.Size().cx) { Org.x = 0; } if(szDoc.cy <= rcView.Size().cy) { Org.y = 0; } Org.x = m_Scale* (Org.x); Org.y = m_Scale* (Org.y); SetScrollSizes(MM_TEXT,szDoc); ScrollToPosition(Org); Invalidate(); }
//---------- void Mesh2DFromGraycode::triangulate() { this->throwIfMissingAnyConnection(); auto dataSet = this->getInput<Scan::Graycode>()->getDataSet(); if (!dataSet.getHasData()) { throw(Exception("No scan data available")); } //get camera coords in projector space map const auto & cameraInProjector = dataSet.getDataInverse(); const auto & active = dataSet.getActive(); const auto projectorWidth = cameraInProjector.getWidth(); const auto projectorHeight = cameraInProjector.getHeight(); const auto cameraWidth = active.getWidth(); auto getCameraPixelPosition = [&cameraInProjector, projectorWidth, cameraWidth](int i, int j) { const auto cameraPixelIndex = cameraInProjector.getData()[i + j * projectorWidth]; return ofVec2f(cameraPixelIndex % cameraWidth, cameraPixelIndex / cameraWidth); }; auto isActive = [& cameraInProjector, &active, projectorWidth](int i, int j) { const auto cameraPixelIndex = cameraInProjector.getData()[i + j * projectorWidth]; const auto isActive = active.getData()[cameraPixelIndex]; return isActive; }; vector<ofPoint> projectorSpaceActivePoints; //find all active pixels for (int j = 0; j < projectorHeight; j++) { for (int i = 0; i < projectorWidth; i++) { if (isActive(i, j)) { projectorSpaceActivePoints.emplace_back(ofVec2f(i, j)); } } } //triangulate ofMesh mesh; { //make vertices and tex coords Delaunay::Point tempP; vector<Delaunay::Point> delauneyPoints; for (const auto & projectorSpaceActivePoint : projectorSpaceActivePoints) { delauneyPoints.emplace_back(projectorSpaceActivePoint.x, projectorSpaceActivePoint.y); mesh.addVertex(projectorSpaceActivePoint); mesh.addTexCoord(getCameraPixelPosition(projectorSpaceActivePoint.x, projectorSpaceActivePoint.y)); } //triangulate auto delauney = make_shared<Delaunay>(delauneyPoints); delauney->Triangulate(); //apply indices for (auto it = delauney->fbegin(); it != delauney->fend(); ++it) { mesh.addIndex(delauney->Org(it)); mesh.addIndex(delauney->Dest(it)); mesh.addIndex(delauney->Apex(it)); } } swap(this->getInput<Data::Mesh>()->getMesh(), mesh); }