Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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));
				}
			}
		}
	}