2016-12-18 17 views
0

私はPictureBoxとカスタム矩形を描画したWinFormsを使っています(顔検出)。今私は、指定された座標に矩形を描画し、長方形のサイズ変更と移動を可能にするコードを持っています。しかし、マウスを使って矩形を回転させる方法を知る必要があります。私はそれを変換する方法を知っていますが、マウスを使用してそれを行う方法ではありません。誰かがこれを助けてくれますか?ここでVB.Netマウスをクリックしてドラッグして矩形を回転させる方法

は、カスタム長方形のコードです:ここで

Imports System 
Imports System.Drawing 
Imports System.Windows.Forms 

Public Class UserRect 
    Private Enum PosSizableRect 
     UpMiddle 
     LeftMiddle 
     LeftBottom 
     LeftUp 
     RightUp 
     RightMiddle 
     RightBottom 
     BottomMiddle 
     None 
    End Enum 

    Private mPictureBox As PictureBox 

    Public rect As Rectangle 

    Public allowDeformingDuringMovement As Boolean 

    Private mIsClick As Boolean 

    Private mMove As Boolean 

    Private oldX As Integer 

    Private oldY As Integer 

    Private sizeNodeRect As Integer = 5 

    Private mBmp As Bitmap 

    Private nodeSelected As UserRect.PosSizableRect = UserRect.PosSizableRect.None 

    Private angle As Integer = 30 

    Public Sub New(r As Rectangle) 
     Me.rect = r 
     Me.mIsClick = False 
    End Sub 

    Public Sub Draw(g As Graphics) 
     g.DrawRectangle(New Pen(Color.Red), Me.rect) 
     For Each p As UserRect.PosSizableRect In [Enum].GetValues(GetType(UserRect.PosSizableRect)) 
      g.DrawRectangle(New Pen(Color.Red), Me.GetRect(p)) 
     Next 
    End Sub 

    Public Sub SetBitmapFile(filename As String) 
     Me.mBmp = New Bitmap(filename) 
    End Sub 

    Public Sub SetBitmap(bmp As Bitmap) 
     Me.mBmp = bmp 
    End Sub 

    Public Sub SetPictureBox(p As PictureBox) 
     Me.mPictureBox = p 
     AddHandler Me.mPictureBox.MouseDown, AddressOf Me.mPictureBox_MouseDown 
     AddHandler Me.mPictureBox.MouseUp, AddressOf Me.mPictureBox_MouseUp 
     AddHandler Me.mPictureBox.MouseMove, AddressOf Me.mPictureBox_MouseMove 
     AddHandler Me.mPictureBox.Paint, AddressOf Me.mPictureBox_Paint 
    End Sub 

    Private Sub mPictureBox_Paint(sender As Object, e As PaintEventArgs) 
     Try 
      Me.Draw(e.Graphics) 
     Catch ex As Exception 
      Console.WriteLine(ex.Message) 
     End Try 
    End Sub 

    Private Sub mPictureBox_MouseDown(sender As Object, e As MouseEventArgs) 
     Me.mIsClick = True 
     Me.nodeSelected = UserRect.PosSizableRect.None 
     Me.nodeSelected = Me.GetNodeSelectable(e.Location) 
     If Me.rect.Contains(New Point(e.X, e.Y)) Then 
      Me.mMove = True 
     End If 
     Me.oldX = e.X 
     Me.oldY = e.Y 
    End Sub 

    Private Sub mPictureBox_MouseUp(sender As Object, e As MouseEventArgs) 
     Me.mIsClick = False 
     Me.mMove = False 
    End Sub 

    Private Sub mPictureBox_MouseMove(sender As Object, e As MouseEventArgs) 
     Me.ChangeCursor(e.Location) 
     If Not Me.mIsClick Then 
      Return 
     End If 
     Dim rectangle As Rectangle = Me.rect 
     Select Case Me.nodeSelected 
      Case UserRect.PosSizableRect.UpMiddle 
       Me.rect.Y = Me.rect.Y + (e.Y - Me.oldY) 
       Me.rect.Height = Me.rect.Height - (e.Y - Me.oldY) 
      Case UserRect.PosSizableRect.LeftMiddle 
       Me.rect.X = Me.rect.X + (e.X - Me.oldX) 
       Me.rect.Width = Me.rect.Width - (e.X - Me.oldX) 
      Case UserRect.PosSizableRect.LeftBottom 
       Me.rect.Width = Me.rect.Width - (e.X - Me.oldX) 
       Me.rect.X = Me.rect.X + (e.X - Me.oldX) 
       Me.rect.Height = Me.rect.Height + (e.Y - Me.oldY) 
      Case UserRect.PosSizableRect.LeftUp 
       Me.rect.X = Me.rect.X + (e.X - Me.oldX) 
       Me.rect.Width = Me.rect.Width - (e.X - Me.oldX) 
       Me.rect.Y = Me.rect.Y + (e.Y - Me.oldY) 
       Me.rect.Height = Me.rect.Height - (e.Y - Me.oldY) 
      Case UserRect.PosSizableRect.RightUp 
       Me.rect.Width = Me.rect.Width + (e.X - Me.oldX) 
       Me.rect.Y = Me.rect.Y + (e.Y - Me.oldY) 
       Me.rect.Height = Me.rect.Height - (e.Y - Me.oldY) 
      Case UserRect.PosSizableRect.RightMiddle 
       Me.rect.Width = Me.rect.Width + (e.X - Me.oldX) 
      Case UserRect.PosSizableRect.RightBottom 
       Me.rect.Width = Me.rect.Width + (e.X - Me.oldX) 
       Me.rect.Height = Me.rect.Height + (e.Y - Me.oldY) 
      Case UserRect.PosSizableRect.BottomMiddle 
       Me.rect.Height = Me.rect.Height + (e.Y - Me.oldY) 
      Case Else 
       If Me.mMove Then 
        Me.rect.X = Me.rect.X + e.X - Me.oldX 
        Me.rect.Y = Me.rect.Y + e.Y - Me.oldY 
       End If 
     End Select 
     Me.oldX = e.X 
     Me.oldY = e.Y 
     If Me.rect.Width < 5 OrElse Me.rect.Height < 5 Then 
      Me.rect = rectangle 
     End If 
     Me.TestIfRectInsideArea() 
     Me.mPictureBox.Invalidate() 
    End Sub 

    Private Sub TestIfRectInsideArea() 
     If Me.rect.X < 0 Then 
      Me.rect.X = 0 
     End If 
     If Me.rect.Y < 0 Then 
      Me.rect.Y = 0 
     End If 
     If Me.rect.Width <= 0 Then 
      Me.rect.Width = 1 
     End If 
     If Me.rect.Height <= 0 Then 
      Me.rect.Height = 1 
     End If 
     If Me.rect.X + Me.rect.Width > Me.mPictureBox.Width Then 
      Me.rect.Width = Me.mPictureBox.Width - Me.rect.X - 1 
      If Not Me.allowDeformingDuringMovement Then 
       Me.mIsClick = False 
      End If 
     End If 
     If Me.rect.Y + Me.rect.Height > Me.mPictureBox.Height Then 
      Me.rect.Height = Me.mPictureBox.Height - Me.rect.Y - 1 
      If Not Me.allowDeformingDuringMovement Then 
       Me.mIsClick = False 
      End If 
     End If 
    End Sub 

    Private Function CreateRectSizableNode(x As Integer, y As Integer) As Rectangle 
     Return New Rectangle(x - Me.sizeNodeRect/2, y - Me.sizeNodeRect/2, Me.sizeNodeRect, Me.sizeNodeRect) 
    End Function 

    Private Function GetRect(p As UserRect.PosSizableRect) As Rectangle 
     Select Case p 
      Case UserRect.PosSizableRect.UpMiddle 
       Return Me.CreateRectSizableNode(Me.rect.X + Me.rect.Width/2, Me.rect.Y) 
      Case UserRect.PosSizableRect.LeftMiddle 
       Return Me.CreateRectSizableNode(Me.rect.X, Me.rect.Y + Me.rect.Height/2) 
      Case UserRect.PosSizableRect.LeftBottom 
       Return Me.CreateRectSizableNode(Me.rect.X, Me.rect.Y + Me.rect.Height) 
      Case UserRect.PosSizableRect.LeftUp 
       Return Me.CreateRectSizableNode(Me.rect.X, Me.rect.Y) 
      Case UserRect.PosSizableRect.RightUp 
       Return Me.CreateRectSizableNode(Me.rect.X + Me.rect.Width, Me.rect.Y) 
      Case UserRect.PosSizableRect.RightMiddle 
       Return Me.CreateRectSizableNode(Me.rect.X + Me.rect.Width, Me.rect.Y + Me.rect.Height/2) 
      Case UserRect.PosSizableRect.RightBottom 
       Return Me.CreateRectSizableNode(Me.rect.X + Me.rect.Width, Me.rect.Y + Me.rect.Height) 
      Case UserRect.PosSizableRect.BottomMiddle 
       Return Me.CreateRectSizableNode(Me.rect.X + Me.rect.Width/2, Me.rect.Y + Me.rect.Height) 
      Case Else 
       Return Nothing 
     End Select 
    End Function 

    Private Function GetNodeSelectable(p As Point) As UserRect.PosSizableRect 
     For Each posSizableRect As UserRect.PosSizableRect In [Enum].GetValues(GetType(UserRect.PosSizableRect)) 
      If Me.GetRect(posSizableRect).Contains(p) Then 
       Return posSizableRect 
      End If 
     Next 
     Return UserRect.PosSizableRect.None 
    End Function 

    Private Sub ChangeCursor(p As Point) 
     Me.mPictureBox.Cursor = Me.GetCursor(Me.GetNodeSelectable(p)) 
    End Sub 

    Private Function GetCursor(p As UserRect.PosSizableRect) As Cursor 
     Select Case p 
      Case UserRect.PosSizableRect.UpMiddle 
       Return Cursors.SizeNS 
      Case UserRect.PosSizableRect.LeftMiddle 
       Return Cursors.SizeWE 
      Case UserRect.PosSizableRect.LeftBottom 
       Return Cursors.SizeNESW 
      Case UserRect.PosSizableRect.LeftUp 
       Return Cursors.SizeNWSE 
      Case UserRect.PosSizableRect.RightUp 
       Return Cursors.SizeNESW 
      Case UserRect.PosSizableRect.RightMiddle 
       Return Cursors.SizeWE 
      Case UserRect.PosSizableRect.RightBottom 
       Return Cursors.SizeNWSE 
      Case UserRect.PosSizableRect.BottomMiddle 
       Return Cursors.SizeNS 
      Case Else 
       Return Cursors.[Default] 
     End Select 
    End Function 
End Class 
+0

を回転させた後、他のすべての単純な変換が異なって行われるべきであることに注意してください。例えば。水平軸はもはや通常のx方向に位置合わせされない。それで、あなたの現在のコードはこれが考慮されていないので、非常に変更が必要です! –

+0

どのように回転角度を増減したいかによって決まります。移動マウスの水平、垂直など –

答えて

1

はシナリオです:ダウン1回目の すると、ユーザプッシュマウス、チェック例えばCTRLキーもModifierKeys = Keys.Controlを押された場合、我々は回転を開始する必要があります(CTRLキーは移動と回転を区別するためのものです)。このために回転中心と回転量(回転角)を知る必要があります。矩形(面)の中心が回転の中心であると仮定できます。回転角度を見つけるために、我々はいくつかの計算を行う必要があります。

Dim a1, a2, delta as Double 
a1 = Math.Atan2(yA-yO, xA-xO) 
a2 = Math.Atan2(yB-yO, xB-xO) 
delta = a2 - a1 'this is the angle AOB (in radians) to be applied for rotation to all 4 points 

enter image description here

+0

ありがとう..しかし、私の数学は吸う。あなたはこれをコードで持っていますか? – Eminem

+0

私は実際のポイントA2ではなく、角度AOBを計算する方が良いと思います。残りの3点の座標を計算するのではなく、回転が簡単になります。 –

関連する問題