怎样旋转矢量图形(100分)

  • 主题发起人 主题发起人 pyxyu
  • 开始时间 开始时间
P

pyxyu

Unregistered / Unconfirmed
GUEST, unregistred user!
知道的话,能给发个实例程序(pyxyu@126.com),谢了!
 
到www.delphiarea.com看看,有一控件可以做到
控件叫RotateImage
里面还有很多其他好东东哦
 
重新定义世界,用SetWorldTransform就可以了
 
上面的可是这方面的高手哦,
 
’爱元元的哥哥‘谢谢您的参与,能否发一个实例程序,简单的就行。
 
{ 旋转图像特效
输入参数:
Image 要进行旋转特效的TImage
Angle 旋转的角度(以度为单位,例如90表示旋转90度)
SleepTime 特效的快慢控制
}
procedure Img_Rotate(Image:TImage;Angle:Extended;SleepTime:Word);
var
c1x,c1y,c2x,c2y:Integer;
p1x,p1y,p2x,p2y:Integer;
radius,n:Integer;
alpha:Extended;
c0,c1,c2,c3:TColor;
OldBmp:TBitmap;
begin
OldBmp:=TBitmap.Create;
try
OldBmp.Assign(Image.Picture.Graphic);
Image.Picture:=nil;
angle:=(Angle/180)*PI; //将角度转换为PI值
// 计算中心点
c1x:=OldBmp.Width div 2;
c1y:=OldBmp.Height div 2;
c2x:=c1x;
c2y:=c1y;
// 步骤数值number
if c2x < c2y then n:=c2y
else n:=c2x;
Dec(n,1);
// 开始旋转
for p2x:=0 to n do
begin
for p2y:=0 to n do
begin
if p2x=0 then alpha:=PI/2
else alpha:=ArcTan2(p2y,p2x);
radius:=Round(Sqrt((p2x*p2x)+(p2y*p2y)));
p1x:=Round(radius*Cos(angle+alpha));
p1y:=Round(radius*Sin(angle+alpha));

c0:=OldBmp.Canvas.Pixels[c1x+p1x,c1y+p1y];
c1:=OldBmp.Canvas.Pixels[c1x-p1x,c1y-p1y];
c2:=OldBmp.Canvas.Pixels[c1x+p1y,c1y-p1x];
c3:=OldBmp.Canvas.Pixels[c1x-p1y,c1y+p1x];

Image.Canvas.Pixels[c2x+p2x,c2y+p2y]:=c0;
Image.Canvas.Pixels[c2x-p2x,c2y-p2y]:=c1;
Image.Canvas.Pixels[c2x+p2y,c2y-p2x]:=c2;
Image.Canvas.Pixels[c2x-p2y,c2y+p2x]:=c3;
Image.Refresh;
Sleep(SleepTime);
end;
end;
finally
OldBmp.Free;
end;
end;
 
楼上的代码需要math 单元,速度太慢了
 
楼上的,我是说的矢量图啊
 
将你的矢量图显示部分的代码贴出来,可以给你做一下。
 
这个和你自己的实现有关,因为矢量图画的过程中需要重新定义各个点,而旋转就是以某个点为原点,重新计算各个点的坐标
 
就是与平常的画法一样,如画距形
var
rc: TRect;
procedure TForm1.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
rc.Left := X; rc.Top := Y;
end;
procedure TForm1.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
rc.Right := X; rc.Bottom := Y;
Self.Canvas.Rectangle(rc);
end;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
rc.Right := X; rc.Bottom := Y;
Self.Canvas.Rectangle(rc);
end;
 
其实可以在重画的时候,整个bitmap旋转
 
重新定义世界,用SetWorldTransform就可以了
=======================》》》》》》》》》》》》》》》》》
这是在D3D中是这样的
 
真是答非所问。
矢量图的显示至少要有这两步:
1)将矢量图元(比如一个矩形)的所有点通过用户坐标到屏幕坐标点的转换。
2)将转换后的各点按顺序连起来。
旋转过程包含在第一步。由于旋转后矩形四个点移位,此时恐怕不能用Rectangle画旋转后的图形吧!
 
直接使用我们的产品吧

TCAD
http://www.codeidea.com
 
是在网上下载的那个画图程序吧.我也在想实现这个方法.
 
billwillman,爱元元的哥哥的思路是正确的,而且也是最简单的,本人也做过这样的程序,可以实现旋转、平移、缩放、镜像、拉伸等多种效果,而且对矢量字体也支持以上效果,但是并不象billwillman所说的那样需要D3D的支持,说穿了其实就是一个座标转换
 
procedure RotateWmf(AWmf: TMetaFile; const Angle: Double);

function CalAngle(PointX, PointY: Double): Double;
var
d1, d2, d3: Double;
begin
d1 := - PointX;
d2 := - PointY;
if d1 <> 0 then
begin
d3 := ArcTan(Abs(d2 / d1)) * 180 / PI;
if (d2 > 0) and (d1 < 0) then
d3 := 180 - d3
else if (d2 <= 0) and (d1 < 0) then
d3 := d3 + 180
else if (d2 < 0) and (d1 > 0) then
d3 := 360 - d3;
end
else
begin
if d2 > 0 then
d3 := 90
else if D2 < 0 then
d3 := 270
else
d3 := -1;
end;
Result := d3;
end;

var
d1, d2, d3, d4, d5, d6: Double;
pXf: XFORM;
RoMetafile: TMetafile;
RoMetafileCanvas: TMetafileCanvas;
R: TRect;
begin
if not Assigned(AWmf) or (Angle = 0) then
Exit;

if (AWmf.Width = 0) or
(AWmf.Height = 0) then
Exit;

with pXf do
begin
d3 := -Angle * PI / 180;
d1 := COS(d3);
d2 := SIN(d3);

eM11 := d1;
eM12 := d2;
eM21 := -d2;
eM22 := d1;

d4 := AWmf.Width / 2;
d5 := AWmf.Height / 2;

d3 :=CalAngle(d4, d5) -Angle;
d3 := -d3 * PI / 180;

d6 := sqrt(d4 * d4 + d5 * d5);
d1 := COS(d3) * d6 + d4;
d2 := -SIN(d3) * d6 + d5;

eDx := d1;
eDy := d2;
end;

RoMetafile := TMetafile.Create;
try
R := Rect(0, 0, AWmf.Width, AWmf.Height);
RoMetafile.Width := AWmf.Width;
RoMetafile.Height := AWmf.Height;

RoMetafileCanvas := TMetafileCanvas.Create(RoMetafile, 0);
try
SetGraphicsMode(AWmf.Handle, GM_COMPATIBLE);
SetGraphicsMode(RoMetafileCanvas.Handle, GM_ADVANCED);
SetWorldTransform(RoMetafileCanvas.Handle, pXf);
PlayEnhMetaFile(RoMetafileCanvas.Handle, AWmf.Handle, R);

finally
RoMetafileCanvas.Free;
end;

AWmf.Clear;
AWmf.Assign(RoMetafile);
finally
RoMetafile.Free;
end;
end;
 
多人接受答案了。
 
后退
顶部