Первое что я поборол - это отрисовка лучей и продолженных линий. их основная загвоздка в том что надо находить точки на грани виджета, куда надо направлять линию. Луч я рисую так:
(defun parser-ray (cd w h)
(set-source-rgb 0 0 1)
(set-line-width 1)
(move-to (* *scroll-units* (getf cd :x1))
(* *scroll-units* (getf cd :y1)))
(line-to (* (/ (getf cd :x1) *scroll-units*)
(let ((x1 (getf cd :x1))
(y1 (getf cd :y1))
(x2 (getf cd :x2))
(y2 (getf cd :y2)))
(+
(* (- w y1)
(/ (- x2 x1)
(- y2 y1)))
x1)))
(* (/ (getf cd :y1) *scroll-units*)
(let ((x1 (getf cd :x1))
(y1 (getf cd :y1))
(x2 (getf cd :x2))
(y2 (getf cd :y2)))
(* (/ (- y2 y1)
(- x2 x1))
(- h x1)))))
(stroke))
Вроде нигде не наврал, но есть проблема - если зуммировать изображение до размеров точки, то луч и прод.линия начинают люто-бешено прыгать по экрану. Как мне помнится такое я наблюдал в компасе, qcad и еще где то, так что не особо обеспокоен этим фактом. ЕМНИП в автокаде есть на это дело границы зуммирования. Чуть позже разберусь с этим.
А пока вот рабочий скрин:


Только что обнаружил косяк - при изменении геометрии окна, у лучей и прод.линий меняются углы. придется снова распутывать клубок и смотреть откуда грабли
ОтветитьУдалитьНе нравятся мне эти формулы с делениями. Помню, что в задачах по выч.геометрии старались избегать делений, а пользоваться только умножениями.
ОтветитьУдалитьВопрос номер 0: а числа в double-float или single-float? У single-float маленькая точность, что-то около 7-8 значащих десятичных знаков.
Что либо считать в момент рисования - ИМХО не правильно. считать нужно отдельно, рисовать отдельно - расход памяти, но без этого никакой производительности небудет.
ОтветитьУдалитьПри делении обязательно проверки на 0 и соответственно расчет вертикальных и горизонтальных прямых разными способами.
В атокаде нет ограничений зуммирования, вернее есть, но они снимаются регенерацией чертежа.
формулы кривые, это да. Надо поднимать школьную программу по геометрии. числа вроде в double-float. Кстати, а как это можно деление заменить умножением?
ОтветитьУдалить@Andrey в автокаде после регенерации по хитрому меняются координаты экрана. По этому артефактов не вылазит.
ОтветитьУдалить>>в автокаде после регенерации по хитрому меняются координаты экрана??
ОтветитьУдалитьв смысле?
точно не помню как вся эта кухня работает, но суперзум после регенерации не вызывает артефактов. по моему там перестают обращать внимание на элементы вне видимой области
ОтветитьУдалить>Кстати, а как это можно деление заменить умножением?
ОтветитьУдалитьПользоваться теми формулами/уравнениями, где деление не нужно. Например, вместо уравнения прямой y=kx+b использовать уравнение ax+by+c=0
Еще, раз уж используется лисп, то для произвольного зума имеет смысл вычисления делать в точной рациональной арифметике, а потом переводить в плавающую точку.
ax+by+c=0 и y=kx+b это одна и таже форма задание прямой. удобней использовать p=dx*t+dy*t, но от деления всеравно избавиться не получится - в этом случае на ноль не придется делить для вертикальных\горизонтальных прямых.
ОтветитьУдалить>>имеет смысл вычисления делать в точной рациональной арифметике
У вас погрешность не от плавающей точки, а от неправильной обработки изменения размеров окна.
описался - совместил векторную и невекторную формы и забыл постоянную чисть)), имел ввиду
ОтветитьУдалитьp=p1+(p2-p1)*t