LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

ZL31ARM: funkcje graficzne 3D

Teraz można wywoływać tę funkcją podając dwie współrzędne na płaszczyźnie (x,y), 3 kąty obrotu oraz to czy ma być widoczny czy nie.

Ukrywanie niewidocznych krawędzi sześcianu

Jednym ze sposobów nadania bryle solidnej formy jest usunięcie tych krawędzi, które znajdują się z „tyłu”. Zrealizowana tutaj metoda ukrywania tych elementów działa dość dobrze tylko dla sześcianu. W przypadku innych brył należałoby zmodyfikować kod, jednak możliwe, że nie ze wszystkimi rodzajami brył ta metoda będzie współpracować.
Idea polega na tym, aby po obróceniu sześcianu i przed jego wyświetleniem, wyrzucić niepotrzebne krawędzie. Jako, że przyjęty globalny układ jest nieruchomy i jego oś z jest prostopadła i skierowana w stronę wyświetlacza, to zawsze przynajmniej jedna krawędź będzie miała ujemne współrzędne początku i końca w osi z. Przy wyznaczaniu wszystkich takich linii są znajdowane pewne wartości graniczne, dolne i górne w osi x i y. Dzięki nim będzie można określić czy dana krawędź jest widoczna czy nie. Ilustruje to poniższy kod:

signed short xThresDown=0, yThresDown=0, xThresUp=0, yThresUp=0;
line3D tempBUF[12];
..
for(i=0, j=0; i < 12; i++){
if( (rotatedCube[i].z1 <= 0) && (rotatedCube[i].z2 <= 0) ){
	tempBUF[j++] = rotatedCube[i];
	if(rotatedCube[i].x1 > xThresUp)
		xThresUp = (short) rotatedCube[i].x1;
	else if(rotatedCube[i].x2 > xThresUp)
		xThresUp = (short) rotatedCube[i].x2;
	if(rotatedCube[i].y1 > yThresUp)
		yThresUp = (short) rotatedCube[i].y1;
	else if(rotatedCube[i].y2 > yThresUp)
		yThresUp = (short) rotatedCube[i].y2;			
	if(rotatedCube[i].x1 < xThresDown)
		xThresDown = (short) rotatedCube[i].x1;
	else if(rotatedCube[i].x2 < xThresDown)
		xThresDown = (short) rotatedCube[i].x2;
	if(rotatedCube[i].y1 < yThresDown)
		yThresDown = (short) rotatedCube[i].y1;
	else if(rotatedCube[i].y2 < yThresDown)
		yThresDown = (short) rotatedCube[i].y2;
}
}

Następnie należy wyszukać niewidocznych krawędzi:

//Szukaj "widocznych" krawedzi
for(i=0; i < 12; i++){

//Odrzuc juz zapamietane krawedzie
	if( (rotatedCube[i].z1 <= 0) && (rotatedCube[i].z2 <= 0) ) continue;

else if( (rotatedCube[i].x1 >= xThresUp || rotatedCube[i].y1 >= yThresUp) && 
	   (rotatedCube[i].x2 >= xThresUp || rotatedCube[i].y2 >= yThresUp))
		tempBUF[j++] = rotatedCube[i];
	else if( (rotatedCube[i].x1 >= xThresUp  || rotatedCube[i].y1 >= yThresUp) &&
   (rotatedCube[i].x2 <= xThresDown || rotatedCube[i].y2 <= yThresDown))
		tempBUF[j++] = rotatedCube[i];
	else if( (rotatedCube[i].x1 <= xThresDown || rotatedCube[i].y1 <= yThresDown) &&
   (rotatedCube[i].x2 >= xThresUp   || rotatedCube[i].y2 >= yThresUp))
		tempBUF[j++] = rotatedCube[i];
	else if( (rotatedCube[i].x1 <= xThresDown || rotatedCube[i].y1 <= yThresDown) &&
   (rotatedCube[i].x2 <= xThresDown || rotatedCube[i].y2 <= yThresDown))
		tempBUF[j++] = rotatedCube[i];
}

Nowy zbiór krawędzi jest zapamiętywany w tablicy tempBUF[], która zostanie następnie wyświetlona:

//Rysuj kolejne krawedzie szescianu
for(i=0; i < j; i++){
  //rotatedCube[i] = tempBUF[i];
  drawLine(x0+tempBUF[i].x1,y0+tempBUF[i].y1,x0+tempBUF[i].x2,y0+tempBUF[i].y2,color);
Autor: Jan Szemiet
Tagi: BTC, STM32