TElem* FindClosestByCoordinate(const typename TVertexPositionAttachmentAccessor::ValueType& coord, typename geometry_traits<TElem>::iterator iterBegin, typename geometry_traits<TElem>::iterator iterEnd, TVertexPositionAttachmentAccessor& aaPosVRT) { if(iterBegin == iterEnd) return NULL; typename geometry_traits<TElem>::iterator iter = iterBegin; TElem* bestElem = *iter; number bestDistSq = VecDistanceSq(coord, CalculateCenter(bestElem, aaPosVRT)); iter++; while(iter != iterEnd) { number distSq = VecDistanceSq(coord, CalculateCenter(*iter, aaPosVRT)); if(distSq < bestDistSq) { bestDistSq = distSq; bestElem = *iter; } ++iter; } return bestElem; }
UG_API inline typename TAAPosVRT::ValueType CalculateGridObjectCenter(const GridObject* o, TAAPosVRT& aaPosVRT) { switch(o->base_object_id()){ case VERTEX: return CalculateCenter(static_cast<const Vertex*>(o), aaPosVRT); case EDGE: return CalculateCenter(static_cast<const Edge*>(o), aaPosVRT); case FACE: return CalculateCenter(static_cast<const Face*>(o), aaPosVRT); case VOLUME: return CalculateCenter(static_cast<const Volume*>(o), aaPosVRT); default: UG_THROW("Unknown geometric-object type."); } }
ExtendedFace::ExtendedFace(QVector <Vertex* > inVertices, QVector <ExtendedEdge* >& inEdges) { m_edges.reserve(inEdges.size()); for(int i=0;i<inEdges.size();i++) m_edges.push_back(inEdges[i]); m_vertices = inVertices; for (int i=0; i<inEdges.size(); ++i) inEdges[i]->AddIncidentFace(this); CalculateCenter(); CaluclateNorm(); BuildSmallerFace(1.0); unfoldedSmallerFace.resize(3); }
typename TAAPosVRT::ValueType CalculateCenter(TIterator begin, TIterator end, TAAPosVRT& aaPos) { int counter = 0; typename TAAPosVRT::ValueType center; VecSet(center, 0); for(TIterator iter = begin; iter != end; ++iter, ++counter) VecAdd(center, center, CalculateCenter(*iter, aaPos)); if(counter > 0) VecScale(center, center, 1./(number)counter); return center; }
// pyramid number CalculateVolumePyramid(const vector3& a, const vector3& b, const vector3& c, const vector3& d, const vector3& e) { number result = 0; // UG_LOG("a: " << a << " b: " << b << " c: " << c << " d: " << d << " e: " << e << endl) //fixme check for a set of volumes that this condition is met! // check a,b,c,d are in same plane // fixme why does this check only work in x,y plane?! // vector3 r, n, x; // VecCross(n, a, b); // VecNormalize(n, n); // // VecSubtract(r, a, b); // VecSubtract(x, c, r); // number dot = VecDot(x, n); // // UG_LOG("dot pyra: " << dot<< endl) // UG_ASSERT(dot < SMALL, // "pyramid volume calculation needs all base are points in one plane!"); vector3 center, h_, h, c1, c2, da, ba, cb, cd; VecSubtract(da, d, a); VecSubtract(ba, b, a); VecSubtract(cb, c, b); VecSubtract(cd, c, d); VecCross(c1, da, ba); VecCross(c2, cb, cd); number A = 0.5 * VecLength(c1) + 0.5 * VecLength(c2); // UG_LOG("A pyra: " << A <<endl) vector3 arr[] = { a, b, c, d }; CalculateCenter(center, arr, 4); number height = DistancePointToPlane(e, center, c1); // VecSubtract(h_, e, center); // VecAdd(h, h_, center); // VecSubtract(h, e, center); // VecLength(h); // UG_LOG("pyra h: " << height << endl) result = 1.0 / 3.0 * A * height; // UG_LOG("pyra vol: " << result << endl) return result; }
// prism number CalculateVolumePrism(const vector3& a, const vector3& b, const vector3& c, const vector3& d, const vector3& e, const vector3& f) { number result = 0; vector3 center; vector3 arr[] = { a, b, c, d, e, f }; CalculateCenter(center, arr, 6); // UG_LOG("center prism: " << center << endl) result += CalculateTetrahedronVolume(a, b, c, center); // UG_LOG("t1: " << result << endl) result += CalculateTetrahedronVolume(d, e, f, center); // UG_LOG("t1+t2: " << result << endl) result +=CalculateVolumePyramid(a, b, e, d, center); result +=CalculateVolumePyramid(b, c, f, e, center); result +=CalculateVolumePyramid(c, a, d, f, center); return result; }
number CalculateVolumeHexahedron(const vector3& a, const vector3& b, const vector3& c, const vector3& d, const vector3& e, const vector3& f, const vector3& g, const vector3& h) { number result = 0; vector3 arr[] = { a, b, c, d, e, f, g, h }; vector3 center; CalculateCenter(center, arr, 8); // top and bottom result += CalculateVolumePyramid(a, b, c, d, center); result += CalculateVolumePyramid(e, f, g, h, center); // sides result += CalculateVolumePyramid(a, b, f, e, center); result += CalculateVolumePyramid(b, c, g, f, center); result += CalculateVolumePyramid(c, d, g, h, center); result += CalculateVolumePyramid(a, d, h, e, center); return result; }
TValue operator() (Volume* e) {return CalculateCenter(e, m_aaPos);}
AABB2D::AABB2D(const Vec2f &lowerBound, const Vec2f &upperBound) : m_lowerBound(lowerBound), m_upperBound(upperBound) { CalculateHalfDims(); CalculateCenter(); }
void Texture::CalculateSize( ) { rect.SetSizeFromTexture( texture ); CalculateCenter( ); }
void MultiGridRefiner::refine() { assert(m_pMG && "refiner not has to be assigned to a multi-grid!"); if(!m_pMG) return; // the multi-grid MultiGrid& mg = *m_pMG; // make sure that the required options are enabled. if(!mg.option_is_enabled(GRIDOPT_FULL_INTERCONNECTION)) { LOG("WARNING in MultiGridRefiner::refine(): auto-enabling GRIDOPT_FULL_INTERCONNECTION.\n"); mg.enable_options(GRIDOPT_FULL_INTERCONNECTION); } // access position attachments Grid::VertexAttachmentAccessor<APosition> aaPos; if(mg.has_vertex_attachment(aPosition)) aaPos.access(mg, aPosition); // collect objects for refine collect_objects_for_refine(); // notify derivates that refinement begins refinement_step_begins(); // cout << "num marked edges: " << m_selMarks.num<Edge>() << endl; // cout << "num marked faces: " << m_selMarks.num<Face>() << endl; // we want to add new elements in a new layer. bool bHierarchicalInsertionWasEnabled = mg.hierarchical_insertion_enabled(); if(!bHierarchicalInsertionWasEnabled) mg.enable_hierarchical_insertion(true); // some buffers vector<Vertex*> vVrts; vector<Vertex*> vEdgeVrts; vector<Edge*> vEdges; vector<Face*> vFaces; // some repeatedly used objects EdgeDescriptor ed; FaceDescriptor fd; VolumeDescriptor vd; //LOG("creating new vertices\n"); // create new vertices from marked vertices for(VertexIterator iter = m_selMarks.begin<Vertex>(); iter != m_selMarks.end<Vertex>(); ++iter) { Vertex* v = *iter; if(!mg.get_child_vertex(v)) { // create a new vertex in the next layer. Vertex* nVrt = *mg.create_by_cloning(v, v); if(aaPos.valid()) { aaPos[nVrt] = aaPos[v]; // change z-coord to visualise the hierarchy //aaPos[nVrt].z() += 0.01; } } } //LOG("creating new edges\n"); // create new vertices and edges from marked edges for(EdgeIterator iter = m_selMarks.begin<Edge>(); iter != m_selMarks.end<Edge>(); ++iter) { // collect_objects_for_refine removed all edges that already were // refined. No need to check that again. Edge* e = *iter; int rule = get_rule(e); switch(rule) { case RM_COPY: { // clone the edge. ed.set_vertices(mg.get_child_vertex(e->vertex(0)), mg.get_child_vertex(e->vertex(1))); Edge* newEdge = *mg.create_by_cloning(e, ed, e); set_status(newEdge, SM_COPY); }break; default: { // create two new edges by edge-split RegularVertex* nVrt = *mg.create<RegularVertex>(e); Vertex* substituteVrts[2]; substituteVrts[0] = mg.get_child_vertex(e->vertex(0)); substituteVrts[1] = mg.get_child_vertex(e->vertex(1)); if(aaPos.valid()) { VecScaleAdd(aaPos[nVrt], 0.5, aaPos[e->vertex(0)], 0.5, aaPos[e->vertex(1)]); // change z-coord to visualise the hierarchy //aaPos[nVrt].z() += 0.01; } // split the edge e->refine(vEdges, nVrt, substituteVrts); assert((vEdges.size() == 2) && "RegularEdge refine produced wrong number of edges."); mg.register_element(vEdges[0], e); mg.register_element(vEdges[1], e); set_status(vEdges[0], SM_REGULAR); set_status(vEdges[1], SM_REGULAR); }break; } } //LOG("creating new faces\n"); // create new vertices and faces from marked faces for(FaceIterator iter = m_selMarks.begin<Face>(); iter != m_selMarks.end<Face>(); ++iter) { Face* f = *iter; int rule = get_rule(f); switch(rule) { case RM_COPY: { // clone the face. if(fd.num_vertices() != f->num_vertices()) fd.set_num_vertices(f->num_vertices()); for(size_t i = 0; i < fd.num_vertices(); ++i) fd.set_vertex(i, mg.get_child_vertex(f->vertex(i))); Face* nf = *mg.create_by_cloning(f, fd, f); set_status(nf, SM_COPY); }break; default: { // collect child-vertices vVrts.clear(); for(uint j = 0; j < f->num_vertices(); ++j){ vVrts.push_back(mg.get_child_vertex(f->vertex(j))); } // collect the associated edges vEdgeVrts.clear(); //bool bIrregular = false; for(uint j = 0; j < f->num_edges(); ++j){ Vertex* vrt = mg.get_child_vertex(mg.get_edge(f, j)); vEdgeVrts.push_back(vrt); //if(!vrt) // bIrregular = true; } /* if(bIrregular){ assert((get_rule(f) != RM_REFINE) && "Bad refinement-rule set during collect_objects_for_refine!"); //TODO: care about anisotropy set_rule(f, RM_IRREGULAR); } */ Vertex* newVrt; if(f->refine(vFaces, &newVrt, &vEdgeVrts.front(), NULL, &vVrts.front())){ // if a new vertex was generated, we have to register it if(newVrt){ mg.register_element(newVrt, f); if(aaPos.valid()){ aaPos[newVrt] = CalculateCenter(f, aaPos); // change z-coord to visualise the hierarchy //aaPos[newVrt].z() += 0.01; } } int oldRule = get_rule(f); // register the new faces and assign status for(size_t j = 0; j < vFaces.size(); ++j){ mg.register_element(vFaces[j], f); switch(oldRule) { case RM_REFINE: set_status(vFaces[j], SM_REGULAR); break; case RM_IRREGULAR: set_status(vFaces[j], SM_IRREGULAR); break; default: assert((oldRule == RM_REFINE) && "rule not yet handled.");//always fails. break; } } } else{ LOG(" WARNING in Refine: could not refine face.\n"); } } } } // done - clean up if(!bHierarchicalInsertionWasEnabled) mg.enable_hierarchical_insertion(false); m_selMarks.clear(); // notify derivates that refinement ends refinement_step_ends(); }
m2::PointD CalculateCenter(ScreenBase const & screen, m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth) { double const scale = screen.GlobalRect().GetLocalRect().SizeX() / screen.PixelRect().SizeX(); return CalculateCenter(scale, screen.PixelRect(), userPos, pixelPos, azimuth); }