Linie zeichnen mit C++



  • @muemmel

    Hallo Mümmel. Weisst du, das Problem ist bei diesem Bresenham-Algorithmus, ist der Befehl SetPixel. Um den geht es mir ja die ganze Zeit. Aber diese Lumpen haben den Befehl in fast keiner Programmiersprache mehr implementiert. Es ist zum Kotzen.
    Aber ich glaube mit SFML komme ich weiter.
    Oder hast du noch eine Idee, wie es einfacher geht?



  • @spatz sagte in Linie zeichnen mit C++:

    Aber diese Lumpen haben den Befehl in fast keiner Programmiersprache mehr implementiert.

    So ein Befehl gehörte nie (selten) zu irgendeiner Programmiersprache.
    Wenn, war er eine Erweiterung (z.B. BASIC) oder in einer mitgelieferten Bibliothek (z.B. Pascal, C zu DOS-Zeiten)

    Mittlerweile hat sich aber die Computergrafik gewandelt. Man zeichnet nicht mehr auf einem Bildschirm der einem alleine gehört sondern in einem skalierbaren Fenster (von vielen).

    Zudem kommen noch die GUI-Features dazu.
    Darum gibt es jetzt externe oder systemeigene Bibliotheken.
    Aber da muss man sich einarbeiten.


  • Mod

    Bevor du jetzt anfängst, nach Bresenham einzelne Pixel zu setzen, solltest du dich fragen, was denn letztlich dein Ziel ist. Computergrafik heute macht man schlichtweg nicht mehr als Ansammlung einzelner Pixel. Irgendwo ganz am Ende wird zwar natürlich irgendein Algorithmus entscheiden, welcher Pixel auf welche Farbe gesetzt wird, aber die grundlegenden Konzepte, wie man heutzutage über die Grafikdarstellung denkt, sind ganz anders. Daher nützt es dir überhaupt gar nichts, mit einzelnen Pixeln anzufangen, wenn du später dann doch moderne Computergrafik machen möchtest.



  • @spatz sagte in Linie zeichnen mit C++:

    der Befehl SetPixel. Um den geht es mir ja die ganze Zeit. Aber diese Lumpen haben den Befehl in fast keiner Programmiersprache mehr implementiert. Es ist zum Kotzen.

    Ja, furchtbar, alles Verbrecher!!

    Oder hast du noch eine Idee, wie es einfacher geht?

    Ich empfehle dir DOSBox + GW-BASIC.



  • #include <Windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	static TCHAR szAppName[] = TEXT("Aufgäbe 1");
    	HWND hwnd;
    	MSG msg;
    	WNDCLASS wndclass;
    
    	wndclass.style = CS_HREDRAW | CS_VREDRAW;
    	wndclass.lpfnWndProc = WndProc;
    	wndclass.cbClsExtra = 0;
    	wndclass.cbWndExtra = 0;
    	wndclass.hInstance = hInstance;
    	wndclass.hIcon = LoadIcon(0, IDI_APPLICATION);
    	wndclass.hCursor = LoadCursor(0, IDC_HAND);
    	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndclass.lpszMenuName = 0;
    	wndclass.lpszClassName = szAppName;
    	
    
    	if (!RegisterClass(&wndclass))
    	{
    		MessageBox(0, TEXT("Fehler!"), szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	hwnd = CreateWindow(szAppName, TEXT("Aufgabe 1"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0);
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd);
    
    	while (GetMessage(&msg, 0, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	HDC hdc;
    	PAINTSTRUCT ps;
    	RECT rect;	
    
    	switch (message) 
    	{
    	case WM_CREATE:
    		return 0;
    	case WM_PAINT:
    		hdc = BeginPaint(hwnd, &ps);
    
    		GetClientRect(hwnd, &rect);
    
                    MoveToEx(hdc, 10, 10, NULL);
                    LineTo(hdc, 20, 20);
    
    		EndPaint(hwnd, &ps);
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hwnd, message, wParam, lParam);
    }
    


  • @SeppJ

    Hallo Sepp. Mein Ziel ist es, mathematische Funktionen zu zeichnen. Etwa eine Parabel (Quadratfunktion). Dazu muss ich einzelne Pixel setzten können. Es ist mir dies übrigens jetzt mit SFML gelungen auf Linux.
    Juhui!



  • achja wenn du pixel setzen willst, musst du SetPixel(hdc, xcoord, ycoord, RGB(rval, gval, bval)) verwenden. geht doch alles ganz einfach.🙄



  • @Wade1234

    Muss man da noch eine spezielle Bibliothek einbinden? Also für SetPixel?



  • also es funktioniert halt nur unter windows, aber im prinzip kannst du ab zeile 58 ganz normal SetPixel aufrufen. in einem "richtigen" programm würde man das natürlich alles in unterfunktionen auslagern usw., aber wenn du "nur mal ein bisschen malen" möchtest, geht das so. das programm müsstest du einfach so mit copy & paste übernehmen können.



  • @Wade1234

    Also dieser Code funktioniert bei mir in Visual Studio nicht.
    Vielleicht habe ich auch mein VS abgeschossen.



  • @spatz "funktioniert nicht" ist immer sehr ungenau. also ich habs eben getestet mit "Neues Projekt" -> "Windows-Desktopanwendung" (achtung: nicht -Assistent!) -> "Weiter, weiter, weiter" -> vorhandenen quelltext löschen -> meinen code einfügen. wenn du ein leeres projekt erstellst, musst du in den linker-einstellungen das subsystem auf "Windows" ändern.



  • @Wade1234

    Jetzt hat es funktioniert. Da kommt dann ein kleines Strichli, richtig?
    Ich ging drum auf Konsole-Anwendung zuerst.
    Vielen Dank



  • @spatz ja da kommt ein strich von (10, 10) nach (20, 20). die dimensionen bzw. eckpunkte des fensters sind in rect (zeile 48) gespeichert und für linien musst du eben zuerst MoveToEx und dann LineTo aufrufen.



  • Es gibt auch sf::LineStrip. Dann musst Du nur entscheiden, welchen Bereich und mit welcher Abtastrate Du darstellen willst (sprich, Du brauchst (X,Y) Vektoren) und dann werden die Punkte automatisch linear interpoliert).

    Jetzt könnte man natürlich wieder fragen, wozu Du denn Funktionen plotten willst. Dafür gibt es wieder fertige Bibliotheken, oder es geht in anderen Programmiersprachen leichter und schneller. Deshalb solltest Du Deine Fragen eher so stellen z. B. :

    Ich möchte gerne zu Lernzwecken selbst Kurven plotten in C++, wie gehe ich am besten vor?

    Das führt i. d. R. schneller zum Ziel 😉

    Von der WinAPI würde ich hier persönlich abraten:

    • C-Style Interface, mischt sich nicht gut und schön mit C++, kennt kein RAII etc.

    • Windows Only (prinzipiell).

    • Viel Boilerplate Code notwendig, allgemein mehr Aufwand/low-level.

    P.S.:
    Qt oder Qwt können auch plotten, und wenn Du GUI Elemente willst, bist Du auch schon bedient. Es gibt auch GNUPlot, damit habe ich selbst aber noch nie in C++ gearbeitet. Python+Matplotlib ist aber sicherlich einfacher.



  • @HarteWare

    Auf alle Fälle, vielen Dank für eure Hilfe.
    Habe wieder ne Menge dazugelernt.


Anmelden zum Antworten