zna ktoś algorytm rysowania trójkąta 2D w całości rysowany jednym kolorem w c++ ? , mam dostępne punkty i odcinki do rysowania , na google są ale z reguły wzrory a to mi nic nie daje , nie jestem matematykiem aby takie wzory rozpisać sobie na kod

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
- Rejestracja:prawie 19 lat
- Ostatnio:około 2 godziny
Chodzi o narysowanie pełnego trójkąta piksel po pikselu na ekranie lub bitmapie?
Jakiś czas temu zastosowałem taki algorytm, bo sam potrzebowałem:
https://github.com/andrzejlisek/ScriptSDCCWeb/blob/main/ProjWeb/prog/guigraphinstance_draw.cpp - funkcja IOGraphWin::DrawTriangle
(jeden kolor) i IOGraphWin::DrawTriangle0
(gradient na podstawie kolorów w wierzchołkach)
W mojej funkcji argumenty mają następujące znaczenie:
X1, Y1, X2, Y2, X3, Y3 - współrzędne wierzchołków na ekranie - potrzebne do faktycznego narysowania
Z1, Z2, Z3 - punkt głębi, które służą do obliczania wierzchołków w buforze głębi - to można pominąć w przypadku rysowania 2D
R0, G0, B0 - kolor trójkąta w przypadku trójkąta jednokolorowego
R1, G1, B1, R2, G2, B2, R3, G3, B3 - kolory wierzchołków w RGB do narysowania gradientu
LightAngle - Kąt światła potrzebny do obliczania wynikowego koloru rysowania w 3D - niepotrzebne przy rysowaniu w 2D, mój program ma prostą symulację 3D
Zasadnicza funkcja, która jest wywoływana i odpowiada za faktyczne rysowanie trójkąta to tak naprawdę DrawHalfTriangle
i DrawHalfTriangle0
, te dwie funkcje tan naprawdę malują połowę trójkąta, czyli tak naprawdę cały trójkąt, w którym jeden bok jest linią poziomą.
Pozostanie usunąć argumenty Z1, Z2, Z3, LightAngle i usunąć obliczenia z ich udziałem, potem przerobić samo malowanie, bo ten program rysuje do bufora będącego tablicą bajtową.

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
przepraszam ale za duzo tego nie moge sie połąpać jesli chodzi o twój projekt z kodem.... mozesz napiać samą wersje rysowania na jednym kolorze bez światła bez gradientu i bez bufforawania głębi , prosił bym , po kazdym oblicznie u mnie jest putpixel(X,Y) i tyle starczy dla tego trójkąta co napisałeś bez warotści osi Z tzn głębi
- Rejestracja:prawie 19 lat
- Ostatnio:około 2 godziny
Usunąłem wszystko, co niepotrzebne i teraz można łatwo testować. Ustawianie ImgRaw
możesz zmienić na to swoje putpixel
bez problemu, teraz kod można bez trudu testować:
W pliku *.h powinny być takie zmienne:
typedef unsigned char uchar;
std::vector<uchar> ImgRaw;
int ImgW = 640;
int ImgH = 480;
W pliku *.cpp powinny być takie funkcje:
// Rysowanie połowy trójkąta
void MainWindow::DrawHalfTriangle(int X0, int Y0, int X1, int X2, int Y_, uchar R0, uchar G0, uchar B0)
{
int DrawX0 = X0;
int DrawY0 = Y0;
int DrawX1 = X1;
int DrawX2 = X2;
int DrawY_ = Y_;
int X, Y, YI1, YI2, XI1, XI2;
double DX1, DX2, DZ1, DZ2, DY, DYX, A1, A2, A1Z, A2Z;
if (DrawX1 > DrawX2)
{
X = DrawX1;
DrawX1 = DrawX2;
DrawX2 = X;
}
DX1 = DrawX1 - DrawX0;
DX2 = DrawX2 - DrawX0;
DY = DrawY0 - DrawY_;
A1 = DX1 / DY;
A2 = DX2 / DY;
A1Z = DZ1 / DY;
A2Z = DZ2 / DY;
if (DrawY_ < DrawY0)
{
YI1 = DrawY_;
YI2 = DrawY0;
}
else
{
YI1 = DrawY0;
YI2 = DrawY_;
}
for (Y = YI1; Y <= YI2; Y++)
{
DYX = (DrawY_ - Y);
XI1 = round(DYX * A1) + DrawX1;
XI2 = round(DYX * A2) + DrawX2;
for (X = XI1; X <= XI2; X++)
{
int Pos = (Y * ImgW) + X;
int Pos4X = Pos << 2;
ImgRaw[Pos4X + 0] = R0;
ImgRaw[Pos4X + 1] = G0;
ImgRaw[Pos4X + 2] = B0;
}
}
}
// Rysowanie trójkąta z wykorzystaniem funkcji rysujących połowę
void MainWindow::DrawTriangle(int X1, int Y1, int X2, int Y2, int X3, int Y3, uchar R0, uchar G0, uchar B0)
{
int XMin;
int XMax;
int YMin;
int YMax;
double F1, F2, F3, F4;
int P0X_;
int P0X__;
int P0Y_;
int P1X_;
int P1Y_;
int P2X_;
int P2Y_;
XMin = X1;
XMax = X1;
if (XMin > X2) { XMin = X2; }
if (XMax < X2) { XMax = X2; }
if (XMin > X3) { XMin = X3; }
if (XMax < X3) { XMax = X3; }
YMin = Y1;
YMax = Y1;
if (YMin > Y2) { YMin = Y2; }
if (YMax < Y2) { YMax = Y2; }
if (YMin > Y3) { YMin = Y3; }
if (YMax < Y3) { YMax = Y3; }
P0Y_ = YMin;
if ((Y1 > YMin) && (Y1 < YMax))
{
P0X_ = X1; P0Y_ = Y1;
if (Y2 == YMin)
{
P1X_ = X2; P1Y_ = Y2;
P2X_ = X3; P2Y_ = Y3;
}
else
{
P1X_ = X3; P1Y_ = Y3;
P2X_ = X2; P2Y_ = Y2;
}
}
else
{
if ((Y2 > YMin) && (Y2 < YMax))
{
P0X_ = X2; P0Y_ = Y2;
if (Y3 == YMin)
{
P1X_ = X3; P1Y_ = Y3;
P2X_ = X1; P2Y_ = Y1;
}
else
{
P1X_ = X1; P1Y_ = Y1;
P2X_ = X3; P2Y_ = Y3;
}
}
else
{
if ((Y3 > YMin) && (Y3 < YMax))
{
P0X_ = X3; P0Y_ = Y3;
if (Y1 == YMin)
{
P1X_ = X1; P1Y_ = Y1;
P2X_ = X2; P2Y_ = Y2;
}
else
{
P1X_ = X2; P1Y_ = Y2;
P2X_ = X1; P2Y_ = Y1;
}
}
}
}
if ((P0Y_ > YMin) && (P0Y_ < YMax))
{
F1 = P0Y_ - P1Y_;
F2 = P2Y_ - P1Y_;
F3 = P2X_ - P1X_;
F4 = F3 * (F1 / F2);
P0X__ = P1X_ + F4;
DrawHalfTriangle(P1X_, P1Y_, P0X_, P0X__, P0Y_, R0, G0, B0);
DrawHalfTriangle(P2X_, P2Y_, P0X_, P0X__, P0Y_, R0, G0, B0);
}
else
{
if (Y1 == Y2)
{
DrawHalfTriangle(X3, Y3, X1, X2, Y1, R0, G0, B0);
}
if (Y2 == Y3)
{
DrawHalfTriangle(X1, Y1, X2, X3, Y2, R0, G0, B0);
}
if (Y3 == Y1)
{
DrawHalfTriangle(X2, Y2, X3, X1, Y3, R0, G0, B0);
}
}
}
// Przykładowa funkcja w programie
void MainWindow::on_pushButton_clicked()
{
// Przygotowanie tablicy "unsigned char" symulującej bitmapę
ImgW = 40;
ImgH = 40;
ImgRaw.clear();
for (int i = 0; i < (ImgW * ImgH * 4); i++)
{
ImgRaw.push_back(0);
}
// Rysowanie przykładowych trójkątow
DrawTriangle(5, 5, 18, 7, 10, 30, 1, 1, 1);
DrawTriangle(20, 37, 17, 28, 38, 26, 2, 2, 2);
// Wypisanie tablicy symulującej bitmapę
int ptr = 0;
for (int y = 0; y < ImgH; y++)
{
for (int x = 0; x < ImgW; x++)
{
switch (ImgRaw[ptr])
{
case 0: std::cout << "."; break;
case 1: std::cout << "#"; break;
case 2: std::cout << "@"; break;
}
ptr += 4;
}
std::cout << std::endl;
}
}
W powyższym kodzie kolory są symulowane znakami i wypisywany jest co czwarty bajt. Zakładam, że przekształcenie tego na rysowanie na bitmapie za pomocą putpixel
nie będzie żadnym wyzwaniem. Zmieni się tylko techniczny sposób malowania, same obliczenia pozostaną te same.
Samo stawianie piksela to jest poniższy kod, użyty w DrawHalfTriangle
, gdzie X
i Y
to współrzędne piksela, a R0
, G0
, B0
to składowe koloru:
int Pos = (Y * ImgW) + X;
int Pos4X = Pos << 2;
ImgRaw[Pos4X + 0] = R0;
ImgRaw[Pos4X + 1] = G0;
ImgRaw[Pos4X + 2] = B0;

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
dobra dzięki teraz lepiej powinniem sobie poradzić

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
czy to jest C++ 17
void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
// Find the bounding box of the triangle
int minY = min({y1, y2, y3});
int maxY = max({y1, y2, y3});
// Loop through each scanline from minY to maxY
for (int y = minY; y <= maxY; ++y) {
// Find the intersections of the scanline with the triangle edges
int x_intersection1 = -1, x_intersection2 = -1;
// Check if the scanline intersects with the edge (x1, y1) to (x2, y2)
if ((y1 <= y && y2 > y) || (y2 <= y && y1 > y)) {
x_intersection1 = x1 + (y - y1) * (x2 - x1) / (y2 - y1);
}
// Check if the scanline intersects with the edge (x2, y2) to (x3, y3)
if ((y2 <= y && y3 > y) || (y3 <= y && y2 > y)) {
x_intersection2 = x2 + (y - y2) * (x3 - x2) / (y3 - y2);
}
// Check if the scanline intersects with the edge (x3, y3) to (x1, y1)
if ((y3 <= y && y1 > y) || (y1 <= y && y3 > y)) {
x_intersection1 = x3 + (y - y3) * (x1 - x3) / (y1 - y3);
}
// Ensure the intersection points are ordered from left to right
if (x_intersection1 > x_intersection2)
swap(x_intersection1, x_intersection2);
// Fill the pixels between the two intersections
for (int x = x_intersection1; x <= x_intersection2; ++x) {
putPixel(x, y);
}
}
}
jesli tak to potrafi ktos kto ma wiedze przerobic na C++ 98 , chociaż na C++20 gdzie nie potrzeba #include <algorithm> tylko czysta matma , bo u mnie na VC++6.0 tego nie ma tzn min , max ,swap

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
swap zaimienia warotsciami min pobiera najmniejszą a max największą ale jeszcze jedno chodzi o to:
int x_intersection1 = -1, x_intersection2 = -1;
tutaj jest przecinek czy to wymagane bo powinnien byc srednik
tuaj jest potrójna wartosc i mi nie działa min({y1, y2, y3});

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
zrobiłem sam swap, działa
void swap(int &a, int &b)
{
int c=a;
a=b;
b=c;
}
takie pytanie jak są trzy wartosci to dalej jak normalnie najwiekszą z max gdzy było by tylko dwie wartości i z min tak samo ?
mam tak niby działa sam napisałem
int Min(int a,int b,int c)
{
if(a<b && a<c)
return a;
if(b<a && b<c)
return b;
if(c<a && c<b)
return c;
}
int Max(int a,int b,int c)
{
if(a>b && a>c)
return a;
if(b>a && b>c)
return b;
if(c>a && c>b)
return c;
}
proszę o komentarz czy na pewno właściwie napisalem jak powinno działać , wg testów które robiłem działa dobrze

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
zapodałem swojego Min , Max i swap i działa mi funkcja fillTriangle
to wszystko ... temat do zamknięcia

- Rejestracja:około 17 lat
- Ostatnio:3 minuty
wilkwielki napisał(a):
czy to jest C++ 17
- Ile mam razy prosić, byś zaczął używać kolorowania składni dla kodu? tak trudno dopisać: ```cpp przed kodem i ``` po kodzie?
- To przeładowanie
std::max
(3) (4) jest z C++11, inne przeładowania są starsze od C++98 (1) (2), od wersji C++14 zmieniły się na wersjęconstexpr
:
template< class T >
const T& max( const T& a, const T& b );(1) (constexpr since C++14) template< class T, class Compare >
const T& max( const T& a, const T& b, Compare comp );(2) (constexpr since C++14) template< class T >
T max( std::initializer_list<T> ilist );(3) (since C++11)
(constexpr since C++14)template< class T, class Compare >
T max( std::initializer_list<T> ilist, Compare comp );(4) (since C++11)
(constexpr since C++14)
- Jak masz tylko C++98 nie prościej było zrobić kaskadę
std::max
?
std::max(std::max(a, b), c);

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
int a;
przepraszam juz sie nauczyłem trzeba klawiszem tyldy ja tego nie wiedziałem . przepraszam

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
int minY = Min(y1, Min(y2, y3));
int maxY = Max(y1, Max(y2, y3));
ta funkcja fillTriangle z tym algorytmem jest skopana, błędna , raz działa a raz pokazuje śmieci

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
spoko na OpenGl to ja sie znam tylko pisze i juz koncze silniczek od rysowania grafiki w konsoli odwolywane przez funkcje SetPixel(mydc, x, y, COLOR); grzeibie na google i są urywki kodów ale ciężko znaeść coś działającego albo same wzory matematyczne , ze tez kurcze szkoda ze prawie nigdzie nie ma kodu działajacej funkcji od rysowanie trójkąta wypełnionego

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
no tak funkcja SetPixel nie jest z opengl wiem o tym , są algorytmy rysujące trójkąty wypełnione ale trudno dostępne

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
tutaj jest ale trudne to jak cholera
DrawFilledTriangle (P0, P1, P2, color)
https://gabrielgambetta.com/computer-graphics-from-scratch/07-filled-triangles.html#drawing-filled-triangles
po polsku https://gabrielgambetta-com.translate.goog/computer-graphics-from-scratch/07-filled-triangles.html?_x_tr_sl=auto&_x_tr_tl=pl&_x_tr_hl=pl#drawing-filled-triangles

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
to prawda liczone przez CPU ja to wpisuje putpixel do tablicy a na koncu rendreruje tablice po pwszystkim

- Rejestracja:ponad 2 lata
- Ostatnio:około 5 godzin
- Postów:1595
wilkwielki napisał(a):
zna ktoś algorytm rysowania trójkąta 2D w całości rysowany jednym kolorem w c++ ? , mam dostępne punkty i odcinki do rysowania , na google są ale z reguły wzrory a to mi nic nie daje , nie jestem matematykiem aby takie wzory rozpisać sobie na kod
Ja ci dam prosty algorytm ale bez koloru;
- Wybierasz sobie punkt
- Przez punkt przeprowadzasz prostą
- Następnie wybierasz sobie losowo inny punkt
- Przez punkt z 1. i 3. przeprowadzasz kolejną prostą
- W pewnej odległości od punktu 1. rysujesz kolejną prostą
- Wychodząc z punktu podążasz zgodnie z kierunkiem ruchu wskazówek zegara aż powrócisz do punktu wyjścia
Właśnie otrzymałeś trójkąt!

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
ja nie jestem inźynierem po studiach nie potrafie odczytać tego projektu ktory zapodałeś , za mało informacji przepraszam


- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
no tak stosuje tylko jak ja mam ten projekt przedłożyć na kod ? za mało informacji ...
- Rejestracja:9 miesięcy
- Ostatnio:minuta
- Postów:25
Trudno oczekiwać że znajdziesz dokładnie to czego potrzebujesz. Jak zapytasz LLM to może... Nic dziwnego że są wzory matematyczne. Jak inaczej chcesz opisać trójkąt w układzie współrzędnych? Już pomijam ograniczenia które sam na siebie nakładasz (C++98, VC++6 i tym podobne). Ten OpenGL (> 2.0) o którym wspominasz także. Jakbyśmy nie wyszli poza 2002.
Ja właśnie zapytałem. Sprawdziłem na starym komputerze i rysuje. Poprosiłem też o wyjaśnienie. Może to coś pomoże.
Kod który otrzymałem:
#include <windows.h>
struct Point {
int x, y;
};
// Swap two points
void Swap(Point& a, Point& b) {
Point temp = a;
a = b;
b = temp;
}
// Sort vertices by y-coordinate
void SortVertices(Point& p1, Point& p2, Point& p3) {
if (p1.y > p2.y) Swap(p1, p2);
if (p1.y > p3.y) Swap(p1, p3);
if (p2.y > p3.y) Swap(p2, p3);
}
// Draw horizontal line
void DrawSpan(HDC hdc, int x1, int x2, int y, COLORREF color) {
if (x1 > x2) Swap(*(Point*)&x1, *(Point*)&x2);
for (int x = x1; x <= x2; ++x) {
SetPixel(hdc, x, y, color);
}
}
// Scanline fill algorithm
void FillTriangle(HDC hdc, Point p1, Point p2, Point p3, COLORREF color) {
SortVertices(p1, p2, p3);
int totalHeight = p3.y - p1.y;
if (totalHeight == 0) return; // Avoid division by zero
// Compute slopes
for (int i = 0; i < totalHeight; i++) {
bool secondHalf = (i > (p2.y - p1.y)) || (p1.y == p2.y);
int segmentHeight = secondHalf ? (p3.y - p2.y) : (p2.y - p1.y);
float alpha = (float)i / totalHeight;
float beta = (float)(i - (secondHalf ? (p2.y - p1.y) : 0)) / segmentHeight;
Point A = { p1.x + (int)((p3.x - p1.x) * alpha), p1.y + i };
Point B = secondHalf
? Point{ p2.x + (int)((p3.x - p2.x) * beta), p2.y + (i - (p2.y - p1.y)) }
: Point{ p1.x + (int)((p2.x - p1.x) * beta), p1.y + i };
DrawSpan(hdc, A.x, B.x, p1.y + i, color);
}
}
// Example usage in a WinAPI window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
Point p1 = {50, 250}, p2 = {350, 250}, p3 = {200, 50};
FillTriangle(hdc, p1, p2, p3, RGB(255, 0, 0));
EndPaint(hwnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wp, lp);
}
return 0;
}
// WinAPI boilerplate
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nCmdShow) {
WNDCLASS wc = { CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInst, NULL, LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1), NULL, TEXT("TriangleWin") };
RegisterClass(&wc);
HWND hwnd = CreateWindow(TEXT("TriangleWin"), TEXT("WinAPI Triangle"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInst, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Wyjaśnienie:
Rysowanie wypełnionego trójkąta za pomocą SetPixel
w WinAPI (kompatybilne z VC++6)
Opis algorytmu
Ponieważ SetPixel
działa tylko na pojedynczych pikselach, rysowanie trójkąta wymaga metody skanowania wierszy (ang. scanline fill). Oto jak działa nasz algorytm:
-
Sortowanie wierzchołków
- Trójkąt ma trzy punkty:
p1
,p2
ip3
. - Sortujemy je według współrzędnej
y
, aby miećp1
u góry,p3
na dole, ap2
w środku. - Dzięki temu możemy łatwo podzielić trójkąt na dwie części: dolną i górną.
- Trójkąt ma trzy punkty:
-
Podział na dwa trójkąty
- Górna część jest trójkątem płaskim od góry.
- Dolna część jest trójkątem płaskim od dołu.
- Oba fragmenty można wypełnić iterując wiersz po wierszu (po współrzędnej
y
).
-
Wypełnianie trójkąta metodą skanowania wierszy
- Dla każdego wiersza
y
obliczamy dwa krańcowe punktyA
iB
. - Punkty te są uzyskiwane przez interpolację liniową między wierzchołkami trójkąta.
- Następnie rysujemy poziomą linię między
A
aB
za pomocąSetPixel
.
- Dla każdego wiersza
Omówienie funkcji w kodzie
Struktura Point
struct Point {
int x, y;
};
- Definiuje prostą strukturę dla współrzędnych punktu
(x, y)
.
Funkcja Swap
– zamiana wartości dwóch punktów
void Swap(Point& a, Point& b) {
Point temp = a;
a = b;
b = temp;
}
- Używana do sortowania wierzchołków trójkąta.
Sortowanie wierzchołków według współrzędnej y
void SortVertices(Point& p1, Point& p2, Point& p3) {
if (p1.y > p2.y) Swap(p1, p2);
if (p1.y > p3.y) Swap(p1, p3);
if (p2.y > p3.y) Swap(p2, p3);
}
- Zapewnia, że
p1
ma najmniejszey
, ap3
największe.
Rysowanie poziomej linii między dwoma punktami w jednym wierszu
void DrawSpan(HDC hdc, int x1, int x2, int y, COLORREF color) {
if (x1 > x2) Swap(*(Point*)&x1, *(Point*)&x2);
for (int x = x1; x <= x2; ++x) {
SetPixel(hdc, x, y, color);
}
}
- Upewnia się, że
x1 ≤ x2
, a następnie rysuje poziomą linię.
Wypełnianie trójkąta metodą skanowania wierszy
void FillTriangle(HDC hdc, Point p1, Point p2, Point p3, COLORREF color) {
SortVertices(p1, p2, p3);
int totalHeight = p3.y - p1.y;
if (totalHeight == 0) return;
for (int i = 0; i < totalHeight; i++) {
bool secondHalf = (i > (p2.y - p1.y)) || (p1.y == p2.y);
int segmentHeight = secondHalf ? (p3.y - p2.y) : (p2.y - p1.y);
float alpha = (float)i / totalHeight;
float beta = (float)(i - (secondHalf ? (p2.y - p1.y) : 0)) / segmentHeight;
Point A = { p1.x + (int)((p3.x - p1.x) * alpha), p1.y + i };
Point B = secondHalf
? Point{ p2.x + (int)((p3.x - p2.x) * beta), p2.y + (i - (p2.y - p1.y)) }
: Point{ p1.x + (int)((p2.x - p1.x) * beta), p1.y + i };
DrawSpan(hdc, A.x, B.x, p1.y + i, color);
}
}
- Oblicza interpolację liniową dla każdego wiersza
y
, aby znaleźć skrajne punkty. - Sprawdza, czy jesteśmy w górnej czy dolnej części trójkąta.
- Rysuje poziome odcinki między punktami.
Implementacja w procedurze okna
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
Point p1 = {100, 50}, p2 = {50, 150}, p3 = {150, 150};
FillTriangle(hdc, p1, p2, p3, RGB(255, 0, 0));
EndPaint(hwnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wp, lp);
}
return 0;
}
WM_PAINT
wywołujeFillTriangle
, aby narysować trójkąt podczas odświeżania okna.WM_DESTROY
kończy program po zamknięciu okna.
Funkcja WinMain
– uruchamianie aplikacji
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nCmdShow) {
WNDCLASS wc = { CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInst, NULL, LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1), NULL, TEXT("TriangleWin") };
RegisterClass(&wc);
HWND hwnd = CreateWindow(TEXT("TriangleWin"), TEXT("WinAPI Triangle"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, NULL, NULL, hInst, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
- Rejestruje i tworzy okno WinAPI.
- Obsługuje główną pętlę komunikatów systemowych.
Podsumowanie
- Algorytm oparty jest na interpolacji liniowej i wypełnianiu wierszy.
SetPixel
jest stosowany do rysowania pojedynczych pikseli, co działa nawet na bardzo starych systemach.- Kod jest w pełni kompatybilny z VC++6 i Windows API z 2001 roku.

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
dużo tego , dziękuje , połapałem sie tym kodem dam sobie rade tak mysle ..

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
mam problem pokazuje błedy z tym
Point B = secondHalf
? Point{ p2.x + (int)((p3.x - p2.x) * beta), p2.y + (i - (p2.y - p1.y)) }
: Point{ p1.x + (int)((p2.x - p1.x) * beta), p1.y + i };
opis
error C2143: syntax error : missing ',' before '{'
C:\projekty\konsola\konsola.cpp(660) : error C2143: syntax error : missing ';' before '{'
C:\projekty\konsola\konsola.cpp(660) : error C2143: syntax error : missing ';' before '}'
C:\projekty\konsola\konsola.cpp(661) : error C2143: syntax error : missing ';' before ':'
C:\projekty\konsola\konsola.cpp(661) : error C2143: syntax error : missing ';' before '{'
C:\projekty\konsola\konsola.cpp(661) : error C2143: syntax error : missing ';' before '}'
- Rejestracja:9 miesięcy
- Ostatnio:minuta
- Postów:25
myślę że problem tkwi w tym - list initialization. To jest C++11. I wierz tu człowieku LLM'om

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
czyli nic u mnie , ja jade na c++98
- Rejestracja:9 miesięcy
- Ostatnio:minuta
- Postów:25
bez przesady. to latwo poprawic (w sensie uniknac list initialization).

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
jak ten PointB rozpisać jesli ktos wie?
- Rejestracja:9 miesięcy
- Ostatnio:minuta
- Postów:25
Ręce mi opadają ale może ja mam za wysokie oczekiwania.
Wersja A - pierwotny kod:
Point B = secondHalf
? Point{ p2.x + (int)((p3.x - p2.x) * beta), p2.y + (i - (p2.y - p1.y)) }
: Point{ p1.x + (int)((p2.x - p1.x) * beta), p1.y + i };
Wersja B (bez ternary i list initialization) - nie testowałem:
Point B;
if (secondHalf) {
B.x = p2.x + (int)((p3.x - p2.x) * beta);
B.y = p2.y + (i - (p2.y - p1.y));
} else {
B.x = p1.x + (int)((p2.x - p1.x) * beta);
B.y = p1.y + i;
}

- Rejestracja:ponad rok
- Ostatnio:około 18 godzin
- Postów:376
teraz to działa rysuje trójkąt , dzieki za treściwy przekaz wiedzy ...