Задача написать код для перемещения центра оси координат в центр TCanvas
данный материал написан на основе http://www.frolov-lib.ru/books/bsp/v14/ch2_2.htm
Приступим
Метрические режимы отображения
Режим MM_LOMETRIC , наряду с режимами MM_HIMETRIC , MM_LOENGLISH , MM_HIENGLISH и MM_TWIPS, относится к метрическим режимам. Эти режимы отображения позволяют использовать привычные единицы измерения, такие как миллиметры и дюймы.
В метрических режимах отображения используются полные формулы преобразования координат, приведенные выше в разделе "Преобразование координат". В этих формулах приложение может изменять переменные, определяющие смещение начала физической или логической системы координат xViewOrg, yViewOrg, xWinOrg и yWinOrg.
Приложение не может изменить значения переменных xViewExt, yViewExt, xWinExt и yWinExt, от которых зависит масштаб по осям координат. Отношения xViewExt/xWinExt и yViewExt/yWinExt имеют фиксированное значение для каждого из метрических режимов отображения.
Заметим, что для этих режимов отношение yViewExt/yWinExt имеет отрицательный знак, в результате чего ось Y оказывается направленной снизу вверх.
Обратим ваше внимание на одно важное обстоятельство, связанное с использованием метрических режимов отображения.
Сразу после переключения в метрический режим отображения система координат примет достаточно странный вид (рис. 1).
Ось X, как и следовало ожидать, окажется направленной слева направо, а ось Y - снизу вверх. Точка с координатами (0,0) будет находиться в верхнем левом углу экрана, поэтому для того чтобы нарисовать что-нибудь в такой системе координат, вам придется для y-координаты графических объектов использовать отрицательные числа. Для того чтобы система координат приняла более удобный вид, можно переместить начало физических координат в нижний левый угол окна или в центр окна.
Для того чтобы расположить начало координат в левом нижнем углу окна, следует вызвать функцию SetViewportOrg, передав ей новые координаты начала физической системы координат (0,cyClient):
SetViewportOrg(hdc, 0, cyClient);
Полученная в результате система координат показана на рис. 2
Рис. 2. Метрическая система координат,
начало координат находится в левом нижнем углу
окна
Аналогичным образом можно расположить начало
системы координат в середине окна (рис. 3),
обеспечив возможность использования
положительных и отрицательных координат вдоль
оси X и Y:
приведем пример функции для TCanvas
winAPI SetViewportOrg(hdc, cxClient/2, cyClient/2); SetViewportOrgEx(form1.Image1.Canvas.Handle, form1.Image1.Width div 2 , form1.Image1.Height div 2 , nil);
Рис. 3. Метрическая система координат, начало координат находится в центре окна
пример кода на Delphi для Image1.canvas
uses math; // для функции ugol:=arctan2(((y2-y1)),((x2-x1)))-pi;
// переводим координаты в центр SetMapMode(form1.image1.canvas.handle, MM_LOMETRIC); SetViewportOrgEx(form1.Image1.Canvas.Handle,form1.Image1.Width div 2 , form1.Image1.Height div 2 , nil);
Function Dlina(a,b:Tpoint):real; // находим расстояние между двумя точками var x1,y1,x2,y2:real; begin x1:=a.x; y1:=a.y; x2:=b.x; y2:=b.y; result:=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)) end; // Функция обрисовки стрелки по координатам на Паскале / Delphi
// для работы функции необходимо подключить модуль Math // все замечания и предложения писать в аську 368254335 Procedure DrawStrelka_Sh(Cn:Tcanvas;x1,y1,x2,y2:integer;fhs:integer=25;a:integer=30;Sh:integer=55;fhs2:integer=10); var ugol:real; i:integer; rx,ry:integer; begin Cn.MoveTo(x1,y1); Cn.LineTo(x2,y2); if (abs(x2-x1)+abs(y1-y2))>0 then begin ugol:=arctan2(((y2-y1)),((x2-x1)))-pi; Cn.LineTo(round((x2+(cos(ugol-a*pi/180)*fhs))),round(y2+(sin(ugol-a*pi/180)*fhs))); Cn.MoveTo(x2,y2); Cn.LineTo(round((x2+(cos(ugol+a*pi/180)*fhs))),round(y2+(sin(ugol+a*pi/180)*fhs))); ugol:=ugol+pi; fhs:=fhs2; for i:=0 to (Round(dlina(point(x1,y1),point(x2,y2))) div sh)-1 do begin rx:=round(x1+cos(ugol)*i*sh); ry:=round(y1+sin(ugol)*i*sh); Cn.Ellipse(rx-2,ry-2,rx+2,ry+2); // выводим точку Cn.MoveTo(rx,ry); Cn.LineTo(round((rx+(cos(ugol-pi/2)*fhs))),round(ry+(sin(ugol-pi/2)*fhs))); Cn.MoveTo(rx,ry); Cn.LineTo(round((rx+(cos(ugol+pi/2)*fhs))),round(ry+(sin(ugol+pi/2)*fhs))); if abs(x2-x1)>abs(y2-y1) then begin Cn.TextOut(rx,ry-fhs2-Cn.TextHeight(inttostr(rx)),inttostr(rx)); end
else begin if (ry>60) or (ry<-60) then Cn.TextOut(rx-fhs2-Cn.TextWidth(inttostr((ry))),ry,inttostr(ry)) end;
end; end; end;
успехов в работе над вашими проектами
|