Skip to content

Instantly share code, notes, and snippets.

@Amorim33
Last active December 14, 2022 14:35
Show Gist options
  • Save Amorim33/a089a05e3f05ebc077000319dbe14a46 to your computer and use it in GitHub Desktop.
Save Amorim33/a089a05e3f05ebc077000319dbe14a46 to your computer and use it in GitHub Desktop.
Busca com Coordenadas Baricêntricas - cpp, openGL.

Exercício de Programação da disciplina de Matrizes, Vetores e Geometria Analítica da EACH-USP

Aluisio Amorim

Estruturas e variáveis globais:

// estrutura para representar um ponto no plano cartesiano
typedef struct {
  double x, y;
} CartesianPoint;


// estrutura para representar um triângulo como um conjunto de três pontos
typedef struct {
  CartesianPoint a, b, c;
} Triangle;

typedef struct {
  double u, v, w;
} Barycentric;


double x_inp, y_inp;
CartesianPoint p_from_input;
Triangle triangle;
vector<int> cell_ids_to_print;

Funções auxiliares:

Barycentric barycentrics_for_p_in_triangle(CartesianPoint p, Triangle t) {
  // calcular as coordenadas baricêntricas do ponto
  double u, v, w;
  barycentric(p, t, u, v, w);

  cout<<"Coordenadas baricentricas:"<<endl;
  cout<<u<<" "<<v<<" "<<w<<endl;

  return { u, v, w };
}

Triangle get_cell_triangle(int cell_id){
	CartesianPoint p[3];
	for(int i = 0; i < 3; i++){
		double x = malha->getVertex(malha->getCell(cell_id)->getVertexId(i))->getCoord(0);
		double y = malha->getVertex(malha->getCell(cell_id)->getVertexId(i))->getCoord(1);
		p[i] = {x, y};
	}
	Triangle t = {p[0], p[1], p[2]};
	return t;
}

Funções principais:

// função para calcular as coordenadas baricêntricas de um ponto em um triângulo
void barycentric(CartesianPoint p, Triangle t, double &u, double &v, double &w) {
  // calcular os lados do triângulo
  double x0 = t.a.x, y0 = t.a.y;
  double x1 = t.b.x, y1 = t.b.y;
  double x2 = t.c.x, y2 = t.c.y;

  // calcular as coordenadas baricêntricas
  double a0 = -(x1*(p.y-y2)+x2*(y1-p.y)+(y2-y1)*p.x)/(x1*(y2-y0)+x0*(y1-y2)+x2*(y0-y1));
  double a1 = (x0*(p.y-y2)+x2*(y0-p.y)+(y2-y0)*p.x)/(x1*(y2-y0)+x0*(y1-y2)+x2*(y0-y1));
  double a2 = (x1*(p.y-y0)+x0*(y1-p.y)+(y0-y1)*p.x)/(x1*(y2-y0)+x0*(y1-y2)+x2*(y0-y1));

  // atribuir as coordenadas baricêntricas calculadas às variáveis de entrada
  u = a0;
  v = a1;
  w = a2;
}

// encontrar ponto p na malha percorrendo os triângulos recurssivamente 
void find_p(CartesianPoint p, Triangle t, int cell_id){
	cell_ids_to_print.push_back(cell_id);
	Interactor->Refresh_List();

	Barycentric b = barycentrics_for_p_in_triangle(p,t);
	double p_min = min(b.u,min(b.v,b.w));
	// para p com coordenadas baricêntricas {u, v, w} >= 0, p está contido no triângulo
	if(p_min >= 0){
		cout<<"Ponto esta dentro do triangulo"<<endl;
		cout<<"Coordenadas Baricentricas: ("<<b.u<<", "<<b.v<<", "<<b.w<<")"<<endl;

		return;
	}
	// para p com coordenadas baricêntricas negativas, o vértice de coeficiente mais negativo indica que p 
	// está na direção da aresta oposta a este vértice
	if (p_min == b.u){
		cout<<"Ponto esta na aresta bc"<<endl;
		int vertex_id = malha->getCell(cell_id)->getVertexId(0);
		int mate_cell_id = malha->getCell(cell_id)->getMateVertexId(vertex_id);

		Triangle t = get_cell_triangle(mate_cell_id);

		find_p(p, t, mate_cell_id);
	}
	else if(p_min == b.v){
		cout<<"Ponto esta na aresta ac"<<endl;
		int vertex_id = malha->getCell(cell_id)->getVertexId(1);
		int mate_cell_id = malha->getCell(cell_id)->getMateVertexId(vertex_id);
		Triangle t = get_cell_triangle(mate_cell_id);


		find_p(p, t, mate_cell_id);
	}
	else if(p_min == b.w){
		cout<<"Ponto esta na aresta ab"<<endl;
		int vertex_id = malha->getCell(cell_id)->getVertexId(2);
		int mate_cell_id = malha->getCell(cell_id)->getMateVertexId(vertex_id);

		Triangle t = get_cell_triangle(mate_cell_id);

		find_p(p, t, mate_cell_id);
	}
	else{
		cout<<"Ponto não encontrado"<<endl;
	}
}

Render Scene:

void RenderScene(void){ 
	allCommands->Execute();
	Print->Vertices(malha,blue,3);
	Print->FacesWireframe(malha,grey,3);
	for(auto it: cell_ids_to_print){
		Print->Face(it, red);
	}

	glFinish();
	glutSwapBuffers();
}

Provas de Conceito:

image image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment