Языки програмирования

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Здравствуйте) кто хорошо владеет каким нибудь языком програмирования?
Задание.Алгоритм построчного заполнения многоугольника с использованием затравочного пикселя.
Решение
в гуугле есть не сколько программ но они почемуто у меня не работаютв чем причина?(
на дельфи
Код:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  StackPix = record
    x: integer;
    y: integer;
  end;
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormPaint(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  arrStack: array of StackPix;
implementation
uses Math;
{$R *.dfm}
procedure pushStack(pxl: StackPix);
begin
SetLength(arrStack, Length(arrStack)+1);
arrStack[High(arrStack)]:=pxl;
end;
function popStack():StackPix;
begin
if High(arrStack)>=0 then
  begin
  popStack:=arrStack[High(arrStack)];
  SetLength(arrStack, High(arrStack));
  end
end;
procedure www(npxl:StackPix; Xmax:integer);
var
  fl: boolean;
  pc: TColor;
  i: integer;
begin
  while npxl.x <= Xmax do
    begin
      fl:=false;
      pc:=Form1.canvas.Pixels[npxl.x,npxl.y];
      while ((pc <> clBlack) and (pc <> clred) and (npxl.x < Xmax)) do
        begin
          if fl=false then fl:=true;
          npxl.x:=npxl.x+1;
          pc:=Form1.canvas.Pixels[npxl.x,npxl.y];
        end;
      if fl=true then
        begin
          if (npxl.x=Xmax) and (pc <> clBlack) and (pc <> clGreen) then
             pushStack(npxl)
          else
             begin
             npxl.x:=npxl.x-1;
             pushStack(npxl);
             end;
    //    fl:=false;
        end;
      i:=npxl.x;
      pc:=Form1.canvas.Pixels[npxl.x,npxl.y];
      while (((pc=clBlack) or (pc=clGreen)) and (npxl.x<Xmax)) do
        begin
          npxl.x:=npxl.x+1;
          pc:=Form1.canvas.Pixels[npxl.x,npxl.y];
        end;
 
      if npxl.x=i then npxl.x:=npxl.x+1;
  end;
end;
procedure nearby(pxl: StackPix);
var
  pc: TColor;
begin
pc:=Form1.canvas.Pixels[pxl.x,pxl.y];
if (pc <> clBlack) and (pc <> clRed) then pushStack(pxl);
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
canvas.Pen.Color:=clBlack;
canvas.MoveTo(100,115);
canvas.LineTo(180,115);
canvas.LineTo(280,115);
canvas.LineTo(280,270);
canvas.LineTo(230,270);
canvas.LineTo(70,270);
canvas.LineTo(20,270);
canvas.LineTo(20,115);
canvas.LineTo(200,115);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  pxl: StackPix;
  npxl: StackPix;
  i:integer;
  color: TColor;
begin
  Button1.Enabled:=false;
  pxl.x:=270;
  pxl.y:=118;
  pushStack(pxl);
  while High(arrStack)>-1 do
    begin
    case i  of
    0: color:=clblack;
    1: color:=clblack;
    2: color:=clblack;
    3: color:=clblack;
    4: color:=clblack;
    5: color:=clblack;
    end;
    pxl:=popStack;
    i:=RandomRange(0,5);
    canvas.Pixels[pxl.x,pxl.y]:=color;

    npxl.x:=pxl.x-1;
    npxl.y:=pxl.y;
    nearby(npxl);
 
    npxl.x:=pxl.x+1;
    npxl.y:=pxl.y;
    nearby(npxl);
 
    npxl.x:=pxl.x;
    npxl.y:=pxl.y-1;
    nearby(npxl);
 
    npxl.x:=pxl.x;
    npxl.y:=pxl.y+1;
    nearby(npxl);
    end;
 Button1.Enabled:=true;
end;
end.
и на с++ из этой темы тоже не идут(
 

Techno

Ассоциация VN
Сообщения
876
Реакции
403
Баллы
443
Ошибки какие выдает?
Одного кода мало, надо форму еще нарисовать с такими именами, что и в коде...
 
Последнее редактирование:

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Одного кода мало, надо форму еще нарисовать с такими именами, что и в коде...
Об этом я не подумал ну вот например
ни одна из этим команд не работает на Dev c++ 0.17 Приложение 6. Процедуры заливки области

Добавлено через 42 минуты 11 секунд
или hxxp://edu.nstu.ru/education/educourses/CompIm/Lit/Graphic/kg/3.htm (ссылка более не действительна) здесь написана [/URL]процедура я не знаю как ее реализовать?
 
Последнее редактирование модератором:

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Techno, я приблизительно понял что мне нужно сперва создать тхт файлы потом их объеденить в один проект, из этой статьи не знаю даже как приблизительно делать(, мне хотябы ехе файлы сделать.
 

Techno

Ассоциация VN
Сообщения
876
Реакции
403
Баллы
443
У меня нет времени все это читать)))

Там несколько процедур, Вас какая интересует?
Код:
 0.16.1  V_FP0 - простая процедура заливки многоугольника
V_FP1 - эффективная процедура заливки многоугольника
0.16.4  Тестовая процедуры V_FP1
  0.17.1  V_FAB4R - рекурсивная заливка 4-x связной области
0.17.5  V_FAST - построчная заливка области
 

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
ЗАЛИВКА ОБЛАСТИ С ЗАТРАВКОЙ

Как уже отмечалось, для приложений, связанных в основном с интерактивной работой, используются алгоритмы заполнения области с затравкой.

При этом тем или иным образом задается заливаемая (перекрашиваемая) область, код пиксела, которым будет выполняться заливка и начальная точка в области, начиная с которой начнется заливка.

По способу задания области делятся на два типа:

· гранично-определенные, задаваемые своей (замкнутой) границей такой, что коды пикселов границы отличны от кодов внутренней, перекрашиваемой части области. На коды пикселы внутренней части области налагаются два условия - они должны быть отличны от кода пикселов границы и кода пиксела перекраски. Если внутри гранично-определенной области имеется еще одна граница, нарисованная пикселами с тем же кодом, что и внешняя граница, то соответствующая часть области не должна перекрашиваться;

· внутренне-определенные, нарисованные одним определенным кодом пиксела. При заливке этот код заменяется на новый код закраски.

В этом состоит основное отличие заливки области с затравкой от заполнения многоугольника. В последнем случае мы сразу имеем всю информацию о предельных размерах части экрана, занятой многоугольником. Поэтому определение принадлежности пиксела многоугольнику базируется на быстро работающих алгоритмах, использующих когерентность строк и ребер (см. предыдущий раздел). В алгоритмах же заливки области с затравкой нам вначале надо прочитать пиксел, затем определить принадлежит ли он области и если принадлежит, то перекрасить.

Заливаемая область или ее граница - некоторое связное множество пикселов. По способам доступа к соседним пикселам области делятся на 4-х и 8-ми связные. В 4-х связных областях доступ к соседним пикселам осуществляется по четырем направлениям - горизонтально влево и вправо и в вертикально вверх и вниз. В 8-ми связных областях к этим направлениям добавляются еще 4 диагональных. Используя связность мы может, двигаясь от точки затравки, достичь и закрасить все пикселы области.

Важно отметить, что для 4-х связной прямоугольной области граница 8-ми связна (рис. а) и наоборот у 8-ми связной области граница 4-х связна (см. рис. б). Поэтому заполнение 4-х связной области 8-ми связным алгоритмом может привести к "просачиванию" через границу и заливке пикселов в примыкающей области.

В общем, 4-х связную область мы можем заполнить как 4-х, так и 8-ми связным алгоритмом. Обратное же неверно. Так область на рис. а мы можем заполнить любым алгоритмом, а область на рис. б, состоящую из двух примыкающих 4-х связных областей можно заполнить только 8-ми связным алгоритмом.
http://algolist.manual.ru/graphics/pic/kg0226.gif
С использованием связности областей и стека можно построить простые алгоритмы закраски как внутренне, так и гранично-определенной области. В [] рассматриваются совсем короткие рекурсивные подпрограммы заливки. В [] - несколько более длинные итеративные подпрограммы.
 

Techno

Ассоциация VN
Сообщения
876
Реакции
403
Баллы
443
В программу нужно копировать процедуру
Код:
0.17.5  V_FAST - построчная заливка области
и тест
Код:
0.17.6  Тест процедуры V_FAST
потом попробуйте запустить и напишите какие ошибки выдает
 

Techno

Ассоциация VN
Сообщения
876
Реакции
403
Баллы
443
Ничего не видно:)

Приложение Console Wizard
Код:
Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#include <winbgi.cpp>
#pragma hdrstop



/*----------------------------------------------------- V_FAST
 * Подпрограммы заливки области с затравкой
 * построчным алгоритмом:
 *
 * Pop_Stk   - Локальная подпрограмма. Извлекает координаты
 *             пиксела из стека в глобальные скаляры xtek,ytek
 *
 * Push_Stk  - Локальная подпрограмма. Заносит координаты
 *             пиксела в стек
 *
 * Get_Video - Локальная подпрограмма. Читает строку из
 *             видеопамяти в глобальный буфер строки.
 *
 * Put_Video - Локальная подпрограмма. Копирует байты из
 *             глобального буфера строки в видеопамять.
 *
 * Search    - Локальная подпрограмма. Ищет затравочные
 *             пикселы в строке видеопамяти, находящейся
 *             в глобальном массиве.
 *
 * V_FAST    - Собственно подпрограмма построчной заливки
 *             гранично-определенной области
 *
 * V_FA_SET  - Устанавливает количественные ограничения
 *            для заливки
 */

#include <alloc.h>
#include <graphics.h>
#include <stdio.h>

#define MAX_GOR 2048  /* Разрешение дисплея по X */
#define MAX_VER 2048  /* Разрешение дисплея по Y */
#define MAX_STK 8192  /* Размер стека координат заливки */

static int gor_max= MAX_GOR;
static int ver_max= MAX_VER;
static int stk_max= MAX_STK;
static int *pi_stk, *pn_stk;   /* Указ  стека заливки */
static int xtek, ytek;         /* Координаты из стека */
static char *pc_video;         /* Указ на буфер строки */
static int stklen;             /* Достигнутая глубина стека*/
                               /* только для отладочных    */
                               /* измерений программы      */


/*---------------------------------------------------- Pop_Stk
 * Извлекает координаты пиксела из стека в xtek, ytek
 * Возвращает 0/1 - нет/есть ошибки
 */
static int  Pop_Stk ()
{  register int  otw;
   otw= 0;
   if (pi_stk <= pn_stk) ++otw; else {
      ytek= *--pi_stk;  xtek= *--pi_stk;
   }
   return (otw);
}  /* Pop_Stk */

/*--------------------------------------------------- Push_Stk
 * Заносит координаты пиксела в стек
 * Возвращает -1/0 - нет места под стек/норма
 */
static int  Push_Stk (int x, int y)
//register int x, y;
{
   register int glu;
   if ((glu= pi_stk - pn_stk) >= stk_max) x= -1; else {
      *pi_stk++= x;  *pi_stk++= y; x= 0;
      if (glu > stklen) stklen= glu;
   }
   return (x);
}  /* Push_Stk */

/*-------------------------------------------------- Get_Video
 * В байтовый буфер строки, заданный глобальным
 * указателем pc_video,
 * читает из видеопамяти пикселы y-строки от xbg до xen
 * Возвращает 0/1 - нет/есть ошибки
 */
static int  Get_Video (int y, char *pcxbg, char *pcxen)
//register char *pcxbg, *pcxen;
{  register int x;

   if (y>=0 && y<ver_max && pcxbg<=pcxen) {
      x= pcxbg - pc_video;
      do *pcxbg++= getpixel (x++, y); while (pcxbg <= pcxen);
      y= 0;
   } else y= 1;
   return (y);
}  /* Get_Video */

/*-------------------------------------------------- Put_Video
 * Пикселы из буфера строки, начиная от указателя pxbg,
 * до указателя pxen пишет в y-строку видеопамяти
 * Возвращает 0/1 - нет/есть ошибки
 */
static int  Put_Video (int y, char *pxbg, char *pxen)
//register char *pxbg, *pxen;
{  register int  x;
   if (y>=0 && y<ver_max && pxbg<=pxen) {
      x= pxbg - pc_video;
      do putpixel (x++, y, *pxbg++); while (pxbg <= pxen);
      y= 0;
   } else y= 1;
   return (y);
}  /* Put_Video */

/*----------------------------------------------------- Search
 * Ищет затравочные пикселы в yt-строке видеопамяти,
 * находящейся по указателю pc_video, начиная от
 * указателя pcl до указателя pcr
 * grn - код граничного пиксела
 * new - код, которым перекрашивается область
 * Возвращает: 0/1 - не найден/найден затравочный
 */
static int  Search (int yt, char *pcl, char *pcr, int grn, int nw)
//char *pcl, *pcr;  int grn, nw;
{  register int pix;
   register char *pc;
   int x, otw;

   otw= 0;
   while (pcl <= pcr) {
      pc= pcl;                          /* Указ тек пиксела */
/* Поиск крайнего правого не закрашенного пиксела в строке */
      while ((pix= *pc & 255) != grn && pix != nw && pc<pcr)
         ++pc;

      if (pc != pcl) {          /* Найден закрашиваемый */
         ++otw;
         x= pc - pc_video;      /* Его координата в строке */
         if (pc != pcr || pix == grn || pix == nw) --x;
         Push_Stk (x, yt);
      }
/* Продолжение анализа строки пока не достигнут прав пиксел */
      pcl= pc;
      while (((pix= *pc & 255) == grn || pix==nw) && pc<pcr)
         ++pc;
      if (pc == pcl) ++pc;
      pcl= pc;
   }
   return (otw);
}  /* Search */

/*----------------------------------------------------- V_FAST
 * Построчная заливка с затравкой гранично-определенной
 * области
 *
 * int V_FAST (int grn_pix, int new_pix, int x_isx, int y_isx)
 *
 * Вход:
 * grn_pix - код граничного пиксела
 * new_pix - код заполняющего пиксела
 * x_isx   - координаты затравки
 * y_isx
 *
 * Возвращает:
 * -2 - нет места под растровую строку
 * -1 - нет места под стек
 *  0 - норма
 *  1 - при чтении пикселов из видеопамяти в буферную
 *      строки выход за пределы буферной строки
 *  2 - исчерпан стек при запросе координат пикселов
 *
 */
int V_FAST (int grn_pix, int new_pix, int x_isx, int y_isx)
//int grn_pix, new_pix, x_isx, y_isx;
{
   register char *pcl;    /* Указ левого  пиксела в строке */
   register char *pcr;    /* Указ правого пиксела в строке */
   int  otw;

   otw= 0;

/* Инициализация стека */
   if ((pn_stk= (int *)malloc (stk_max)) == NULL) {
      --otw;  goto all;
   }
   pi_stk= pn_stk;

/* Заказ массива под растровую строку */
   if ((pc_video= (char *)malloc (gor_max)) == NULL) {
      otw= -2;  goto fre_stk;
   }

   Push_Stk (x_isx, y_isx);     /* Затравку в стек */

/* Цикл заливки строк до исчерпания стека */

   while (pi_stk > pn_stk) {

/* Запрос координат затравки из стека */
      if (Pop_Stk ()) {otw=2; break; }
      pcl= pcr= pc_video + xtek;   /* Указ затравки */

/* Запрос полной строки из видеопамяти */
      if (Get_Video (ytek, pc_video, pc_video+gor_max-1))
         {otw= 1;  break; }

/* Закраска затравки и вправо от нее */
      do *pcr++= new_pix; while ((*pcr & 255) != grn_pix);
      --pcr;                    /* Указ крайнего правого */

/* Закраска влево */
      while ((*--pcl & 255) != grn_pix) *pcl= new_pix;
      ++pcl;                    /* Указ крайнего левого */

/* Занесение подправленной строки в видеопамять */
      Put_Video (ytek, pcl, pcr);

/* Поиск затравок в строках ytek+1 и ytek-1,
 * начиная с левого подинтервала, заданного pcl, до
 * правого подинтервала, заданного pcr
 */
      if (!Get_Video (++ytek, pcl, pcr))
         Search (ytek, pcl, pcr, grn_pix, new_pix);

      if (!Get_Video (ytek-= 2, pcl, pcr))
         Search (ytek, pcl, pcr, grn_pix, new_pix);
   }
   free (pc_video);
fre_stk:
   free (pn_stk);
all:
   return (otw);
}  /* V_FAST */

/*--------------------------------------------------- V_FA_SET
 * Устанавливает количественные ограничения для заливки
 */
void V_FA_SET (int x_resolution, int y_resolution, int stack_length)
//int  x_resolution, y_resolution, stack_length;
{
   if (x_resolution > 0 && x_resolution <= MAX_GOR)
      gor_max= x_resolution;
   if (y_resolution > 0 && y_resolution <= MAX_VER)
      ver_max= y_resolution;
/* Кол байт координат, заносимых в стек м.б. только четным */
   if (stack_length > 0) stk_max= stack_length & 0177776;
}  /* V_FA_SET */





/*-------------------------------------------------- FAST_MAIN
 */
void main (void)
{
   int   ii, kol, grn, nw, entry;
   int   x_isx, y_isx;
   int   gdriver = DETECT, gmode;
   int   Px[256] = {200,200,250,270,270,210,210,230,230};
   int   Py[256] = {200,250,250,230,200,210,230,230,210};

   kol= 5;              /* Кол-во вершин        */
   grn= 11;             /* Код пикселов границы */
   nw= 14;             /* Код заливки          */
   x_isx= 240;          /* Координаты затравки  */
   y_isx= 240;
   entry= 0;

   initgraph(&gdriver, &gmode, "c:\tc\bgi");
   if ((ii= graphresult()) != grOk) {
      printf ("Err=%d\n", ii); goto all;
   }

m0:goto m2;
m1:++entry;
   printf("Vertexs, boundary_pixel, new_pixel= (%d %d %d) ? ",
            kol, grn, nw);
   scanf ("%d%d%d", &kol, &grn, &nw);
   if (kol < 0) goto all;

   for (ii=0; ii<kol; ++ii) {
      printf ("Px[%d], Py[%d] = ? ", ii, ii);
      scanf  ("%d%d", &Px[ii], &Py[ii]);
   }

   printf ("X,Y isx= (%d %d) ? ", x_isx, y_isx);
   scanf ("%d%d", &x_isx, &y_isx);

m2:
   setbkcolor(0);
   cleardevice();

/* Построение границы */
   setcolor (grn);
   for (ii= 0; ii<kol-1; ++ii)
      line (Px[ii], Py[ii], Px[ii+1], Py[ii+1]);
   line (Px[kol-1], Py[kol-1], Px[0], Py[0]);

/* При первом входе строится квадратик дырки */
   if (!entry) {
      for (ii= kol; ii<kol+3; ++ii)
         line (Px[ii], Py[ii], Px[ii+1], Py[ii+1]);
      line (Px[kol+3], Py[kol+3], Px[kol], Py[kol]);
   }

/* Установка количественных ограничений для проц заливки */
   V_FA_SET (getmaxx()+1, getmaxy()+1, MAX_STK);

   stklen= 0;           /* Занятое кол-во байт в стеке */

/* Заливка */
   ii= V_FAST (grn, nw, x_isx, y_isx);
   printf ("Answer= %d MaxStack=%d\n", ii, stklen);
   goto m1;

all:
   closegraph();
}

Файлы .h, .cpp, .c из архива в папка_сибилдера/include
Файл .lib из архива в папка_сибилдера/lib
 

Вложения

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Techno, Сейчас буду пробывать!!!Спасибо)

Добавлено через 3 часа 0 минут 19 секунд
Файлы .h, .cpp, .c из архива в папка_сибилдера/include
Файл .lib из архива в папка_сибилдера/lib
я их переместил куда вы сказали, код вставил и выдал две ошибки
Код:
[Linker Error] Unresolved external '_Form1' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER6\PROJECTS\PROJECT1.OBJ
[Linker Error] Unresolved external 'TForm1::' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER6\PROJECTS\PROJECT1.OBJ
 

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Techno, что оно делает? и как можно сделать рисунок по больше? и чтоб обработка была по медленне?
 
Последнее редактирование:

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Techno, и за это большое спасибо))Попробую сам разобраться)вы получается все скрипты включили или только эти два 0.17.5 V_FAST - построчная заливка области и тест 0.17.6 Тест процедуры V_FAST?
 

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Techno, еще раз больщое спасибо))Выручили)
 

aidoqa

Активный пользователь
Сообщения
1,137
Реакции
316
Баллы
463
Techno, можно вопрос как происходит заливка?и еще почему когда я вбиваю свои значения он постоянно выдает мне ошибку или как правильно вбивать значения(может я делаю что то нето)?

что за ошибка
Код:
"[C++ Warning] Dialogs.hpp(437): W8058 Cannot create pre-compiled header: initialized data in header"
как можно сделать замедление по времени
 
Последнее редактирование:
Сверху Снизу