Line CoarseSegmentProcessor::average(Line line1, Line line2) { Line result; result.p0 = averagePoint(line1.p0, line2.p0); result.p1 = averagePoint(line1.p1, line2.p1); return result; }
vector<Triangle*> Triangle::subdivide() const { Point *point1 = getPoint(allPoints, averagePoint(points[0], points[1])); Point *point2 = getPoint(allPoints, averagePoint(points[0], points[2])); Point *point3 = getPoint(allPoints, averagePoint(points[1], points[2])); vector<Triangle*> triangles; triangles.push_back(new Triangle(points[0], point1, point2, allPoints)); triangles.push_back(new Triangle(points[1], point1, point3, allPoints)); triangles.push_back(new Triangle(points[2], point2, point3, allPoints)); triangles.push_back(new Triangle(point1, point2, point3, allPoints)); return triangles; }
glm::vec2 KeyboardMouseDevice::evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) const { glm::vec2 averagePoint(0.0f); if (points.count() > 0) { for (auto& point : points) { averagePoint += glm::vec2(point.pos().x(), point.pos().y()); } averagePoint /= (float)(points.count()); } return averagePoint; }
vector3<Real> Polyhedron<Real>::getAveragePoint() const { vector3<Real> averagePoint(vector3<Real>::zero); Real scale = ((Real) 1.0) / vertices.size(); for (uint i = 0; i < vertices.size(); ++i) averagePoint += vertices[i] * scale; return averagePoint; }
void Polyhedron<Real>::addConvexPointToPolyhedron( const std::vector<plane<Real >> &planes, const std::vector<vector3<Real >> &vertices, const std::vector<PolyhedronEdge> &edges, const vector3<Real> &spot, std::vector<plane<Real >> &new_planes, std::vector<vector3<Real >> &new_vertices, std::vector<PolyhedronEdge> &new_edges) { //TODO wyprofilować i zoptymalizować /* założenia: 1) żaden wierzchołek się nie powtarza 2) żadna płaszczyzna się nie powtarza */ vector3<Real> averagePoint(vector3<Real>::zero); Real scale = ((Real) 1.0) / vertices.size(); for (uint i = 0; i < vertices.size(); ++i) averagePoint += vertices[i] * scale; new_vertices.reserve(vertices.size() + 1); new_vertices.clear(); new_vertices.push_back(spot); int num_spot = 0; // new_vertices.size() -1; new_edges.clear(); new_planes.clear(); std::vector<bool> isPlaneUseful(planes.size()); std::vector<int> oldNewVertexMapping(vertices.size()); std::vector<int> oldNewPlaneMapping(planes.size()); /* klucz - indeks starego wierzchołka (!= spot) nowej krawędzi wartość - druga ściana która wspóldzieli nową krawędź lub pusta gdy nieznana */ std::map<int, int> oldEdgesToNewWalls; for (uint i = 0; i < oldNewVertexMapping.size(); ++i) oldNewVertexMapping[i] = -1; //unused for (uint i = 0; i < oldNewPlaneMapping.size(); ++i) oldNewPlaneMapping[i] = -1; //unused for (uint i = 0; i < planes.size(); ++i) { bool planeUseful = (planes[i].distance(spot) >= -std::max(error, std::fabs(error * planes[i].d))); isPlaneUseful[i] = planeUseful; if (planeUseful) { new_planes.push_back(planes[i]); oldNewPlaneMapping[i] = new_planes.size() - 1; } } for (uint i = 0; i < edges.size(); ++i) { char usefulness = 0; if (isPlaneUseful[edges[i].num_p1]) usefulness++; if (isPlaneUseful[edges[i].num_p2]) usefulness++; if (usefulness == 0) continue; /* wierczhołkom mogły pozmieniać się numery, następne 10 linijek to załatwia */ int new_num_v1 = oldNewVertexMapping[edges[i].num_v1]; if (new_num_v1 == -1) { new_vertices.push_back(vertices[edges[i].num_v1]); new_num_v1 = new_vertices.size() - 1; oldNewVertexMapping[edges[i].num_v1] = new_num_v1; } int new_num_v2 = oldNewVertexMapping[edges[i].num_v2]; if (new_num_v2 == -1) { new_vertices.push_back(vertices[edges[i].num_v2]); new_num_v2 = new_vertices.size() - 1; oldNewVertexMapping[edges[i].num_v2] = new_num_v2; } /* płaszczyznom też mogły się zmienić numery, ale tu test na -1 (wyrzucenie złej płaszczyzny) zanużymy w podprzypadku. */ int new_num_p1 = oldNewPlaneMapping[edges[i].num_p1]; int new_num_p2 = oldNewPlaneMapping[edges[i].num_p2]; if (usefulness == 2) // obie płaszczyzny istnieją, super. { //PolyhedronEdge(uint _num_v1, uint _num_v2, uint _num_p1, uint _num_p2) new_edges.push_back(PolyhedronEdge(new_num_v1, new_num_v2, new_num_p1, new_num_p2)); } else { // jedna istnieje, druga nie. if (new_num_p1 == -1) // dla ułatwienia, zawsze druga nieistnieje { new_num_p1 = new_num_p2; new_num_p2 = -1; } // tworzę nową ścianę plane<Real> new_plane(new_vertices[new_num_v1], new_vertices[new_num_v2], spot); /* plane<Real> new_plane2(plane<Real>::stablePlaneFromPoints(new_vertices[new_num_v1], new_vertices[new_num_v2], spot)); NEWLOG("p1:[%f\t][%f\t][%f\t][%f\t]\np2:[%f\t][%f\t][%f\t][%f\t]", new_plane.normal.x, new_plane.normal.y, new_plane.normal.z, new_plane.d, new_plane2.normal.x, new_plane2.normal.y, new_plane2.normal.z, new_plane2.d); */ if (new_plane.distance(averagePoint) < -std::max(error, std::fabs(error * new_plane.d))) new_plane.flip(); new_planes.push_back(new_plane); new_num_p2 = new_planes.size() - 1; //dodaję STARĄ krawędź new_edges.push_back(PolyhedronEdge(new_num_v1, new_num_v2, new_num_p1, new_num_p2)); /* próbuję dodać od 0 do 2 NOWYCH KRAWĘDZI TUTAJ new_num_p1 jest już BEZUŻYTECZNE, (wskazuje starą ścianę, już załatwioną) new_num_p2 wskazuje nowoutworzoną ścianę new_num_v1 i new_num_v2 wskazują stare wierzchołki poniższy kod działa tak: dla każdego ze starych wierzchołków (new_num_v1, new_num_v2) mam krawędź (stary_wierzchołek, spot) którą identyfikuję za pomocą indeksu starego wierzchołka (wallKey) sprawdzam w mapie: jeśli druga ściana przyległa do tej krawędzi już istnieje, to mogę dodać krawędź do zbioru nowych (bo wreszcie znam wszystkie arg. konstruktora) jeśli jeszcze nie istenieje, to zostawiam informacje o tej ścianie i czekam, aż krawędź zostanie dodana przy okazji dodawania ściany przyległej. */ std::map<int, int>::iterator secondWall; // najpierw sprawdzamy ścianę przyległą z new_num_v1 int wallKey = new_num_v1; secondWall = oldEdgesToNewWalls.find(wallKey); if (secondWall == oldEdgesToNewWalls.end()) // nie znamy drugiej ściany dla tej krawędzi. { oldEdgesToNewWalls[wallKey] = new_num_p2; // to ją dodajemy i kiedyś do tego wrócimy //NEWLOG("pkt %d czeka", wallKey); } else // wiemy z którą ścianą ta krawędź będzie współdzielona { //NEWLOG("pkt %d się doczekał", secondWall->first); new_edges.push_back(PolyhedronEdge(new_num_v1, num_spot, new_num_p2, secondWall->second)); } // teraz sprawdzamy ścianę przyległa z new_num_v2 wallKey = new_num_v2; secondWall = oldEdgesToNewWalls.find(wallKey); if (secondWall == oldEdgesToNewWalls.end()) // nie znamy drugiej ściany dla tej krawędzi. { oldEdgesToNewWalls[wallKey] = new_num_p2; // to ją dodajemy i kiedyś do tego wrócimy //NEWLOG("pkt %d czeka", wallKey); } else // wiemy z którą ścianą ta krawędź będzie współdzielona { //NEWLOG("pkt %d się doczekał", secondWall->first); new_edges.push_back(PolyhedronEdge(new_num_v2, num_spot, new_num_p2, secondWall->second)); } } } }