I'm having a difficult time emulating an 'eyeball' effect. I have an OvalShape
(as in PowerPack shape) and can constrain the movement to a specific x,y. However, I need a fresh eyes to help me out, I think I've been looking at it too long to make any sense of it.
The goal:
Emulate an eyeball movement experience by following the cursor position.
Specifics:
Cursor position is of PointToClient
type, ergo, it's relative to the form.
The object/shape is relative to a ShapeContainer
so MousePosition 10,10 will translate to EyePupil position 10,10 because the location is based on it's parent
Here's a synopsis:
Class
Dim MousePosition As Drawing.Point
.....Handles MyBase.Load
Dim ctrl As System.Windows.Forms.Control
For Each ctrl In Me.Controls
AddHandler ctrl.MouseMove, AddressOf OnMouseMoveHandler
Next
Dim canvas As New ShapeContainer
canvas.Parent = Me.EyeIcon
Me.EyePupilShape.Parent = canvas
Handling the events:
....OnMouseMoveHandler(..)
MousePosition = Me.PointToClient(Cursor.Position)
Debug.Print("Mouse position : X = " & MousePosition.X & ", " & MousePosition.Y)
Me.EyePupilShape.Location = New Drawing.Point(Clamp(MousePosition.X, 32, 50), Clamp(MousePosition.Y, 31, 50))
Where Clamp is just a custom version of MathHelper.clamp and the min/max values are where the 'pupil' of the eye should be constrained to within it's parent element
This works as in it confines the pupil to a specific x,y bounds
However, it doesn't 'follow' the cursor per sey. For example, if the cursor is on the bottom left, it doesn't recognize that, it's just based on x,y values, that's were I need help with what I have so far. For what it's worth I've gotten most of my info from MSDN
You need to take the angle to the mouse cursor into account, then calculate position on a unit circle based on that angle, and scale by radius of your "pupil movement area", adjusting for mouse position being inside the eye/pupil.
I wrote a sample in VB.NET, posted on Github.
Calculations are within the Eyeball.Pupil.Update(Point mouse)
function, which receives the mouse coordinates translated using PointToClient()
function, as in your case. Here's the code:
Public Sub Update(ByVal mouse As Point)
'Calculate angle to mouse position
Dim distanceVector = New PointF(mouse.X - _center.X, mouse.Y - _center.Y)
Dim angleToMouse = Math.Atan2(distanceVector.Y, distanceVector.X)
'If the mouse is within the movement radius, restrict movement
Dim absDistanceVector As PointF = distanceVector
If absDistanceVector.X < 0 Then absDistanceVector.X *= -1
If absDistanceVector.Y < 0 Then absDistanceVector.Y *= -1
'Calculate scale
Dim scale = New PointF(Math.Min(absDistanceVector.X, _movementRadius.X),
Math.Min(absDistanceVector.Y, _movementRadius.Y))
'Adjust X and Y of the pupil based on scaled vector to mouse cursor, offset by pupil origin
X = CType(Math.Cos(angleToMouse), Single) * scale.X + _center.X - BoundingBox.Width / 2
Y = CType(Math.Sin(angleToMouse), Single) * scale.Y + _center.Y - BoundingBox.Height / 2
End Sub