Advertisement
ms_shnits

Рисование раскрашенного треугольника

Dec 7th, 2020 (edited)
1,352
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 6.30 KB | None | 0 0
  1. PROGRAM ColorTriangle;
  2.  
  3. CONST
  4.     canvas_width  = 500;
  5.     canvas_height = 500;
  6.  
  7. TYPE
  8.     Integer = int32;
  9.     TCanvas = array[0..canvas_width, 0..canvas_height] of Integer;
  10.  
  11.  
  12.  
  13. { меняет местами x и y }
  14. PROCEDURE Swap(var x, y : Integer);
  15. BEGIN
  16. x := x + y;
  17. y := x - y;
  18. x := x - y;
  19. END;
  20.  
  21.  
  22.  
  23. { работа с R, G, B компонентами }
  24. FUNCTION cR(x : Integer) : Integer; BEGIN cR := x shr 16; END;
  25. FUNCTION cG(x : Integer) : Integer; BEGIN cG := x shr 8 and 255; END;
  26. FUNCTION cB(x : Integer) : Integer; BEGIN cB := x and 255; END;
  27. FUNCTION RGB (r, g, b : Integer) : Integer;
  28. BEGIN
  29. RGB := r and 255 shl 16 + g and 255 shl 8 + b and 255;
  30. END;
  31.  
  32.  
  33.  
  34. { линейная интерполяция (x1, y1) - (x, ? ) - (x2, y2) }
  35. FUNCTION LinearInterpolate(x1, y1, x, x2, y2 : Integer) : Integer;
  36. BEGIN
  37. LinearInterpolate := y1 + (y2 - y1) * (x - x1) div (x2 - x1);
  38. END;
  39.  
  40.  
  41.  
  42. { рисование градиентной горизонтальной линии }
  43. PROCEDURE DrawLine(var canvas : TCanvas; x1, color1, x2, color2, y : Integer);
  44.  
  45. VAR
  46.     x : Integer;
  47.  
  48. BEGIN
  49.  
  50. { если x1 = x2 - вырожденный случай }
  51. if x1 = x2 then begin
  52.     canvas[x1, y] := (color1 + color2) shr 1;
  53.     exit;
  54.     end;
  55.  
  56. { сортируем вершины так, чтобы выполнялось x1 <= x2 }
  57. if x1 > x2 then begin
  58.     Swap(    x1,     x2);
  59.     Swap(color1, color2);
  60.     end;
  61.  
  62. for x := x1 to x2 do
  63.     if (x >= 0) and (x <= canvas_width) and (y >= 0) and (y <= canvas_height) then
  64.         canvas[x, y] := RGB(
  65.                         LinearInterpolate(x1, cR(color1), x, x2, cR(color2)),
  66.                         LinearInterpolate(x1, cG(color1), x, x2, cG(color2)),
  67.                         LinearInterpolate(x1, cB(color1), x, x2, cB(color2))
  68.                         );
  69.  
  70. END;
  71.  
  72.  
  73.  
  74.  
  75. { рисование закрашенного треугольника }
  76. PROCEDURE DrawTriangle(var canvas : TCanvas;  x1, y1, color1,  x2, y2, color2,  x3, y3, color3 : Integer);
  77.  
  78. VAR
  79.     y                      : Integer;
  80.     x_line_A, color_line_A,
  81.     x_line_B, color_line_B : Integer;
  82.  
  83. BEGIN
  84.  
  85. { сортируем вершины так, чтобы выполнялось y1 <= y2 <= y3 }
  86. if (y1 > y2) or (y1 = y2) and (x1 > x2) then begin
  87.     Swap(    x1,     x2);
  88.     Swap(    y1,     y2);
  89.     Swap(color1, color2);
  90.     end;
  91. if (y2 > y3) or (y2 = y3) and (x2 > x3) then begin
  92.     Swap(    x2,     x3);
  93.     Swap(    y2,     y3);
  94.     Swap(color2, color3);
  95.     end;
  96. if (y1 > y2) or (y1 = y2) and (x1 > x2) then begin
  97.     Swap(    x1,     x2);
  98.     Swap(    y1,     y2);
  99.     Swap(color1, color2);
  100.     end;
  101.  
  102. { если y1 = y3 - вырожденный случай }
  103. if y1 = y3 then begin
  104.     DrawLine(canvas, x1, color1, x3, color3, y1);
  105.     exit;
  106.     end;
  107.  
  108. { закрашиваем горизонтальными полосками часть треугольника от y1 до y2 }
  109. if y1 <> y2 then
  110.     for y := y1 to y2 do begin
  111.  
  112.         { считаем начало и конец горизонтальной полоски }
  113.         x_line_A     := LinearInterpolate(y1, x1, y, y2, x2);
  114.         color_line_A := RGB(
  115.                         LinearInterpolate(y1, cR(color1), y, y2, cR(color2)),
  116.                         LinearInterpolate(y1, cG(color1), y, y2, cG(color2)),
  117.                         LinearInterpolate(y1, cB(color1), y, y2, cB(color2))
  118.                         );
  119.         x_line_B     := LinearInterpolate(y1, x1, y, y3, x3);
  120.         color_line_B := RGB(
  121.                         LinearInterpolate(y1, cR(color1), y, y3, cR(color3)),
  122.                         LinearInterpolate(y1, cG(color1), y, y3, cG(color3)),
  123.                         LinearInterpolate(y1, cB(color1), y, y3, cB(color3))
  124.                         );
  125.  
  126.         { рисуем полоску }
  127.         DrawLine(canvas, x_line_A, color_line_A, x_line_B, color_line_B, y);
  128.         end;
  129.  
  130. { закрашиваем горизонтальными полосками часть треугольника от y2 до y3 }
  131. if y2 <> y3 then
  132.     for y := y2 to y3 do begin
  133.  
  134.         { считаем начало и конец горизонтальной полоски }
  135.         x_line_A     := LinearInterpolate(y2, x2, y, y3, x3);
  136.         color_line_A := RGB(
  137.                         LinearInterpolate(y2, cR(color2), y, y3, cR(color3)),
  138.                         LinearInterpolate(y2, cG(color2), y, y3, cG(color3)),
  139.                         LinearInterpolate(y2, cB(color2), y, y3, cB(color3))
  140.                         );
  141.         x_line_B     := LinearInterpolate(y1, x1, y, y3, x3);
  142.         color_line_B := RGB(
  143.                         LinearInterpolate(y1, cR(color1), y, y3, cR(color3)),
  144.                         LinearInterpolate(y1, cG(color1), y, y3, cG(color3)),
  145.                         LinearInterpolate(y1, cB(color1), y, y3, cB(color3))
  146.                         );
  147.  
  148.         { рисуем полоску }
  149.         DrawLine(canvas, x_line_A, color_line_A, x_line_B, color_line_B, y);
  150.         end;
  151.  
  152. END;
  153.  
  154.  
  155. VAR
  156.     { картинная плоскость }
  157.     canvas : TCanvas;
  158.  
  159.     x, y  : integer;
  160.  
  161.     { вершины треугольника и их цвета }
  162.     x1, y1, color1,
  163.     x2, y2, color2,
  164.     x3, y3, color3 : integer;
  165.  
  166.     { для сохранения картинки в файл }
  167.     F :Text;
  168.  
  169.  
  170. BEGIN
  171.  
  172. { инициализируем катринную плоскость черным цеветом }
  173. for x := 0 to canvas_width do
  174.     for y := 0 to canvas_height do
  175.         canvas[x, y] := 0;
  176.  
  177.  
  178. { задаём вершины треугольника и их цвета }
  179. x1 :=  10; y1 :=  10; color1 := RGB(255, 0, 0);
  180. x2 := 300; y2 := 490; color2 := RGB(0, 255, 0);
  181. x3 := 490; y3 := 100; color3 := RGB(0, 0, 255);
  182.  
  183.  
  184. { рисуем треугольник }
  185. DrawTriangle(canvas, x1, y1, color1,  x2, y2, color2,  x3, y3, color3);
  186.  
  187.  
  188. { сбрасываем картинную плоскость в файл .ppm }
  189. Assign(F, 'result.ppm');
  190. Rewrite(F);
  191.  
  192. WriteLn(F, 'P3');
  193. WriteLn(F, canvas_width+1, ' ', canvas_height+1);
  194. WriteLn(F, 255);
  195.  
  196. for y := 0 to canvas_height do begin
  197.     for x := 0 to canvas_width do
  198.         Write(F, cR(canvas[x, y]), ' ', cG(canvas[x, y]), ' ', cB(canvas[x, y]), ' ');
  199.     WriteLn(F, '');
  200.     end;
  201.  
  202.  
  203. Close(F);
  204.  
  205. END.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement