Rechtecke drehen



  • verstehe ich nicht... :p du weisst, dass dein rechteck sagen wir ma einen seitenverhältnis von 3zu4 hat.
    Dein steigungsvektor (1.0 | steigung) , und somit auch dein normalenvektor (-steigung | 1.0) haben die länge sqrtf(steigung*steigung+1.0f). Ohne zu normieren kannst du daraus natürlich ein recheckt basteln, das dieselben seitenverhältnisse hat, indem du den einen vektor mit 4 und den anderen mit 3 multiplizierst. aber die seiten werden doch je nach steigung unterschiedlich lang sein, und das ist nich erwünscht.



  • ich bezog mich drauf, dass eine seite des rechteckes bekannt ist (also 2 endpunkte gegeben sind -> variante mit den rädern)...

    aber wie gesagt, ohne nähere info wie es denn jetzt eigentlich aussehen soll, kann man da nicht viel dazu sagen...



  • Erst mal Danke für eure hilfe, vorallem an Andrey. (ich verstehe dich^^) Nur noch ein Problem Rechtecke bach ihren Eckpunkte zeichnen hatten wir no net, kann mir da llt au no jemand helfen (sollte ja net zu schwer seinb).
    Mfg Christi



  • mit den befehlen, mit den du grad arbeitest, kannst du auch kein gedrehtes gefülltes rechteck zeichnen, ich hab eigentlich vorgeschlagen, einfach die vier eckpunkte einzeln zu transformieren und diese danach mit einfachen strichen (linien) zu verbinden, also von A nach B von B nach C von C nach D usw... (dann hast du nur den rechteckrand)

    {
    obwohl, wenn du schon die transformationsmatrix hast, kannste grad n ganzen pixelarray (ganzes bild von einem auto) nehmen, und punkt für punkt transformieren und hinzeichnen. Solange das gezeichnete auto kleiner oder genausogros ist, wie das ausgangsbild, brauchst du keinen rasterizer, es werden auch so (so gut wie?) keine löcher im gedrehten bild entstehen [nicht besonders elegant, wird wahrscheinlich hässlich und pixelig aussehen, aber wenn du's schön machen willst, kannst du entweder OpenGL lernen oder dir nen eigenen mini-rasterizer schreiben, der ein rechteck texturieren kann (ist echt voll overkill für die aufgabe=> machs pixel für pixel) ]
    };



  • Hallo Christi,

    in so einem Fall, wie Du ihn hier schilderst, kann man zur Transformation auch komplexe Zahlen hernehmen. Komplexe Zahlen können auch als 2-dimensional Vektoren interpretiert werden und genau wie Vektoren addiert und subtrahiert werden. Auch wenn Du das noch nicht in der Schule gehabt hast, ist es recht einfach in C++ zu programmieren, da eine Klasse für komplexe Zahlen bereits vorhanden ist.

    Mal angenommen, dass Rechteck (Auto) hat die Länge 20 und die Höhe 10.

    const double laenge = 20;
        const double hoehe = 10;
    

    Und das Rechteck soll mit seiner unteren Seite mittig auf dem Boden (bzw. auf der Funktion aufliegen), dann sind die vier Ecken - bezogen auf das Auto

    vector< complex< double > > auto_ecken;
        auto_ecken.push_back( complex< double >( laenge/2, 0.0 ) );
        auto_ecken.push_back( complex< double >( laenge/2, hoehe ) );
        auto_ecken.push_back( complex< double >( -laenge/2, hoehe ) );
        auto_ecken.push_back( complex< double >( -laenge/2, 0.0 ) );
    

    Man benötigt dazu noch die includes

    #include <vector>
    #include <complex>
    

    Aus den complexen Zahlen kann man sich eine einfache Transformation basteln

    class Lage
    {
    public:
        explicit Lage( const std::complex< double >& rot = std::complex< double >( 1.0, 0.0 ), 
                const std::complex< double >& trans = std::complex< double >() )
            : m_rot( rot ), m_pos( trans )
        {}
    
        std::complex< double > operator*( const std::complex< double >& v ) const
        {
            return  m_rot * v + m_pos;
        }
    
    private:
        std::complex< double > m_rot, m_pos;
    };
    

    das nenne ich hier mal Lage, da das die Lage des Autos in der Welt ('w') ist. Die komplexen Zahlen werden einmal als Position (m_pos) und als Rotation bzw. Richtung (m_rot) interpretiert. Dann braucht man noch eine Funktion, die aus einer beliebigen komplexen Zahl eine Zahl mit gleicher Richtung und der Länge 1 macht.

    std::complex< double > unit( const std::complex< double >& c )
    {
        return c / std::abs( c );
    }
    

    .. und natürlich eine Funktion f(x) und deren Ableitung fs(x) für die Kurve, auf der das Auto fahren soll. Anschließend kann man die vier Ecken im Weltsystem 'w' berechen.

    double x = 40;
        Lage w_L_auto( unit( complex< double >( 1.0, fs(x) ) ), complex< double >( x, f(x) ) ); // Lage des Autos in der Welt
        vector< complex< double > > w_ecken( auto_ecken.size() );
        for( int i=0; i < auto_ecken.size(); ++i )
            w_ecken[i] = w_L_auto * auto_ecken[i]; // transformiert die Punkte vom Auto- in das Welt-System
    

    Die Ecken im vector 'w_ecken' sind das Rechteck im Welt-System, also in den Koordinaten, die man zum Zeichnen benötigt.

    Ich habe noch vergessen zu erwähnen, dass man die X- und Y-Werte aus dem Real- und Imaginär-Teil der komplexen Zahl erhält; also z.B.:

    cout << "X= " << w_ecken[0].real() <<"  Y= " << w_ecken[0].imag() << endl;
    

    Gruß
    Werner



  • ob man's jetzt mit der rotationsmatrix oder den komplexen zahlen macht: hinter beiden rechnungen stecken dieselben trigonometrischen additionssätze, aber das stimmt: multiplikation der komplexen zahlen ist um einiges leichter zu merken, als der krumme geometrische beweis der additionssätze 👍
    andererseits ist dieser ansatz nicht so wirklich universell einsetzbar, wenn da noch veschiebungen dazukommen, kann mans nicht mehr in komplexen zahlen ausdrücken (mit einer 3x3 matrix geht dagegen _alles_ in nur einem schritt)



  • Andrey schrieb:

    andererseits ist dieser ansatz nicht so wirklich universell einsetzbar, wenn da noch veschiebungen dazukommen, kann mans nicht mehr in komplexen zahlen ausdrücken (mit einer 3x3 matrix geht dagegen _alles_ in nur einem schritt)

    Irrtum; die Klasse Lage ist eine Lage - enthält somit Rotation UND Verschiebung. Und das geht deshalb, weil sie auch zwei komplexe Zahlen als Member enthält. Damit ist Lage für eine affine Abbildung (ohne Scherung und nur mit einer Skalierung) im 2-dimensionalen völlig ausreichend.
    Und das ist genau das, was der OT benötigt.

    Gruß
    Werner



  • Und was wenn man irgendwann mal noch rotierende räder zu dem auto dazumachen will, und dann noch einen insassen, der mit der hand winkt? Bei komplexen zahlen braucht man dann für jedes einzelne bildelement einen array aus mehreren rotationen und verschiebungen. Bei dem ansatz mit den matrizen bleibts immer bei einer einzigen matrix. egal wie komplex die transformation ist, und aus wievielen rotationen skalierungen und verschiebungen sie besteht... 💡

    edit: wer oder was ist "der OT"? chegg ich ned :p

    *edit2: obwohl... andererseits... man kann eigentlich auch die ganzen transformationen mit komplexen zahlen verschachteln und dann "ausmultiplizieren", dann bleibts in der tatt auch immer bei zwei komplexen zahlen... na gut, der ansatz ist okay, gibs ja zu 😃 👍



  • Andrey schrieb:

    edit: wer oder was ist "der OT"? chegg ich ned :p

    .. das ist ein Schreibfehler. Gemeint ist der OP (original poster) also Christi.



  • Hallo,

    Da er den C++Builder nimmt, könnte er auch einfach eine fertige Komponente verwenden, die Rotationen erlaubt. Hier gibt es z.Bsp. sowas
    http://www.torry.net/pages.php?id=155



  • Werner Salomon schrieb:

    Gemeint ist der OP (original poster)

    achso, mkay, "OP" hätt ich wahrscheinlich auch nicht entziffert 😃


Anmelden zum Antworten