PDA

View Full Version : ho 3 vettori e devo ricavare un angolo


okay
05-10-2005, 15:13
ESEMPIO 1
Ho 3 vettori che sono in pratica un triangolo che io ricavo

vDietro3 = pAI->Pos - pNodePath2[pAI->WayPos+1].Pos;
vDietro2 = pNodePath2[pAI->WayPos].Pos - pNodePath2[pAI >WayPos+1].Pos;
vDietro1 = pAI->Pos - pNodePath2[pAI->WayPos].Pos;

con le funzioni di trigonometria vorrei ricavare almeno un angolo tra 2 vettori

So solo che ottenendo l'angolo in gradi posso fare sin(angolo) e allora posso ricavare l'altezza del primo vettore oppure cos(angolo) e ricavare l'altezza del secondo vettore.

non sò come procedere

ESEMPIO 2
Un'altro modo che conosco è usare il dot di directx che è così:

vDietro3 = pAI->Pos - pNodePath2[pAI->WayPos+1].Pos;
vDietro2 = pNodePath2[pAI->WayPos].Pos - pNodePath2[pAI >WayPos+1].Pos;
vDietro1 = pAI->Pos - pNodePath2[pAI->WayPos].Pos;
vDietro4 = vDietro2;
D3DXVec3Normalize( &vDietro2, &vDietro3 );

angolo = dot( vDietro2, vDietro3 );
calcol=D3DXVec3Length(&vDietro4);
Altezza=sin(angolo)*calcol;

............ invece quì angolo è un numero che varia in continuazione e poi non capisco se è in gradi o radianti e quindi non riesci a capire se l'altezza trovata è giusta

????

Ziosilvio
05-10-2005, 15:28
Il prodotto scalare di due vettori è pari al prodotto delle loro norme e del coseno dell'angolo formato.
Ossia: dati due vettori u e v che formano un angolo theta, vale sempre:

"u scalar v" = ||u|| ||v|| cos theta

Quindi, se hai u e v e vuoi ottenere theta, basta che fai:

theta = arc cos ("u scalar v" / (||u|| ||v||) )

okay
05-10-2005, 16:27
Il prodotto scalare di due vettori è pari al prodotto delle loro norme e del coseno dell'angolo formato.
Ossia: dati due vettori u e v che formano un angolo theta, vale sempre:

"u scalar v" = ||u|| ||v|| cos theta

Quindi, se hai u e v e vuoi ottenere theta, basta che fai:

theta = arc cos ("u scalar v" / (||u|| ||v||) )

è quello che temevo, io sti segni da scienziati non li capisco se li mettessi tipo formula c++ sarebbe meglio per me e attinenti a quello che ho chiesto per il mio algoritmo.

theta = arc cos ("u scalar v" / (||u|| ||v||) )
significa:
theta = sin(u)/cos(v); //per caso??
se è così u e v come li ottieni oppure sono per caso le lunghezze dei miei 2 vettori ??

The3DProgrammer
05-10-2005, 16:38
è quello che temevo, io sti segni da scienziati non li capisco se li mettessi tipo formula c++ sarebbe meglio per me e attinenti a quello che ho chiesto per il mio algoritmo.

theta = arc cos ("u scalar v" / (||u|| ||v||) )
significa:
theta = sin(u)/cos(v); //per caso??
se è così u e v come li ottieni oppure sono per caso le lunghezze dei miei 2 vettori ??

no,
significa qualkosa del genere



inline float scalar(const Vector& a,const Vector& b){

return a.x*b.x+a.y*b.y+a.z*b.z;

}

Vector a,b;

theta =acos(scalar(a,b)/sqrt(scalar(a,a))*sqrt(scalar(b,b))


a meno di errori grossolani, torno ora da Roma ;)

ciauz

The3DProgrammer
05-10-2005, 16:44
ah,

ho riletto il tuo post,se a e b sono normalizzati ovviamente theta = acos(scalar(a,b)), in quanto il modulo delle normali è pari ad 1

ciauz

okay
05-10-2005, 16:52
ah,

ho riletto il tuo post,se a e b sono normalizzati ovviamente theta = acos(scalar(a,b)), in quanto il modulo delle normali è pari ad 1

ciauz

grazie a tutti e 2

ma theta, come ultima info, mi ritorna l'angolo in radianti o gradi. Grazie

okay
05-10-2005, 17:27
angolo = acos(scalar(vDietro2,vDietro1));

ma ho angolo che vale -1.#IND000

okay
05-10-2005, 17:49
così và bene:
angolo = cos(scalar(vDietro1, vDietro2));

ma questo valore è in gradi o radianti??

Ziosilvio
05-10-2005, 18:30
così và bene:
angolo = cos(scalar(vDietro1, vDietro2));

ma questo valore è in gradi o radianti??
In radianti, naturalmente.

The3DProgrammer
05-10-2005, 19:16
così và bene:
angolo = cos(scalar(vDietro1, vDietro2));

ma questo valore è in gradi o radianti??


uhm...

non va bene... scalar ritorna già cos(theta), ergo cos(scalar(....)) = cos(cos(theta))

per ricavare theta devi usare la funzione inversa del coseno, che è appunto l'arcoseno ( la funzione C è appunto acos()).

ciauz

okay
05-10-2005, 20:15
uhm...

non va bene... scalar ritorna già cos(theta), ergo cos(scalar(....)) = cos(cos(theta))

per ricavare theta devi usare la funzione inversa del coseno, che è appunto l'arcoseno ( la funzione C è appunto acos()).

ciauz


Aspettate un attimo.................. allora diciamola tutta (volevo verificare alcune certezze facendo alcuni calcoli)

dunque:

ho una spline.x formata da 466 vertici se navigo sulla spline sto a coordinate 0 se mi sposto dalla spline a destra o a sinistra ho un valora di scostamento che ho chiamato Dist quindi se Dist vale 0 io sto sulla spline.x.
Questo calcolo lo faccio tramite:
D3DXVec3Cross(&vRis1, &vBas, &vDir);

ed è corretto
per verificare che io lo possa fare in altri modi vi confermo questo:

posso distanziarmi tramite:
a=lenght(posizione attuale - vertice+1)
b=lenght(vertice+1 - vertice)
c=lenght(posizione attuale - vertice)

ecco con anche in questo modo ottengo lo scostamento (l'ho verificato) tramite appunto il formarsi dal calcolo sopra di un triangolo, quindi applicando la regola per trovare l'altezza, ottengo che l'altezza di questo triangolo equivale allo scostamento dal Path b=lenght(vertice+1 - vertice) come il calcolo del D3DXVec3Cross.

Stavo provando questo ed ultimo modo fatto con le leggi della trigonometria e cioè: In sintesi è così:

http://www.twork.it/work/aufgabe1.gif

Quindi h = sin(19.5°) × 3.7 km.
sin(19.5°) = 0.3338, e quindi
h = 0.3338 × 3.7 km = 1.24 km, arrotondando il risultato ragionevolmente.

ECCO questo secondo me è l'altro modo per ricavare l'altezza/scostamento

il mio codice per far questo ora è:

vDietro1 = pAI->Pos - pNodePath2[pAI->WayPos+1].Pos;
vDietro2 = pNodePath2[pAI->WayPos].Pos - pNodePath2[pAI->WayPos+1].Pos;
vDietro3 = vDietro2;

D3DXVec3Normalize( &vDietro1, &vDietro2 );
angolo = sin(scalar(vDietro1, vDietro2));
calcol=D3DXVec3Length(&vDietro3);
Altezza=angolo*calcol;//Questo algoritmo (anche perchè l'angolo è già in radianti) è uguale alla figura ma con le verifiche che ho fatto non và bene

potete verificare anche voi.

The3DProgrammer
05-10-2005, 20:36
mi sembra corretto, con una eccezione:


angolo = acos(scalar(vDietro1, vDietro2))

poi puoi usare D3DXVec3Dot per il calcolo del prodotto scalare

ciauz

The3DProgrammer
05-10-2005, 20:40
per curiosità, che stai a fa?
:D

ciauz

okay
06-10-2005, 03:31
per curiosità, che stai a fa?
:D

ciauz

AI per un un gioco

con tutto sto code avevo questa svista:
//Errore: normalizzavo vDietro1 su vDietro2
D3DXVec3Normalize( &vDietro1, &vDietro2 );
//Corrretto bisogna normalizzare i vettori
D3DXVec3Normalize( &vDietro1, &vDietro1 );
D3DXVec3Normalize( &vDietro2, &vDietro2 );


angolo = acos(scalar(vDietro1, vDietro2))
acos e asin ora mi ritorna un numero corretto

.... vado con le verifiche

ciao

okay
06-10-2005, 05:21
No purtroppo i conti nin tornano:

vDietro1 = pAI->Pos - pNodePath2[pAI->WayPos+1].Pos;
vDietro2 = pNodePath2[pAI->WayPos].Pos - pNodePath2[pAI->WayPos+1].Pos;
vDietro3 = vDietro2;//mantengo la distanza originale di vDietro2 su vDietro3
D3DXVec3Normalize( &vDietro1, &vDietro1 );
D3DXVec3Normalize( &vDietro2, &vDietro2 );
angolo = asin(scalar(vDietro1, vDietro2));//oppure acos
calcol=D3DXVec3Length(&vDietro3);
Altezza=angolo*calcol;

The3DProgrammer
06-10-2005, 08:47
Ma certo! :doh:

nn funzia xkè devi fare così

angolo = acos(D3DXVec3Dot(vDietro1, vDietro2));//calcolo l'angolo - usa D3DXVec3Dot invece di scalar ;)
calcol=D3DXVec3Length(&vDietro3);
Altezza=sin(angolo)*calcol;

in quanto, come dicevi prima, cateto=sin(angoloOpposto)*ipotenusa. Acos ritorna l'angolo in radianti (se nn ricordo male) quindi devi fare calcol*sin(angolo)

certe volte sono proprio un testicolo :fagiano:

okay
06-10-2005, 10:08
Ma certo! :doh:

nn funzia xkè devi fare così

angolo = acos(D3DXVec3Dot(vDietro1, vDietro2));//calcolo l'angolo - usa D3DXVec3Dot invece di scalar ;)
calcol=D3DXVec3Length(&vDietro3);
Altezza=sin(angolo)*calcol;

in quanto, come dicevi prima, cateto=sin(angoloOpposto)*ipotenusa. Acos ritorna l'angolo in radianti (se nn ricordo male) quindi devi fare calcol*sin(angolo)

certe volte sono proprio un testicolo :fagiano:


no no non và altezza decresce fino ad arrivare a 0 e così via.
Invece Altezza dovrebbe essere sempre 3.3465248 circa come nel calcolo giusto dell'altezza del triangolo. In questo caso con algoritmo trigonometrico sembra che calcoli il piano quindi da se provo con cos decresce con sin aumenta ho la vaga impressione che sbaglio il passaggio dei cateti/vettori

a cammina---->
>>>>>....a....>>>>>>
.........../.|.\
......../....|h....\
...../.......|............\
n0-------------------n1

a cammina----->
>>>>>........a...>>>>>>
.............../.|...\
........../......|h....\
...../...........|.........\
n0-------------------n1

vedi sopra: a cammina e altezza calcolata con sin deve essere sempre uguale


il punto a è la posizione e và verso il nodo1 io devo conoscere h

se guardi sopra il code è:
a-n1
n0-n1//se n1-n0 è uguale ho numeri + senza forzare con un fabs


quel decrescere o aumentare mi sembra come se devo cambiare cateto per il calcolo......... mi sto impippando il cervello!

okay
06-10-2005, 12:05
che coglione è naturale che l'angolo cambia, adesso che noto quelle specie di figure che ho fatto, l'angolo cambia ed è giusto. è l'altezza che calcolo male manca un solo passaggio o calcolo.

In definitiva l'angolo cambia sempre quello che varia è la lunghezza di a-n0 e a-n1 (i vettori) mentre n0-n1 è sempre uguale.

ci devo ragionare un attimo sopra. (la figura bella sopra è di un tut per trigonometria (avessero sbagliato loro i calcoli!!))

se arrivate prima voi postate!!