| 网站首页 | JAVA文章 | AppServers | Web开发 | 应用开发 | 资源下载 | 论坛
    想学好编程,学好外语很重要  [enadd  2006年12月25日]        
设为首页 加入收藏 联系站长
您现在的位置: 编程笔记网 >> 应用开发 >> vb >> 图形 >> 文章正文
任意角度旋转图形            【字体:
任意角度旋转图形
作者:-    文章来源:-    点击数:    更新时间:2006-6-8

如果有一个图范围如下:

      P1+----------+ P2
        |          |
        |          |
        |          |
        |          |
        |          |
      P3+----------+ P4


我们以P3为轴,顺时针转某个角度,如果是NT的使用者,可以使用PlgBlt()这个API来完
成,如果是Win95那就没办法了,这里也提供 VB5.0进阶程式开发指南所用的方法来完成

PlgBlt()的第二个叁数是重点,它是指向POINTAPI的一个3个元素之阵列,代表图形旋转
之後的三个端点,也就是说顺时针转了某个角度後,P1->P1'  P2->P2'  P3->P3',这阵
列便是存P1' P2' P3'。 所以了,重点在於这三个点的取得,数学不好的我可真痛苦;
如果这三个点没有设好,那会产生一个变形的图,原本 PlgBlt()便是用来扭曲图形用的
,只是那三个点如果设好的话,刚好可以来旋转图。

PlgBlt(
    HDC  hdcDest,      // handle of destination device context
    CONST POINT *  lpPoint,  // vertices of destination parallelogram
    HDC  hdcSrc,      // handle of source device context
    int  nXSrc,      // x-coord. of upper-left corner of source rect.
    int  nYSrc,      // y-coord. of upper-left corner of source rect.
    int  nWidth,      // width of source rectangle
    int  nHeight,      // height of source rectangle
    HBITMAP  hbmMask,      // handle of bitmask
    int  xMask,      // x-coord. of upper-left corner of bitmask rect.
    int  yMask      // y-coord. of upper-left corner of bitmask
)

需2个Command Button  2个PictureBox,目的在Picture2画出旋转图
Option Explicit
Private Declare Function PlgBlt Lib "gdi32" (ByVal hdcDest As Long, _
	lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, _
	ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
	ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long
Private Type POINTAPI
	x As Long
	y As Long
End Type
Const pi = 3.14159265358979
Dim dThetaDeg As Double
'以下只适用於NT
Private Sub Command1_Click()
Dim pt(1 To 3) As POINTAPI, p4 As POINTAPI
Dim dx As Long, dy As Long
Dim i As Long, offsetX As Long, offsetY As Long
Dim sida As Double
Dim MaxX As Long, MaxY As Long, MinX As Long, MinY As Long

sida = dThetaDeg * pi / 180
dx = Me.ScaleX(Picture1.Picture.Width, vbHimetric, vbPixels)
dy = Me.ScaleX(Picture1.Picture.Height, vbHimetric, vbPixels)
pt(1).x = dy * Sin(sida)
pt(1).y = dy - dy * Cos(sida)
pt(2).x = pt(1).x + dx * Cos(sida)
pt(2).y = pt(1).y + dx * Sin(sida)
pt(3).x = 0: pt(3).y = dy

'p4不用在pt()之阵列,它是由pt(1)-pt(3)所推出
p4.x = pt(3).x + dx * Cos(sida)
p4.y = pt(3).y + dx * Sin(sida)

'以下的工作只是为了让旋转後的图在Picture2的中间显示
MaxX = IIf(pt(1).x > pt(2).x, pt(1).x, pt(2).x)
MaxX = IIf(MaxX > pt(3).x, MaxX, pt(3).x)
MaxX = IIf(MaxX > p4.x, MaxX, p4.x)
MinX = IIf(pt(1).x < pt(2).x, pt(1).x, pt(2).x)
MinX = IIf(MinX < pt(3).x, MinX, pt(3).x)
MinX = IIf(MinX < p4.x, MinX, p4.x)

MaxY = IIf(pt(1).y > pt(2).y, pt(1).y, pt(2).y)
MaxY = IIf(MaxY > pt(3).y, MaxY, pt(3).y)
MaxY = IIf(MaxY > p4.y, MaxY, p4.y)
MinY = IIf(pt(1).y < pt(2).y, pt(1).y, pt(2).y)
MinY = IIf(MinY < pt(3).y, MinY, pt(3).y)
MinY = IIf(MinY < p4.y, MinY, p4.y)
offsetX = (Picture2.ScaleWidth - MaxX + MinX) \ 2 - MinX
offsetY = (Picture2.ScaleHeight - (MaxY - MinY)) \ 2 - MinY
pt(1).x = pt(1).x + offsetX: pt(1).y = pt(1).y + offsetY
pt(2).x = pt(2).x + offsetX: pt(2).y = pt(2).y + offsetY
pt(3).x = pt(3).x + offsetX: pt(3).y = pt(3).y + offsetY

i = PlgBlt(Picture2.hDC, pt(1), Picture1.hDC, 0, 0, dx, dy, 0, 0, 0)
End Sub

'这个方式不管95/NT都可行,来自vb5程式设计进阶指南一书,但速度慢
Private Sub Command2_Click()
    Dim nX As Integer, nY As Integer
    Dim nX1 As Integer, nY1 As Integer
    Dim dX2 As Double, dY2 As Double
    Dim dX3 As Double, dY3 As Double

    Dim dThetaRad As Double

    'Compute angle in radians
    dThetaRad = -dThetaDeg * pi / 180
    'Set scale modes to pixels
    For nX = 0 To Picture2.ScaleWidth
	nX1 = nX - Picture2.ScaleWidth \ 2
	For nY = 0 To Picture2.ScaleHeight
	    nY1 = nY - Picture2.ScaleHeight \ 2
	    'Rotate picture by dThetaRad
	    dX2 = nX1 * Cos(-dThetaRad) + nY1 * Sin(-dThetaRad)
	    dY2 = nY1 * Cos(-dThetaRad) - nX1 * Sin(-dThetaRad)
	    'Translate to center of picture box
	    dX3 = dX2 + Picture1.ScaleWidth \ 2
	    dY3 = dY2 + Picture1.ScaleHeight \ 2
	    'If data point is in picOne, set its color in picTwo
	    If dX3 > 0 And dX3 < Picture1.ScaleWidth - 1 _
		And dY3 > 0 And dY3 < Picture1.ScaleHeight - 1 Then
		Picture2.PSet (nX, nY), Picture1.Point(dX3, dY3)
	    End If
	Next nY
    Next nX
End Sub

Private Sub Form_Load()
Picture1.ScaleMode = 3
Picture2.ScaleMode = 3
'设定旋转角度
dThetaDeg = 30
Set Picture1.Picture = LoadPicture("e:\cli.bmp")

End Sub

文章录入:enadd    责任编辑:enadd 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
  • 用VB编写DirectX7.0游戏(下…

  • 用VB编写DirectX7.0游戏(上…

  • 使用OLE DB和ADO调用返回记录…

  • 使用VB调用Oracle程序包内的…

  • VB中用ADO对象动态创建数据库…

  • fffff

  • 如何用MSComm Control传Bina…

  • MultiLink的WinSock Server程…

  • 用VB制作浏览器

  • 用VB编写网络寻呼机

  •   网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |