Przekształcenia trygonometryczne 3D

0

Witam,

Musze zrobić program który będzie reprezentował sześcian który będzie się obracał wokół poruszającego się. Najpierw mnożę macierz sześcianu przez macierz translacji tak aby sześcian znalazł się koło stożka. Później mnożę tak uzyskaną macierz przez macierz obrotu wokół środka stożka. czyli moje przekształcenia wyglądają tak:
W = WT1T2R(-T2)
Gdzie:
W - macierz wynikowa
T1 - macierz translacji tak aby sześcian się znalazł koło stożka
T2- macierz translacji w wokół punktu x0, y0, z0 który jest środkiem stożka
R - macierz obrotu wokół osi z

I sześcian zamiast obracać się w wokół stożka obraca się w miejscu. Czy ktoś ma jakiś pomysł dlaczego tak jest?

0

Z takimi ogólnikami ciężko powiedzieć coś konkretnego.
Zresztą po co po prawej stronie masz W?

0

Sory, pomyłka. Powinno być tam W = ST1T2R(-T2)
gdzie S - macierz stożka.

Nie wiem jak to inaczej zapisać bardziej zrozumiale. Najprawdopodobniej robię złe przekształcenia albo w złej kolejności. Siedzę nad tym dość już długo i nie wiem gdzie leży problem. Poniżej zamieszczam jeszcze kod:

void AfineTransformations::updateBox(osg::Matrix & transformation, double previousTime, double currentTime)
{
	//! TODO
	//! Aktualizacja macierzy transformacji sześcianu

	
	osg::Vec3f wektor;
        
	wektor = coneTransform->getMatrix().getTrans() - transformation.getTrans();  // obliczenie wektoru oddalenia szescianu od stozka
	wektor += osg::Vec3f(0.0, 1.0, 0.0);  // przesuniecie o 1 w kierunku y poniewaz gdy sie tego nie zrobi to szescian by sie znajdowal w srodku stozka
	
	transformation *= osg::Matrix::translate(wektor);            // ustawienie sześcianu z boku stożka
        
        // obrót wokół stożka
	transformation *= osg::Matrix::translate(-1.0, -1.0, 0.0);
	transformation *= osg::Matrix::rotate(0.04, 0.0, 0.0, 1.0);
	transformation *= osg::Matrix::translate(1.0, 1.0, 0.0);
} 

I tak jak pisałem sześcian zamiast się obracać wokół stożka to się obraca w miejscu

0

Może ktoś pomóc? Czy dalej jest niezrozumiale?

0

Popatrz co zrobiłeś:

void AfineTransformations::updateBox(osg::Matrix & transformation, double previousTime, double currentTime)
{
        osg::Vec3f wektor;

       // tu liczysz przesunięcie od stożka, ok! Ale ta wartość będzie ci się zmieniać przy każdym obrocie
        wektor = coneTransform->getMatrix().getTrans() - transformation.getTrans();

        // tu do zmieniającego się wektora (w zamierzeniu rotującego) dodajesz stałą wartość, raczej nie to chciałeś uzyskać
        wektor += osg::Vec3f(0.0, 1.0, 0.0);
 
        // tu AKTUALIZUJESZ macierz a nie ustalasz jej nową wartość, poprzednią iteracja ma wpływ na bierzacą iterację!
        transformation *= osg::Matrix::translate(wektor);
        transformation *= osg::Matrix::translate(-1.0, -1.0, 0.0);
        transformation *= osg::Matrix::rotate(0.04, 0.0, 0.0, 1.0);
        transformation *= osg::Matrix::translate(1.0, 1.0, 0.0);
} 

Czyli pomieszałeś małe aktualizowanie macierzy z jej liczeniem od początku.

Bezpieczniej jak zrobisz tak (obliczenie całkowitego obrotu na podstawie czasu):

void AfineTransformations::updateBox(osg::Matrix & transformation, double previousTime, double currentTime)
{
        const float BoxDistance= 1.0;
        const float RotationSpeed = 0.01;

        // wartość początkowa ustal odległość od stożka dla czasu 0 (obecnie odległość od początku układu wspł)
        transformation = osg::Matrix::translate(BoxDistance, 0, 0); 

        // całkowity obrót obliczony na podstawie czasu
        transformation *= osg::Matrix::rotate(RotationSpeed * currentTime, 0.0, 0.0, 1.0);
 
        // przesuń do pozycji stożka
        transformation *= coneTransform->getMatrix().getTrans();
} 
0

Dzięki wielkie, teraz działa. Widać że moja wiedza algebraiczna jest nie za ciekawa;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1