ZXNet эхоконференция «code.zx»
тема: Алгоpитм постpоения эллипса
от: Alexandr Filippov
кому: All
дата: 18 Apr 2003
Пpивет all!
Hyжен сабж, и если не сложно пpимеp на басике/асме.
Alexand
от: Anton Kolotvin
кому: Alexandr Filippov
дата: 20 Apr 2003
Привет _Alexandr_ ! Пишет тебе *Anton* !
18 Апр 03 20:42, _Alexandr Filippov_ ══. /All/:
AF> Hyжен сабж, и если не сложно пpимеp на басике/асме.
AF>
Сабж прост до безобразия :)
10 let a=10: let b=20: let x=100: let y=100
20 let s=3/(a+b)
30 for t=0 to 2*pi step s
40 plot x+a*sin(t), y+b*cos(t)
50 next t
это так, навскидку. Принцип прост:
10 - инициализация. а= радиус по оси Х, б = радиус по У
20 - вычисление шага. Троечку можно поменять на число поменьше - будет
покачественнее, но медленнее.
30 - в цикле прогоняем t по всей окружности, от 0 до 360 градусов.
40 - ставим точечки. Можно было и отрезками, но неохота :)
а если а и б менять в теле цикла - можно спираль получить или еще чего похлеще
:)
Вот и всё! Очень просто, имхо. Будут вопросы - задавай.
Hу что еще сказать?... Пока, _*Alexandr*_ !
от: Oleg Grigoriev
кому: Anton Kolotvin
дата: 23 Apr 2003
Пусть враги твои, Anton, умрут без сыновей!
20 Apr 2003 at 20:59, Anton Kolotvin => Alexandr Filippov:
AK> покачественнее, но медленнее. 30 - в цикле прогоняем t по всей
AK> окружности, от 0 до 360 градусов.
достаточно до 90 градусов, а остальное зеркально отражать.
WBR, Oleg.
от: Kirill Frolov
кому: Anton Kolotvin
дата: 24 Apr 2003
On Sun, 20 Apr 2003 19:59:40 +0400, Anton Kolotvin wrote:
AK> 20 - вычисление шага. Троечку можно поменять на число поменьше - будет
AK> покачественнее, но медленнее.
Можно точки прямыми линиями соединять, чтобы разрывов не было.
А вообще есть какой-то более нормальный алгоритм (Брезенхейма?) построения
эллипсов и окружностей, но я не помню уже.
--
[ZX]
от: Anton Kolotvin
кому: Oleg Grigoriev
дата: 24 Apr 2003
Привет _Oleg_ ! Пишет тебе *Anton* !
23 Апр 03 18:46, _Oleg Grigoriev_ ══. /Anton Kolotvin/:
AK>> покачественнее, но медленнее. 30 - в цикле прогоняем t по всей
AK>> окружности, от 0 до 360 градусов.
OG>
OG> достаточно до 90 градусов, а остальное зеркально отражать.
Хм, и вправду можно, но я же говорил, что это так, навскидку, без оптимизации.
Hу что еще сказать?... Пока, _*Oleg*_ !
от: Dmitriy Nesmachny
кому: Anton Kolotvin
дата: 27 Apr 2003
Привет, Anton!
Воскресенье 20 Апр 2003 20:59:40, Anton Kolotvin -> Alexandr Filippov:
AK> 10 let a=10: let b=20: let x=100: let y=100
AK> 20 let s=3/(a+b)
AK> 30 for t=0 to 2*pi step s
AK> 40 plot x+a*sin(t), y+b*cos(t)
AK> 50 next t
Hе катит. У тебя оси эллипса параллельны осям координат. Уравнение эллипса,
учитывающее произвольный поворот его осей мне неизвестно. Так что, видимо,
каждую точку надо будет еще на матрицу поворота домножить... :-(((
С уважением, Dmitriy.
от: Anton Kolotvin
кому: Kirill Frolov
дата: 27 Apr 2003
Привет _Kirill_ ! Пишет тебе *Anton* !
24 Апр 03 07:39, _Kirill Frolov_ ══. /Anton Kolotvin/:
KF> Можно точки прямыми линиями соединять, чтобы разрывов не было.
Я об этом говорил. Просто я написал самое простое, что взбрело в голову.
KF> А вообще есть какой-то более нормальный алгоритм (Брезенхейма?)
KF> построения эллипсов и окружностей, но я не помню уже.
Hапомню. Правда на С, но могу и на Васике кинуть.
Алгоритм прорисовки эллипса.
// прорисовка почти точного эллипса быстрым целочисленным алгоритмом;
void DrawEllipse(int x, int y, long int a, long int b,
unsigned long int color)
// прорисовка 1/8 части графика функции D = t0+t1+t2 = (a^2)*(y^2) +
// + 2*(a^2)*y + (x^2)*(b^2) - x*(b^2) - (a^2)*(b^2) + (a^2) + (b^2)/4,
// x>=0, y>=0 или y=-1+(b/a)*sqrt(-(x^2)+x+(a^2)-1/4), x>=0, y>=0
// затем корректировка и прорисовка другой 1/8 части немного изменённого
// подобного графика - получается почти точный эллипс}
{int ex, ey; long int aa, aa2, bb, bb2, d, dx, dy;
// Задание начальных значений; t0:=aa-bb*a+(bb div 4); t1:=0; t2:=bb2*a;
ex = a; ey = 0; aa = a * a; aa2 = aa * 2; bb = b * b; bb2 = bb * 2;
d = aa - bb * a + (bb % 4); dx = aa; dy = bb2 * a;
DrawPixel(x - ex, y, color); DrawPixel(x, y - b, color);
DrawPixel(x + ex, y, color); DrawPixel(x, y + b, color);
// Прорисовка 1/8 части графика, и симметричный вывод в 1,2,3,4 четвертях;
while (dx < dy)
{if (d > 0)
{ex--;
dy = dy - bb2; // DY = -bb2 * (a - ex);
d = d - dy; // t1:=t1-dy = bb*(1+a-ex)*(a-ex)-(a-ex)*bb2*a;
}
ey++;
dx = dx + aa2; // DX = aa2*ey;
d = d + dx; // t2:=t2+aa+dx = aa*EY*(1+EY)+EY*aa; D = t0+t1+t2;
DrawPixel(x + ex, y + ey, color); DrawPixel(x + ex, y - ey, color);
DrawPixel(x - ex, y + ey, color); DrawPixel(x - ex, y - ey, color);
}
// Корректировка: уменьшение D для совпадения радиуса = b по координате Y;
d = d + ( (3*(bb-aa) % 2) - (dx-aa+dy) ) % 2; dy = dy - bb;
// Прорисовка оставшейся 1/8 части графика, и симметричный вывод в 1,2,3,4
// четвертях;
while (ex > 0)
{if (d < 0) {ey++; dx = dx + aa2; d = d + dx;}
ex--; dy = dy - bb2; d = d - dy;
DrawPixel(x + ex, y + ey, color); DrawPixel(x + ex, y - ey, color);
DrawPixel(x - ex, y + ey, color); DrawPixel(x - ex, y - ey, color);
}
}
Hадеюсь, комментариев не надо. в принципе, все должно быть понятно.
Hу что еще сказать?... Пока, _*Kirill*_ !
|