Модераторы: Snowy, Alexeis, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильное рисование окружности, TCanvas 
:(
    Опции темы
MacTep
Дата 9.10.2004, 07:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Почему, когда я рисую окружность так
Код
var i,r:integer;
begin

 for r:=0 to 150 do
   for i:=0 to 360 do
     Canvas.Pixels[200+round(r*cos(i*2*pi/360)),200+round(r*sin(i*2*pi/360))]:=i;
у меня получается, что в окружностях имеются маленькие точечки, которые не прорисовываются? Как от этого можно избавиться? Спасибо!



--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
p0s0l
Дата 9.10.2004, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 16
Всего: 112



Потому что заведомо ты установливаешь количество пикселей в окружности (360). А если радиус будет большой, то будут дыры...
Лучше рисовать по алгоритму Брезенхема - он быстрее, без sin/cos, и без дыр будет...


--------------------
С уважением, г-н Посол.
PM   Вверх
p0s0l
Дата 9.10.2004, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 16
Всего: 112



Вот, накидал рисование через Брезенхема на примере того цветого круга, который ты хотел получить в соседней теме...

Код
procedure TForm1.Button4Click(Sender: TObject);
var
 x0, y0, r : integer;
 d, x, y : integer;

function CalcColor(a : real) : TColor;
var i : integer;
const
 pi23 = pi*2/3;
 pi43 = pi*4/3;
begin
 while a < 0 do a := a + pi*2;
 
 if a < pi23 then
 begin
   i := Round(255*a/pi23);
   Result := RGB(255-i, i, 0);
 end
 else
 if a < pi43 then
 begin
   i := Round(255*(a-pi23)/pi23);
   Result := RGB(0, 255-i, i);
 end
 else
 begin
   i := Round(255*(a-pi43)/pi23);
   Result := RGB(i, 0, 255-i);
 end;
end;

procedure DrawPixels;
var
 a1 : real;
begin
 if x = 0 then a1 := pi / 2 else a1 := ArcTan (y / x);
 Canvas.Pixels[x0 + x, y0 + y] := CalcColor(a1);
 Canvas.Pixels[x0 - x, y0 + y] := CalcColor(pi - a1);
 Canvas.Pixels[x0 + x, y0 - y] := CalcColor(-a1);
 Canvas.Pixels[x0 - x, y0 - y] := CalcColor(-pi + a1);
 Canvas.Pixels[x0 + y, y0 + x] := CalcColor(pi/2 - a1);
 Canvas.Pixels[x0 - y, y0 + x] := CalcColor(pi/2 + a1);
 Canvas.Pixels[x0 + y, y0 - x] := CalcColor(-pi/2 + a1);
 Canvas.Pixels[x0 - y, y0 - x] := CalcColor(-pi/2 - a1);
end;

begin
// центр окружности
 x0 := 200;
 y0 := 200;

 for r := 0 to 150 do
 begin
   x := 0;
   y := r;
   d := 3 - 2*r;
   repeat
     DrawPixels;
     if d < 0 then Inc(d, x*4 + 6)
     else
     begin
       Inc(d, 4*(x-y)+10);
       Dec(y);
       DrawPixels;
     end;
     Inc(x);
   until x > y;
 end;  
end;



--------------------
С уважением, г-н Посол.
PM   Вверх
MacTep
Дата 10.10.2004, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



А знаешь, в соседней теме, да и в этой я тоже пытался сделать так, чтобы к центру окружности, цвета становились темнее и в конце-концов стали черными, а к краям все было белее и белее и вдруг стало белым. Как это сделать?


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
p0s0l
Дата 10.10.2004, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 16
Всего: 112



Так ?
Код
procedure TForm1.Button1Click(Sender: TObject);
var
 x0, y0, rmin, rmax : integer;
 d, x, y, r : integer;
 k, k1 : real;

function CalcColor(a : real) : TColor;
var
 r, g, b : real;
const
 pi23 = pi*2/3;
 pi43 = pi*4/3;
begin
 if a < 0 then a := a + pi*2;

 if a < pi23 then
 begin
   g := 255*a/pi23;
   r := 255-g;
   b := 0;
 end
 else
 if a < pi43 then
 begin
   r := 0;
   b := 255*(a-pi23)/pi23;
   g := 255-b;
 end
 else
 begin
   r := 255*(a-pi43)/pi23;
   g := 0;
   b := 255-r;
 end;

 if k <= 1 then
 begin
   r := r*k;
   g := g*k;
   b := b*k;
 end
 else
 begin
   r := 255 -(255-r)*k1;
   g := 255 -(255-g)*k1;
   b := 255 -(255-b)*k1;
 end;
 Result := RGB(Trunc(r), Trunc(g), Trunc(b));
end;

procedure DrawPixels;
var
 a1 : real;
begin
 if x = 0 then a1 := pi / 2 else a1 := ArcTan (y / x);
 Canvas.Pixels[x0 + x, y0 + y] := CalcColor(a1);
 Canvas.Pixels[x0 - x, y0 + y] := CalcColor(pi - a1);
 Canvas.Pixels[x0 + x, y0 - y] := CalcColor(-a1);
 Canvas.Pixels[x0 - x, y0 - y] := CalcColor(-pi + a1);
 Canvas.Pixels[x0 + y, y0 + x] := CalcColor(pi/2 - a1);
 Canvas.Pixels[x0 - y, y0 + x] := CalcColor(pi/2 + a1);
 Canvas.Pixels[x0 + y, y0 - x] := CalcColor(-pi/2 + a1);
 Canvas.Pixels[x0 - y, y0 - x] := CalcColor(-pi/2 - a1);
end;

begin
// центр окружности
 x0 := 200;
 y0 := 200;
// начальные и конечные радиусы
 rmin := 0;
 rmax := 150;

 for r := rmin to rmax do
 begin
   k := (r-rmin)*2/(rmax - rmin);
   k1 := 2-k;
   x := 0;
   y := r;
   d := 3 - 2*r;
   repeat
     DrawPixels;
     if d < 0 then Inc(d, x*4 + 6)
     else
     begin
       Inc(d, 4*(x-y)+10);
       Dec(y);
       DrawPixels;
     end;
     Inc(x);
   until x > y;
 end;
end;

PS: изменил позже процедуру CalcColor, там из-за целочисленных вычислений/округлений была четкая граница между переходами R-G-B, теперь получше стало...

Это сообщение отредактировал(а) p0s0l - 10.10.2004, 23:54


--------------------
С уважением, г-н Посол.
PM   Вверх
Kesh
Дата 10.10.2004, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2488
Регистрация: 31.7.2002
Где: Германия, Saarbrü cken

Репутация: 1
Всего: 54



Код
procedure TForm1.FormClick(Sender: TObject);
const
 N = 300;
var
 i,j: integer;
 c: byte;
begin
 form1.Canvas.Brush.Style := bsSolid;
 for i := N downto 0 do
   begin
     c := Round(i/N*255);
     form1.Canvas.Pen.Color := RGB(c,c,c);
     form1.Canvas.Brush.Color := RGB(c,c,c);
     form1.Canvas.Ellipse(N-i,N-i,N+i,N+i);
   end;
end;



--------------------
user posted image
PM MAIL WWW ICQ Skype   Вверх
MacTep
Дата 11.10.2004, 08:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Kesh, мне надо, чтобы круг был не черно-белым, а полноцветным. Т.е. там должны быть все цвета радуги, плавно переходящие друг из друга в другие цвета. Мне надо такую окружность, как показал p0s0l, но с таким затемнением, как у тебя. Понятно?

Добавлено @ 08:30
p0s0l, все замечательно. Ты все сделал просто класс. Только теперь можно узнать, в чем состоит алгоритм Брозенхейма и парут-тройку комментаривев к твое программе. А то мне ее надо еще объянять преподу, да и отчет писать как-никак.


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Alex
Дата 11.10.2004, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 1
Всего: 162



Цитата(MacTep @ 11.10.2004, 09:20)
p0s0l, все замечательно. Ты все сделал просто класс. Только теперь можно узнать, в чем состоит алгоритм Брозенхейма и парут-тройку комментаривев к твое программе. А то мне ее надо еще объянять преподу, да и отчет писать как-никак.

http://www.yandex.ru/yandsearch?text=%C1%F...5%E5%EC%E0&tb=1


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
p0s0l
Дата 11.10.2004, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 16
Всего: 112



Comments:

CalcColor - вычисляет цвет точки в зависимости от угла (вх. параметр a), и от радиуса окружности.
Вначале выясняется, к какой трети окружности принадлежит данная точка, и в зависимости от этого вычисляется её цвет. Например, во второй трети (if a < pi43) вычисляется так:
красная компонента = 0
зеленая компонента -> чем больше угол, тем меньше зелености
синяя компонента - наоборот, чем больше угол, тем больше синевы
Далее (if k <= 1) - если радиус текущей окружности ® меньше половины радиуса внешней окружности (rmax), то идёт затемнение цвета путём умножения составляющих цвета на коэффициент k, где k=[0..1]
Если же (k > 1), то наоборот происходит осветление...

DrawPixels - выводит 8 симметрично расположенных пикселей. Почему 8 ? В данном коде окружность разбивается на 8 частей, и алгоритмом Брезенхема вычисляется только одна часть, остальные части получаются путём зеркального отражения.

А там дальше уже идёт сам Брезенхем - о нём можешь почитать в данных выше ссылках...


--------------------
С уважением, г-н Посол.
PM   Вверх
MacTep
Дата 11.10.2004, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Вот спасибо! Очень помогло!


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
posleg
Дата 22.1.2010, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 2.7.2009

Репутация: нет
Всего: нет



хороший пример))))
не подскажете как на его основе сделать 4- х связанный эллипс ??????????
плиз
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.1779 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.