Il titolo potrebbe non essere abbastanza intuitivo, ma ho bisogno di qualche aiuto concettuale per implementare una soluzione per passare attraverso un array:
Sto sviluppando un programma per calcolare il percorso "più shadepath" tra un'origine e un destino, per ottenere ciò un array si riempie di tutti i valori che rappresentano l'altezza del terreno e ogni valore si riferisce a una coordinata UTM. Il sole gira attorno a questo array bidimensionale e la posizione del sole in ogni momento è determinata dal azimut che è semplicemente un angolo tra il vettore nord e la proiezione perpendicolare della stella in basso sull'orizzonte, in altri parole, un angolo formato tra lo zenit e la posizione attuale del sole in senso orario, con questo in mente ora rappresentiamo un array bidimensionale:
Seprendiamoquattrolaticomeiquattropunticardinali,ilnordsitroveràinalto,inaltoadestra,ecc...quindiilsolesorgedaestetramontaaovestnonprimadipassareasud.
Perunvaloredicellanelnostroarraycherappresentalanostraposizioneattualeinunaposizionegeografica,attraversoazimut,otteniamolaposizionedelsoleetraquestoelanostraposizionedobbiamocalcolaretuttelecellechecopronoquestaproiezioneperottenerealtezzepossibiliditerrenochebloccalalucedelsoleinquelmomentoe,diconseguenza,vieneproiettataun'ombra.
Quandoilsoleènelsuozenito90º,180ºo270ºnoncisonoproblemiperchélecolonneolefilesonougualienonsiforma"diagonale" tra il sole e la nostra posizione ma non si verifica quando il sole non è nella sua posizione molto-est per esempio, la mia domanda e il dubbio dopo tutto è ... Come posso determinare un modo per calcolare l'incremento o il decremento per passare attraverso le celle di colonna e riga che indicano l'angolo di sole e la mia posizione per sapere quale diagonale devo visitare le celle per prendere altezze fino alla fine della matrice?
Forse non sono più esplicito, ma spero che tu possa capire, potrei rendere un grafico più esplicativo se ci sono problemi di comprensione.
Saluti!
Modifica con una spiegazione grafica di cosa è l'azimut:
Modifica
Finalmentehotrovatounasoluzioneperdiagonalizzareusandol'algoritmo
Per ottenere la riga di confine e i valori di col della matrice possiamo interpolare , se dividiamo la matrice bidimensionale in quattro parti intersecate da due linee, la linea verticale verso l'alto rappresenta l'azimut per 0º e 360º e il lato inferiore di 180º, la linea orizzontale a destra sarà di 90º e 180º per il lato sinistro; ora i quattro angoli dell'array saranno 45º, 135º, 225º e 315º, vedi sopra la grafica per avere un riferimento nella tua mente.
È come sovrapporre una circonferenza nel nostro array per farti venire in mente cose facili, più valori di angoli prendi come riferimento per l'array più precisi saranno i valori finali quando interpolati.
Quindi, se prendiamo un esempio per capire meglio quello che ho detto prima, immaginando un array con dimensione di 380x316, se dividiamo l'array su quattro lati, il centro per i cols sarà 190 e per le righe 158, il quarto quadrante va da (0,158) per 270º e (190,0) per 0º / 360º e 315º sarebbe (0,0) quindi, usando interpolazione lineare x2 = ((y2 - y1) (x3 - x1) / (y3 - y1)) + x1 dove y coefficienti corrispondono per valori di angolo e x valori per righe o colonne predefiniti per valori di angoli, quindi se prendiamo un azimut di 275º che corrisponde ad un angolo del 4o quadrante sappiamo che il valore del bordo per il quadrante in questo quadrante è 0, quindi dobbiamo interpolare per i valori di riga, cioè, tra 0 e 158, prendendo tra 315º (0,0) e 270º (0,158 ) la nostra ingonite è il valore di riga tra questi, quindi se sostituiamo: x2 = ((275-315) (158-0) / (270-315)) + 0 = 140
Infine il valore intermedio tra 0 e 158 è 140 o meglio dire [0] [140] quindi se prendiamo qualsiasi valore della nostra matrice per esempio [190] [0] passando alla funzione drawLine che prende il parametro x origine, y origine, x finale e y finale otterremmo tutti i punti per fare una linea tra questi due punti in modo che ora possiamo tracciare la nostra linea diagonale nella matrice!
Ora ho incollato l'algoritmo per Xiaolin WU per Java perché ti ricorderai di come è il meccanismo, ho saltato le funzioni per tracciare le linee perché ovviamente non è il mio scopo:
package calculateShadowProjection;
/*
* Xiaolin Wu's line algorithm is an algorithm for line antialiasing, which was presented in the article An Efficient Antialiasing Technique in the July 1991 issue of Computer Graphics, as well as in the article Fast Antialiasing in the June 1992 issue of Dr. Dobb's Journal.
Bresenham's algorithm draws lines extremely quickly, but it does not perform anti-aliasing. In addition, it cannot handle any cases where the line endpoints do not lie exactly on integer points of the pixel grid. A naive approach to anti-aliasing the line would take an extremely long time. Wu's algorithm is comparatively fast, but is still slower than Bresenham's algorithm. The algorithm consists of drawing pairs of pixels straddling the line, each coloured according to its distance from the line. Pixels at the line ends are handled separately. Lines less than one pixel long are handled as a special case.
An extension to the algorithm for circle drawing was presented by Xiaolin Wu in the book Graphics Gems II. Just like the line drawing algorithm is a replacement for Bresenham's line drawing algorithm, the circle drawing algorithm is a replacement for Bresenham's circle drawing algorithm.
*/
public class AlgorithmXiaolinWu {
public AlgorithmXiaolinWu(){
}
public void plot(int x, int y, double c){
}
public int ipart(double x){
return (int)x;
}
public int round(double x){
return ipart(x + 0.5);
}
public double fpart(double x){
if (x<0)
return 1-(x-Math.floor(x));
return x - Math.floor(x);
}
public double rfpart(double x){
return 1 - fpart(x);
}
public void drawLine(double x0, double y0, double x1, double y1){
double aux, x0_orig, x1_orig, y0_orig, y1_orig;
y1_orig=y1;
y0_orig=y0;
x1_orig=x1;
x0_orig=x0;
boolean steep = Math.abs(y1-y0) > Math.abs(x1-x0);
if(steep){
aux = x0;
x0 = y0;
y0 = aux;
aux = x1;
x1 = y1;
y1 = aux;
}
if(x0>x1){
aux = x0;
x0 = x1;
x1 = aux;
aux = y0;
y0 = y1;
y1 = aux;
}
double dx = x1-x0;
double dy = y1-y0;
double gradient = dy / dx;
//handle first endpoint
double xend = round(x0);
double yend = y0 + gradient * (xend - x0);
double xgap = rfpart(x0 + 0.5);
int xpxl1 = (int)(xend); //this will be used in the main loop
int ypxl1 = ipart(yend);
if(steep){
}
else{
}
double intery = yend + gradient; // first y-intersection for the main loop
// handle second endpoint
xend = round(x1);
yend = y1 + gradient * (xend - x1);
xgap = rfpart(x1 + 0.5);
int xpxl2 = (int)(xend); //this will be used in the main loop
int ypxl2 = ipart(yend);
if(steep){
}
else{
}
for(int x = xpxl1+1; x<=xpxl2-1;x++){
if(steep){
System.out.format("Point: [%d][%d]\n", ipart(intery), x);
System.out.format("Point: [%d][%d]\n", ipart(intery)+1, x);
}
else{
System.out.format("Point: [%d][%d]\n", x,ipart(intery));
System.out.format("Point: [%d][%d]\n", x,ipart(intery)+1);
}
intery=intery+gradient;
}
}
public static void main(String[]args){
AlgorithmXiaolinWu axw = new AlgorithmXiaolinWu();
// Test 4º quadrant to 3º quadrant
axw.drawLine(190, 0, 0, 140);
// Test 4º quadrant to 4º quadrant
axw.drawLine(190, 40, 0, 10);
// Test 1º quadrant to 1º quadrant
axw.drawLine(290, 10, 380, 140);
// Test 1º quadrant to 3º quadrant
axw.drawLine(290, 10, 340, 316);
// Test 4º quadrant to 3º quadrant
axw.drawLine(290, 170, 210, 316);
// Test 2º quadrant to 3º quadrant
axw.drawLine(290, 170, 140, 316);
}
}