Я не копался в коде, но могу немного помочь с матрицами (пункт 3).
Я предполагаю, что используются три основные матрицы преобразования: вращение, масштабирование и матрица перевода. Назовем их R, S и T соответственно.
Есть одна сложность в применении матриц к точке. Скажем, вы хотите перевести точку, а затем вращать вокруг центра происхождения. Другими словами, вы хотите применить вращение к эффекту перевода точки. Таким образом, матрицы будут применяться следующим образом:
R (T (P)) = R * T * P = S
Где * - умножение матриц. Обратите внимание, что порядок умноженных матриц меняется в зависимости от вашего намерения.
Однако, если вы хотите сделать обратное преобразование, кроме изменения порядка матриц, вы также должны оценить их обратные преобразования. Мы перевели точку, затем повернули - так что теперь мы повернем ее назад, а затем переведем обратно:
T ^ -1 (R ^ -1 (S)) = T ^ -1 * R ^ -1 * S = P
Обратите внимание, что вам не нужно вычислять обратное значение каждой матрицы, так как очевидно, что T ^ -1 (x) = T (-x), R ^ -1 (угол) = R (-угольник) и т. Д. , Однако вам придется вывести аргумент преобразования, что может быть непросто, если у вас есть доступ только к матрице преобразования.
Я предполагаю, что мировые координаты преобразуются в экранные координаты комбинацией матрицы перевода и масштабирования. Последний отвечает за «изменение единицы измерения» с мировых координат на пиксели с учетом коэффициента масштабирования всей сцены (и, возможно, DPI дисплея). Матрица перевода, с другой стороны, отражает панорамирование сцены и может применяться либо до, либо после матрицы масштабирования; в первом случае панорамирование сохраняется в мировых координатах, во втором - панорамирование в экранных координатах.
Я бы также предположил, что все преобразования объектов выполняются в мировых координатах (для меня это звучит удобнее, чем в экранных координатах). Таким образом, вы можете ожидать, что точка каждого объекта подвергается следующему преобразованию:
W (S (R (T (P)))) = W * S * R * T * P,
где W - преобразование "Мир в экран", S - масштаб, R - поворот, а T - перевод.
Надеюсь, я хоть немного помог ...
<ч />
Обновлено 17-04-2011
Хорошо, я сейчас заглянул внутрь кода. Метод PaintTo объекта SVG выглядит следующим образом:
procedure TSVG.PaintTo(Graphics: TGPGraphics; Bounds: TGPRectF;
Rects: PRectArray; RectCount: Integer);
var
M: TGPMatrix;
MA: TMatrixArray;
begin
M := TGPMatrix.Create;
try
Graphics.GetTransform(M);
try
M.GetElements(MA);
FInitialMatrix.Cells[0, 0] := MA[0];
FInitialMatrix.Cells[0, 1] := MA[1];
FInitialMatrix.Cells[1, 0] := MA[2];
FInitialMatrix.Cells[1, 1] := MA[3];
FInitialMatrix.Cells[2, 0] := MA[4];
FInitialMatrix.Cells[2, 1] := MA[5];
FInitialMatrix.Cells[2, 2] := 1;
SetBounds(Bounds);
Paint(Graphics, Rects, RectCount);
finally
Graphics.SetTransform(M);
end;
finally
M.Free;
end;
end;
Перед любым рисованием метод вызывает Graphics.GetTransform (M). Этот, в свою очередь, вызывает GdipGetWorldTransform, который, по-видимому, является функцией-оболочкой для WinAPI GetWorldTransform .
.
Полагаю, это может быть хорошее место для старта :) 1038 *