Форум Программирование Построение дуги |
|
Необходимо написать собственную процедуру рисования дуги Canvas.Arc не устроил, поскольку для него нужно писать корректирующий алгоритм, чтобы заткнуть дырки в погрешностях построения, которые иногда могут возникать при округлении результатов. Написал на посмотреть такую процедуру procedure TForm1.FormCreate(Sender: TObject); begin Randomize; Color := RGB(Random(256), Random(256), Random(256)); n := False; end; procedure TForm1.BitBtn1Click(Sender: TObject); begin SetLength(Mas0, 3, 2); SetLength(Mas1, 2, 2); // (A1, -), (X1, Y1) Mas0[0, 0] := StrToFloat(Edit1.Text); // R Mas0[0, 1] := StrToFloat(Edit2.Text); // Aльфа0 Mas0[1, 0] := ArcTan(1 / Mas0[0, 0]); // Шаг Canvas.MoveTo(200 + Round(Mas0[0, 0]), 200); Canvas.Pen.Color := RGB(Random(256), Random(256), Random(256)); Mas0[1, 1] := 0; // Начальный/текущий угол repeat Mas0[2, 0] := Round(200 + Mas0[0, 0] * cos(Mas0[1, 1])); // X0 Mas0[2, 1] := Round(200 + Mas0[0, 0] * sin(Mas0[1, 1])); // Y0 Canvas.LineTo(Round(Mas0[2, 0]), Round(Mas0[2, 1])); Mas1[0, 0] := Mas0[1, 1] + 2 * Mas0[1, 0]; if Mas1[0, 0] <= Mas0[0, 1] then begin Mas1[1, 0] := Round(200 + Mas0[0, 0] * cos(Mas1[0, 0])); // X1 Mas1[1, 1] := Round(200 + Mas0[0, 0] * sin(Mas1[0, 0])); // Y1 if (abs(Mas0[2, 0] - Mas1[1, 0]) = 1) and (abs(Mas0[2, 1] - Mas1[1, 1]) = 1) then begin n := True; Canvas.Pen.Color := RGB(Random(256), Random(256), Random(256)); Canvas.LineTo(Round(Mas1[1, 0]), Round(Mas1[1, 1])); end; end; if n = False // Текущий угол then Mas0[1, 1] := Mas0[1, 1] + Mas0[1, 0] else begin Mas0[1, 1] := Mas1[0, 0]; n := False; end; until Mas0[1, 1] >= Mas0[0, 1]; // Текущий угол >= Альфа0 end; Здесь накидано только часть необходимого по минимуму, всё вроде как нормально, но результаты построения отличаются между собой (часть пикселей рисуется на один выше/ниже/левее/правее), проблема в округлении, года 3 назад слышал что программисты долго пилили этот алгоритм округления, чтоб получить то, что есть сейчас. Собственно вопрос: где можно посмотреть исходный код стандартной процедуры построения дуги? | ||||||
|
Цитата (Фео): где можно посмотреть исходный код стандартной процедуры построения дуги? Стандартной, говоришь? Есть тут одна малоизвестная фирма... мелкософт, вроде, называется... Думаю, что исходник находится там, ибо: procedure TCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); begin Changing; RequiredState([csHandleValid, csPenValid, csBrushValid]); Windows.Arc(FHandle, X1, Y1, X2, Y2, X3, Y3, X4, Y4); Changed; end; Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! | ||||||
|
Спасибо... что находится внутри Windows.Arc я не нашёл, и сколько ещё исходников вложенных процедур придётся искать - не знаю, но думаю многовато, тем более для самостоятельного изучения второго курса программирования, единственное что наткнулся на ява код, в котором округления и не боло в принципе, может только внутри Angle где-то, хотя там скорее сглаживание применяется, что мне не надо, писать свою процедуру сглаживания для меня будет геморно, хотя что и как надо делать я представляю | ||||||
|
Нашёл решение своей проблемы, но пока не писал код 0) пишем все получаемые координаты в отдельный динамический массив - буфер, для круга достаточно просчитывать Пи/4 радиана, для овала Пи/2 радиана, дугу в зависимости от ситуации, остальные координаты можно посчитать сложив 2 и 2; 1) в буфере поблочно в 4 пикселя с шагом в 1 обрабатывать получаемые координаты, "выравнивая" их и выкидывая лишние, заменяя их координаты на (-65536, -65536), исключая их из видимой области формы и игнорируя при построении; 2) на следующем проходе буфера выкидываем из него избыточные данные, затирая их значением (-65536, -65536), оставляя минимум точек, находящихся в узлах (вершинах) прямых, кривые и замкнутые линии рисуются как известно из множества прямых разной длины, расположенных под углами X mod Pi/4 = 0; 3) строим дугу или чё там нам надо по оставшимся данным, игнорируя ячейки буфера со значением (-65536, -65536); Результат будет выглядеть нормально, но будет дальше от истинного, в отличие от изначального варианта, наверно данный метод 100% опять же не будет повторять построение с помощью стандартных процедур | ||||||
Перейти в раздел:
© 2004 - 2024, Delphi.int.ru |
Версия форума: 1.10 (19.01.2010) |
Выполнено за 0.03 сек. |