Как оптимизировать определение границ произвольной фигуры ?
Модератор: Модераторы
Чем? всё тоже самое, да есть отличия в примитивах и их особенностях. но например простейшая линия что у тс, что у меня одинаковая
zub писал(а):но например простейшая линия что у тс, что у меня одинаковая
Хорошо - задачи идентичные, но это ничего не меняет.
Вот только данные хранятся по разному, он в метафайлах, а Вы в точках.
Добавлено спустя 7 минут 77 секунд:
Re: Как оптимизировать определение границ произвольной фигуры ?
pupsik писал(а):Что произойдет с PLine после PLine := bmp.ScanLine[q.y];?
С Pline произойдёт вот это: PByte := bmp.RawImage.Data; т.к. это быстрее и Лазарус не ругается.
ничего это не значит. У вас сделана проверка цвета пикселя с определёнными координатами. А вот что дальше.... А дальше -нуль. Ну посчитали вы время цикла и что? Ну считаете что ScanLine не относится к алгоритму. Ну не правильно вы этот ScanLine использовали. Ну криво битмап выгрузили (из-за этого в лине у меня "мертвецы" валялись). Ну считаете begin..endupdate пошлостью (всё равно что это ускорило загрузку битмапа и показ формы). Ну не воспринимаете вы советы zub (хотя он не сильно то и программист, вроде у него профа иная). И т.д., и т.п.Если точка найдена, значит она уже на линии, т.к. кроме линии в задаче ничего больше нет.
Зато ваша реализация круче и вы "положили@ zub на порядок
ох... Т.е. вы считаете что скачок времени произошёл из-за крутости алгоритма? Мдя..я: "Слышали звон, да не знаете где он". Лазарь не ругается, он делает ещё интереснее (гад такойт.к. это быстрее и Лазарус не ругается.
pupsik писал(а):хотя он не сильно то и программист, вроде у него профа иная
И что? Ну, встретились два "не программиста", ну обменялись знаниями и не знаниями. Ну потрунили друг над другом. По моему - всё в норме.
pupsik писал(а): вы считаете что скачок времени произошёл из-за крутости алгоритма?
Я ничего не считаю, просто показал, что: можно поставленную задачу - решать проще, а результат получать быстрее. И этот метод, известен мне очень давно, т.к. раньше все игры так делались. Этот способ я подглядел у наших программистов, которые делали игры ( я тогда ещё не умел программировать, но тесно с ними общался )
pupsik писал(а):У вас сделана проверка цвета пикселя с определёнными координатами.
Цвет пикселя - это ID линии или фигуры, а дальше как в хорошей базе данных, что хотите, то и делаете.
.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
vitaly_l писал(а):можно поставленную задачу - решать проще, а результат получать быстрее.
Не всегда это, кстати, синонимы.
vitaly_l писал(а):Ну, встретились два "не программиста", ну обменялись знаниями и не знаниями.
одни такие крутые прогеры выпуск каждой новой версии винды задерживали на год (именно так 97 превратилась в 98). А уж поиск ошибок в них вообще за гранью добра и зла.
Так что лучше уж хороший любитель, чем два специалиста)))
ну да.. ну да. Вы практически это пробовали? У вас идеальная задача была, а вы только пиксель проверили. И не доказали что он "в линии". А вот куда интереснее будет когда с реальным изображением работать. И как "вытягивать" оттуда необходимое без, как вы выразились, математики?Цвет пикселя - это ID линии или фигуры, а дальше как в хорошей базе данных, что хотите, то и делаете.
хм..:Я ничего не считаю
1.
- стало интересно..Жди, сейчас сварганю.
2.
...Ну вот как и обещал, код работает на порядок быстрее. В частности, при абсолютно равных условиях, код художников возвращает 0.003 и 0.001 секунды, а код программиста zub возвращает 0.021 и 0.024. Тобишь, как и говорилось изначальнокод художников, на порядок быстрее при 1000000 итераций
- интерес потерялсято его код станет медленнее на два порядка, а скорость кода художников - не изменится
Можно больше накидать...
В принципе согласен с одним: "скорость художника не изменится". Сори за сарказм.
ну да : найти цвет по координатампросто показал, что: можно поставленную задачу - решать проще, а результат получать быстрее.
п.с.
вам бы тогда рисовать нечем было бы... Такие поделия тогда, при тех конфигах компов... вызвали бы шок и не только.И этот метод, известен мне очень давно, т.к. раньше все игры так делались
pupsik писал(а):ну да.. ну да. Вы практически это пробовали?
На этом методе - работают 50% 2D игр. Это не моя идея. Кстати, топик-стартер, тоже использует данный метод в своём коде. Метод очень распространённый.
pupsik писал(а): И как "вытягивать" оттуда необходимое без, как вы выразились, математики?
\это уже дело мастера боится, задача идентичная любой другой.
pupsik писал(а):Такие поделия тогда, при тех конфигах компов... вызвали бы шок и не только.
Именно потому что, ресурсов у компов было мало, программисты всячески берегли ресурсы и придумали этот максимально быстрый код, который на порядок быстрее чем математический подход. <== Что в этом удивительного?
Но в наше время, когда ресурсы иные - можно делать более сложными способами, т.к. они дают больше возможностей.
.
э..э: вы о каком коде? Если о поиске цвета... то там, по сути, нет кода.этот максимально быстрый код
Ок...
Тс.
1. Что там у него организовано и как... не известно.
2. Судя по заданному вопросу появилось впечатление что он всё рисует на битмапе. Без объектов и структур. (могу ошибаться... кода не видел).
3. Выделение.... Зачем оно? Ответ тс я писал выше (да и сам он его писал где то на 5-й странице)..
У меня напрашивается вывод о весьма странной логике приложения. Выделения, как я понимаю, в похожих программах необходимо для изменения св-в объекта. У тс оно необходимо для прикола.?
Как из изображения вытягивают необходимое (у меня сложилось впечатление что именно это необходимо тс)? Увы, без знаний математики (которую вы отвергли) фиговенько и мучительно.
Посмотрите, для примера, https://sourceforge.net/projects/evssimplegraph/. Это весьма интересный порт. Да он не похож на задачу тс (возможно). Но там есть выделение объектов.
И, возможно, кривовато сделано но..о там что по пиксельно проходят и ищут необходимое.? Используют хитрые алгоритмы, методы?
Считаю этот топик весьма странным. В котором проехались по всему и всём что только можно. А толку, возможно, никакого. Менять алексу надо логику программы. Иначе или лаги, или странные вопросы.
п.с.
Кстати vitaly_l : вы не доказали что точка находится "в линии". Да и код хромает.
Советую почитать доп. лит-ру. Познакомиться с кодом других программ. Не обязательно крутые и супер быстро работающие. А то ваш "художник" малость достал.
pupsik писал(а):Да и код хромает. Советую почитать доп. лит-ру.
Если видите что, я что-то не так написал в коде, то буду благодарен, если укажите на конкретную ошибку.
/
хм... т.е. "мертвецы" висящие в системе - это не указание на ошибку? Разное (0,4 не могут резко стать 0,01 при почти одинаковых условиях) время срабатывание алгоритма - не указание на ошибки? э..э, а что тогда указание?Если видите что, я что-то не так написал в коде, то буду благодарен, если укажите на конкретную ошибку.
Дополнительно.
По поводу bgrabitmap. Каждому куличику...
Проводил простой тест по загрузке изображения (по времени).
Получился такой порядок:
1. Вампирка.
2. Стандартные лазаровские методы.
3. bgrabitmap.
Первое и второе как бы почти идентичны, в определённых случаях. В вампирке есть плюс: меньше писать кода, есть готовые алгоритмы. Но и в лазаре есть много чего интересного. Если покопаться много чего нарыть можно.
bgrabitmap пока из кокона не вылезла. Хотя пытается.
pupsik писал(а): "мертвецы" висящие в системе - это не указание на ошибку?
Я не понимаю что это такое? ==> "мертвецы" висящие в системе ?
pupsik писал(а):Разное (0,4 не могут резко стать 0,01 при почти одинаковых условиях) время срабатывание алгоритма - не указание на ошибки? э..э, а что тогда указание?
Я сравнивал, на реальном коде, а вы делаете ГИПОТЕТИЧЕСКИЕ предположения. Так вот, 0.01 - становятся 0.4 и больше при реальной загрузке данных.
"мертвецы" - про закрытии программы не освобождается память. Вот и висит себе програмка мертвым грузом.
Повышение времени конечно будет при использовании реальных данных.
Но не в вашем выложенном коде. Проверял несколько раз, ради интереса. После того как начало подлагивать посмотрел в диспетчер и офигел.
Если же при одних и тех же условиях (я не считаю состояния системы) происходит резкий (у меня на 10 порядков) "бросок" скорости работы. По простому: несколько раз нажал на кнопку "Художник" (вроде так). Значит криво сделано.
Я не зря спрашивал о моменте сканирования. Вы не поняли. Жаль.
Такой "скачок" возможен при использовании буфера. Т.е. данные уже получены и происходит подсчёт времени только цикла.
Я уже писал что сканирование - то же участок алгоритма. Вы же его считаете "пятым колесом".
В общем много чего можно вытянуть из маленького кусочка программы. Только толку???
Добавлено спустя 3 минуты:
Re: Как оптимизировать определение границ произвольной фигуры ?
п.с.
При нормальной логике... вот это:
Хотя понятие реально большие объёмы могут у нас отличаться...
это "предположение" было сделано на том коде который вы выложили.. Учитывая малый объем кода и выше сказанное... в общем не весело...а вы делаете ГИПОТЕТИЧЕСКИЕ предположения
Повышение времени конечно будет при использовании реальных данных.
Но не в вашем выложенном коде. Проверял несколько раз, ради интереса. После того как начало подлагивать посмотрел в диспетчер и офигел.
Если же при одних и тех же условиях (я не считаю состояния системы) происходит резкий (у меня на 10 порядков) "бросок" скорости работы. По простому: несколько раз нажал на кнопку "Художник" (вроде так). Значит криво сделано.
Я не зря спрашивал о моменте сканирования. Вы не поняли. Жаль.
Такой "скачок" возможен при использовании буфера. Т.е. данные уже получены и происходит подсчёт времени только цикла.
Я уже писал что сканирование - то же участок алгоритма. Вы же его считаете "пятым колесом".
В общем много чего можно вытянуть из маленького кусочка программы. Только толку???
Добавлено спустя 3 минуты:
Re: Как оптимизировать определение границ произвольной фигуры ?
п.с.
При нормальной логике... вот это:
будет происходить при реально больших объёмах.Так вот, 0.01 - становятся 0.4 и больше при реальной загрузке данных.
Хотя понятие реально большие объёмы могут у нас отличаться...
pupsik писал(а):"мертвецы" - про закрытии программы не освобождается память. Вот и висит себе програмка мертвым грузом.
Вот код. Согласно Вашим утверждениям, здесь память не освобождается и программа висит "мертвецом" в системе.
Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
const
eps=1e-14;
type
TLine=Array [0..2] of byte;
GDBvertex2DI=record
x,y:integer;
end;
{ TForm1 }
TForm1 = class(TForm)
ButtonHudojniki: TButton;
ButtonProgramistZub: TButton;
procedure ButtonHudojnikiClick(Sender: TObject);
procedure ButtonProgramistZubClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
bmp:TBitmap;
implementation
{$R *.lfm}
{ TForm1 }
function distance2line(var q:GDBvertex2DI;var p1,p2:GDBvertex2DI): double;
var t,w,p2x_p1x,p2y_p1y,qx_p1x,qy_p1y,qy_p2y,qx_p2x: double;
begin
p2x_p1x:=p2.x-p1.x;
p2y_p1y:=p2.y-p1.y;
qx_p1x:=q.x-p1.x;
qx_p2x:=q.x-p2.x;
qy_p1y:=q.y-p1.y;
qy_p2y:=q.y-p2.y;
if((qx_p1x)*(p2x_p1x)+(qy_p1y)*(p2y_p1y))*((qx_p2x)*(p2x_p1x)+(qy_p2y)*(p2y_p1y))>-eps then
begin
t:= sqr(qx_p1x)+sqr(qy_p1y);
w:= sqr(qx_p2x)+sqr(qy_p2y);
if w<t then t:= w;
end else
t:= sqr((qx_p1x)*(p2y_p1y)-(qy_p1y)*(p2x_p1x))/(sqr(p2x_p1x)+sqr(p2y_p1y));
result:= sqrt(t);
end;
procedure TForm1.ButtonHudojnikiClick(Sender: TObject);
var
q:GDBvertex2DI;
myTime:TDateTime;
ts:string;
i:integer;
boTest:boolean;
PLine:^TLine;
begin
boTest := false;
q.x:=100; q.y:=100;
PLine := bmp.ScanLine[q.y];
myTime:=now;
for i:=0 to 1000000 do
if PLine^[q.x]<>$f2 then boTest := true;
str((now-myTime)*10e4:2:3,ts);
if boTest
then caption := 'Точка найдена за '+ts+' sec.'
else caption := 'Точка не найдена за '+ts+' sec.';
end;
procedure TForm1.ButtonProgramistZubClick(Sender: TObject);
var
q,p1,p2:GDBvertex2DI;
dist:double;
myTime:TDateTime;
ts:string;
i:integer;
begin
q.x:=100;q.y:=100;
p1.x:=0;p1.y:=0;
p2.x:=9999;p2.y:=9999;
myTime:=now;
for i:=0 to 1000000 do
dist:=distance2line(q,p1,p2);
str((now-myTime)*10e4:2:3,ts);
if abs(dist)<eps then
caption := 'Точка найдена за '+ts+' sec.'
else
caption := 'Точка не найдена за '+ts+' sec.';
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
bmp:=TBitmap.Create;
bmp.Canvas.Pen.Color := clBlack;
bmp.Canvas.Brush.Color := $f2;
bmp.Width :=10000;
bmp.Height:=10000;
bmp.Canvas.FillRect(0,0,9999,9999);
bmp.Canvas.MoveTo(0,0);
bmp.Canvas.LineTo(9999,9999);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
bmp.Free;
end;
end.
Конкретно в этом коде, что Вы полагаете нужно исправить, чтобы не было "мертвецов"?
Вот видно что на ошибках не учитесь. У вас был схожий вопрос. В котором был виноват onClose
Как вы думаете: что надо сделать ещё, окромя
?
Когда создаем объект мы надеемся что его обнулит (удалит) само приложение или программист должен позаботиться о таком мало важном мероприятии?
В принципе, возможно, существует волшебная палочка. Но, в данном случае, она в отпуске.
п.с.
Вполне возможно в винде и нет "мертвых". Но в жтк у меня они висели и радовались.
Добавлено спустя 2 минуты 43 секунды:
Re: Как оптимизировать определение границ произвольной фигуры ?
мне вот интересно: когда до скринов дело дойдёт
))))))))))
Короче: всё вы делаете верно. И zub вы положили на лопатки
Как вы думаете: что надо сделать ещё, окромя
Код: Выделить всё
bmp.Free;Когда создаем объект мы надеемся что его обнулит (удалит) само приложение или программист должен позаботиться о таком мало важном мероприятии?
В принципе, возможно, существует волшебная палочка. Но, в данном случае, она в отпуске.
п.с.
Вполне возможно в винде и нет "мертвых". Но в жтк у меня они висели и радовались.
Добавлено спустя 2 минуты 43 секунды:
Re: Как оптимизировать определение границ произвольной фигуры ?
мне вот интересно: когда до скринов дело дойдёт
Короче: всё вы делаете верно. И zub вы положили на лопатки
pupsik писал(а):Вполне возможно в винде и нет "мертвых". Но в жтк у меня они висели и радовались.
Да, в винде этого нет и действительно в винде, кода: bmp.Free; - более чем достаточно.
Вы намекаете что я должен был сделать: FreeAndNil(bmp); - верно?
Если ответ, Да, то в общем-то я прислушаюсь и буду удалять командой FreeAndNil.
Спасибо что сказали.
