Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.06.2009, 19:01   #1
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию Рандомизационное получение координат массива без повторения.

Требуется создать программу, которая (теоретически) должна повторять эффект "растворение" из Movie Maker`a. Для тех, кто в танке - при этом эффекте одна картинка сменяет другую попиксельно в "случаином" порядке.
Что-бы реализовать такой эффект я решил разделить работу на два шага:
1) создать программу, которая запишет в файл порядок пикселей (кто за кем сменяется).
2) Процедуру, которая считает координаты и сменит пиксель (достаточно простая часть).

Проблемы появились во время первого шага. Предположим у нас есть массив размером 512*96 (размер изображений)
Код:
Var
 Mas[0..512,0..96] of Byte;
Далее идет сам текст программы:
Код:
 Begin
  Randomize;                    {"Случайность"}
  For I:=0 to 512 do          
    For J:=0 to 96 do
      Mas[I,J]:=0;              {Обнулим весь массив (на всякий пожарный)}
  N:=0;                           {Количество измененных пикселей}
  While N<>513*97 do       {Пока все пиксели не закрашены, сделаем это}
    Begin
      ...
    End;
 End;
Вся загвоздка в том, что если система случайно выберет пиксель, а он будет закрашен, мы запишем его координаты повторно и тем самым замедлим время выполнения 2-го шага на несколько часов (пока все не закрасятся по несколько раз). Как реализовать выбор пикселя, еще не закрашенного?
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 07.06.2009, 20:41   #2
Ntlegend
Форумчанин
 
Аватар для Ntlegend
 
Регистрация: 12.05.2007
Сообщений: 373
Радость

в архиве есть примерчик.. попробуй разоюбраться.. если чтото не понятно - обращяйся
Вложения
Тип файла: rar Unit1.rar (1.8 Кб, 10 просмотров)
Перемен! - требуют наши сердца. Перемен! - требуют наши глаза.
В нашем смехе и в наших слезах, И в пульсации вен:
"Перемен!Мы ждем перемен!"
Ntlegend вне форума Ответить с цитированием
Старый 07.06.2009, 20:58   #3
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Я так понимаю это отрисовка изображение ПНГ с использованием альфа каналов, а я думаю о примерно этом:

В принципе можно реализовать с помощью меток:
Код:
LAbels LABELKA
Begin
 
LABELKA
X1:=Random(513);
Y1:=Random(97);
If Mas[X1,Y1]=1 Then Goto LABELKA
Но не хотельсь бы их использовать.
Изображения
Тип файла: jpg Растворение_0001.jpg (61.0 Кб, 98 просмотров)
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 07.06.2009, 22:42   #4
Ntlegend
Форумчанин
 
Аватар для Ntlegend
 
Регистрация: 12.05.2007
Сообщений: 373
По умолчанию

отрисовка не ПНГ а рисунка.. любого.. прсто в ПНГ мне удобно хранить..
если не хочешь на основе изменения альфаканала тогда делай следующее..

в памяти рисонок представлен как массив бит.. тоесть все его пикселы выстроены в строку.. нумерацыя начинается с 0 заканчивается Width*Height-1.. значит создаем массив в котором будут пронумерованы пикселы и заполняем его
Код:
var pn: array [0..Image1.Width*Image1.Height-1] of cardinal;
i:cardinal;
begin
for i:=0 to High(pn) do
 pn:=i;
теперь у нас есть "строка" пронумерованых пикселов.. дальше мы просто переставляем в ней элементы местами
Код:
Shuffle(pn, High(pn), SizeOf(Cardinal));
и собственно эта процедура(скопируй как есть):
Код:
procedure Shuffle(var aArray; aItemCount: Cardinal; aItemSize: Cardinal);
var
  Inx: Cardinal;
  RandInx: Cardinal;
  SwapItem: PByteArray;
  A: TByteArray absolute aArray;
begin
  if (aItemCount > 1) then
  begin
    GetMem(SwapItem, aItemSize);
    try
      for Inx := 0 to (aItemCount - 2) do
      begin
        RandInx := Random(aItemCount - Inx);
        Move(A[Inx * aItemSize], SwapItem^, aItemSize);
        Move(A[RandInx * aItemSize], A[Inx * aItemSize], aItemSize);
        Move(SwapItem^, A[RandInx * aItemSize], aItemSize);
      end;
    finally
      FreeMem(SwapItem, aItemSize);
    end;
  end;
end;
и дальше отображаем картинку..

Код:
for i := 1 to High(pn) - 1 do
 begin
  Image1.Canvas.Pixels[pn[i]div Image1.Height,pn[i] mod Image1.Height ]:=
   Image2.Canvas.Pixels[pn[i]div Image1.Height,pn[i] mod Image1.Height];
end;
работает нормально при условии что картинки одинаковых размеров..
Перемен! - требуют наши сердца. Перемен! - требуют наши глаза.
В нашем смехе и в наших слезах, И в пульсации вен:
"Перемен!Мы ждем перемен!"
Ntlegend вне форума Ответить с цитированием
Старый 08.06.2009, 17:38   #5
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Я сделал немного проще и короче (он кажется длиннее за счет фич):
Код:
var
  Form1: TForm1;
  X1,Y1:Integer;
  Mas:Array[0..511,0..95] of Byte;
  N:LongInt;
  I,J:Integer;
  F:TextFile;
  S,SX,SY:String;
  
implementation

{$R *.dfm}

Procedure Randoming;
 Begin
  X1:=Random(512);
  Y1:=Random(96);
 End;

procedure TForm1.Button1Click(Sender: TObject);
begin
 N:=0;
 For I:=0 to 95 do
  For J:=0 to 511 do
   Mas[J,I]:=0;
   Randoming;

 AssignFile(F,'IMAP.txt');
 Rewrite(F);
 While N<3437 Do
  Begin
   While ((Mas[X1,Y1]=1) Or (Image3.Canvas.Pixels[X1,Y1]=clBlack)) do Randoming;
   Mas[X1,Y1]:=1;
    
   Image2.Canvas.Pixels[X1,Y1]:=clWhite;
   Image2.Refresh;
   
   Image3.Canvas.Pixels[X1,Y1]:=clBlack;
   Image3.Refresh;
   
   If X1<10 Then SX:='00'+IntToStr(X1);
   If (X1>9) And (X1<100) Then SX:='0'+IntToStr(X1);
   If X1>99 Then SX:=IntToStr(X1);
   If Y1<10 Then SY:='00'+IntToStr(Y1);
   If (Y1>9) And (Y1<100) Then SY:='0'+IntToStr(Y1);
   If Y1>99 Then SY:=IntToStr(Y1);
   
   S:=SX+SY;
   Writeln(F,S);
   Inc(N);

  End;
 CloseFile(F);
 Button1.Enabled:=False;
 Button1.Caption:='Restart application for continue';
end;

В архиве - только ЕХЕ
Вложения
Тип файла: rar Project1.rar (186.2 Кб, 13 просмотров)
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Повторения в Combobox crit БД в Delphi 3 03.06.2009 17:10
Повторения(Файл) ТРОЯН=) Помощь студентам 2 09.04.2009 21:52
получение форм без перезагрузки страници AJAX memka PHP 1 08.04.2009 23:19
Получение значений из таблицы в виде массива (Вопрос по MySQL) Linel PHP 5 29.03.2009 11:34
Получение координат точек касательной к окружности Stilet Помощь студентам 2 01.08.2008 15:12