Krumme Linien



  • Hi zusammen,
    kann mir jmd. sagen wie man in VC++ mittels 3 Punkten krumme Linien zeichnen kann?
    Also nicht starre Linien, sondern "gebogene"...
    Man, man, ich hoff, hier checkt jmd. was ich mein...
    Oder vielleicht ein Stichwort, womit ich weitersuchen kann?
    Wäre echt klasse, vielen Dank! Tobias



  • Was verstehst du unter 'krumme' ?
    Man kann in 3 Punkte
    1. einen Kreisbogen,
    2. eine Ellipse
    oder sogar
    3. eine Parabel
    einpassen!



  • Hi!

    Du meinst doch mit Sicherheit Splines. Hier sind mal ein paar Links, wo Du Dich in Ruhe umsehen kannst. Ist hoffentlich was brauchbares dabei.
    http://home.t-online.de/home/08153952614-0001/Index.html http://www.apm.tuwien.ac.at/docs/lva/mmgdv/eins.htm http://www.gris.uni-tuebingen.de/gris/grdev/java/doc/html/german/ http://www.uni-paderborn.de/fachbereich/AG/agdomik/extern/computergrafik/cg_skript/html/main.htm

    MfG
    Andreas

    [ Dieser Beitrag wurde am 04.04.2003 um 08:24 Uhr von andreasvolgmann editiert. ]



  • Sind Splines nicht kubisch und verlangen mind. 4 Stützstellen ?



  • Also mit den Bezier Splines kann man auch mit zwei Punkten eine "Krumme" Linie zeichnen. Da kann man an einen der beiden Punkte eine Tangente eintragen und schon hat man eine Krumme Linie. Man kann es natürlich auch auf eine andere Art und weise machen (z.B. Kreisbogen), aber mit den Splines hat man die beste Kontrolle über das Ergebnis. Und man kann auch mehr als zwei Punkte benutzen (3, 4, 5, ...) 🙂
    Ich habe mir bisher noch keine solche Funktion programmiert, aber ich hatte die Links halt noch aufbewahrt, weil ich sie sehr interessant fand.

    Mfg Andreas



  • Dann erklär mal dem PC, wie er mit 2 Stützstellen ne Tangente an einen Punkt legen soll!



  • Weiß nicht, ob es hilft... Ich hab sowas mal in Standard C++ versucht. Ist nicht perfekt... Wenn jemand Verbesserungen hat bitte hier posten...

    #include <vector>
    using namespace std;
    
    struct sPoint {
        sPoint(void) {}
        sPoint(long x_, long y_)
            : x(x_), y(y_) {}
        long x;
        long y;
    };
    
    class CSplines
    {
    public:
        CSplines(void){};
        ~CSplines(void){};
        void CalcSplines(vector<sPoint>& points, unsigned int steps);
        vector<sPoint>* GetResult();
    protected:
        vector<sPoint> m_result;
    };
    
    // CalcSplines: Interpoliert Zwischenschritte in einem Array aus Punkten
    void CSplines::CalcSplines(vector<sPoint>& points, unsigned int steps) {
        m_result.clear(); // Speicher leeren
        vector<sPoint>::iterator it = points.begin() + 1;
        sPoint A, B, C, D, poiPush;
        long a3, b3, a2, b2, a1, b1, a0, b0;
        unsigned int j;
        float t;
        for(; it < points.end() - 2; ++it) {
            // Berechnung der Koeffizienten
            A = *(it - 1); B = *(it); C = *(it + 1); D = *(it + 2);
            a3 = (-A.x + 3 * (B.x - C.x) + D.x) / 6;
            b3 = (-A.y + 3 * (B.y - C.y) + D.y) / 6;
            a2 = (A.x - 2 * B.x + C.x) / 2;
            b2 = (A.y - 2 * B.y + C.y) / 2;
            a1 = (C.x - A.x) / 2;
            b1 = (C.y - A.y) / 2;
            a0 = (A.x + 4 * B.x + C.x) / 6;
            b0 = (A.y + 4 * B.y + C.y) / 6;
            // Zwischenschritte berechnen
            for(j = 0; j < steps; ++j) {
                t = float(j) / steps;
                poiPush.x = ((a3 * t + a2) * t + a1) * t + a0;
                poiPush.y = ((b3 * t + b2) * t + b1) * t + b0;
                m_result.push_back(poiPush);
            }
        }
    }
    
    // GetResult: Holt das Ergebnis der Interpolation
    vector<sPoint>* CSplines::GetResult() {
        return &m_result;
    }
    


  • Original erstellt von RenéG:
    Dann erklär mal dem PC, wie er mit 2 Stützstellen ne Tangente an einen Punkt legen soll!

    Richtig, man brauch mindestens 3 Punkte. Hat man diese 3 Punkte A,B,C (Ortsvektoren / Kontrollpunkte) beschreiben die eine Bezier Kurve. Und zwar durch (ich hoffe ich vertu mich jetzt nicht) X(t) = At0(1-t)2 + Bt1(1-t)1 + Ct2(1-t)0. t aus [0,1]. Das wäre dann eine Kurve vom Grad 2.

    Je höher der Grad, desto aufwendiger die Berechung (insbesondere die Potenzen), aber desto komplizierter auch die Kurven.

    Das Besondere an Bezier Du erhälts bereits mit den Kontrollpunkten eine gute Annäherung an die Kurve. Das Gleiche gilt für den 3Dimensionalen Fall für die Bezier-Flächen.
    Möchte man nun eine Bezier-Fläche/Kurve im Raum Drehen o.a. dann genügt es die Kontrollpunkte zu Transformieren (geht also schnell).

    Dann gibt es noch einen Speziellen Algorithmus (ich denke De'Casteljau - zumindest klinkt das so wies da steht) mit dem man die Anzahl der Kontrollpunkte erhöht, OHNE den Grad der Kurve zu erhöhen. D.h. die Aproximation wird feiner.

    Vielleicht Helfen dir die Infos ein bischen weiter.

    Gruss mathi



  • hi, auf jeden Fall vielen Dank...
    Ich guck mir mal die Links und die Bezier-Linien an!
    Gruss, Tobias



  • Wie wär's mit NURBS? Da hat man die volle Kontrolle über die Kurve, es lassen sich alle erdenklichen Kurventypen zeichnen...


Anmelden zum Antworten