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

  • Автор темы Автор темы aidoqa
  • Дата начала Дата начала

aidoqa

Опытный участник
Сообщения
1,016
Реакции
108
Здравствуйте) кто хорошо владеет каким нибудь языком програмирования?
Задание.Алгоритм построчного заполнения многоугольника с использованием затравочного пикселя.
Решение
в гуугле есть не сколько программ но они почемуто у меня не работаютв чем причина?(
на дельфи
Код:
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.
и на с++ из этой темы тоже не идут(
 
Ошибки какие выдает?
Одного кода мало, надо форму еще нарисовать с такими именами, что и в коде...
 
Последнее редактирование:
Одного кода мало, надо форму еще нарисовать с такими именами, что и в коде...
Об этом я не подумал ну вот например
ни одна из этим команд не работает на Dev c++ 0.17 Приложение 6. Процедуры заливки области

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

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

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

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

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

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

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

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

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

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

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

потом попробуйте запустить и напишите какие ошибки выдает
 
Ничего не видно:)

Приложение 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
 

Вложения

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
 
Techno, что оно делает? и как можно сделать рисунок по больше? и чтоб обработка была по медленне?
 
Последнее редактирование:
Techno, и за это большое спасибо))Попробую сам разобраться)вы получается все скрипты включили или только эти два 0.17.5 V_FAST - построчная заливка области и тест 0.17.6 Тест процедуры V_FAST?
 
Techno, можно вопрос как происходит заливка?и еще почему когда я вбиваю свои значения он постоянно выдает мне ошибку или как правильно вбивать значения(может я делаю что то нето)?

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