Bringing the eyeball to / moving the cursor (C #)

I am stuck here. I want the eyes to be drawn when "looking" at the (corner of) the cursor. Also, it must be contained within a large circle / quadrant (just like the eyeball). Unfortunately it just won't draw the eye for me in the correct position / angle and with every mouse movement. The only thing it will do is draw an ellipse at (0,0) first, but that's not what I want.

My idea is to calculate the ratio of triangles to the Pythagorean theorem. Then apply the correct coordinates (with the correct ratio) in the method drawEllipse();

. This needs to be repeated every time you move the cursor.

You can check my image for mathematical reasoning. enter image description here

Here is my code, note that the panel is made in design mode, which is not included in this code, but shouldn't make a big difference:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace oogjes2
{
    public partial class Form1 : Form
    {
        public int mousex;
        public int mousey;

        public Form1()
        {
            InitializeComponent();
            panel1.Paint += paintpanel;
            panel1.MouseMove += panel1_MouseMove;     
        }

        //panel1 cover the screen from (0.0) and onwards,
        void panel1_MouseMove(object sender, MouseEventArgs mea)
        {
            int mousex = mea.X;
            int mousey = mea.Y;
        } 

        void paintpanel(object obj, PaintEventArgs pea)
        {
            Pen blackpen = new Pen(Color.Black, 3);

            // the black outer circle which doesnt move
            pea.Graphics.DrawEllipse(blackpen, -125, -125, 250, 250);

            // e = 63. Diagonal distance from (0,0) to starting point drawEllipse
            // factor = multiplication from mea.x and mea.y to the respective ex and ey of the small circle.
            // ey = factor * mousex (mea.X). Same for ex.

            float e = (float)Math.Sqrt(45 * 45 + 45 * 45); //=63
            float factor = (e / (float)Math.Sqrt(mousex * mousex + mousey * mousey));
            int ex = mousex * (int)factor;
            int ey = mousey * (int)factor;

            //  the eye that should be redrawn at every mousemovement
            pea.Graphics.DrawEllipse(blackpen, ex, ey, 50, 50);
            this.Invalidate();
        }
    }
}

      

+3


source to share


2 answers


Try the following:

enter image description here



public partial class Form1 : Form
{

    private Timer tmr;
    private int PupilRadius = 20;
    private int EyeBallRadius = 50;
    private int DistanceBetweenEyes = 20;

    public Form1()
    {
        InitializeComponent();
        this.panel1.Paint += panel1_Paint;

        tmr = new Timer();
        tmr.Interval = 100;
        tmr.Tick += tmr_Tick;
        tmr.Start();
    }

    void tmr_Tick(object sender, EventArgs e)
    {
        panel1.Invalidate();
    }

    void panel1_Paint(object sender, PaintEventArgs e)
    {
        Point center = new Point(panel1.ClientSize.Width / 2, panel1.ClientSize.Height / 2);
        Point LeftEyeCenter = new Point(center.X - EyeBallRadius - (DistanceBetweenEyes / 2), center.Y);
        Point RightEyeCenter = new Point(center.X + EyeBallRadius + (DistanceBetweenEyes / 2), center.Y);

        Rectangle rc = new Rectangle(LeftEyeCenter, new Size(1, 1));
        rc.Inflate(EyeBallRadius, EyeBallRadius);
        e.Graphics.DrawEllipse(Pens.Black, rc);

        rc = new Rectangle(RightEyeCenter, new Size(1, 1));
        rc.Inflate(EyeBallRadius, EyeBallRadius);
        e.Graphics.DrawEllipse(Pens.Black, rc);

        Point curPos = panel1.PointToClient(Cursor.Position);
        Double DistanceFromLeftEyeToCursor = getDistance(LeftEyeCenter.X, LeftEyeCenter.Y, curPos.X, curPos.Y);
        Double DistanceFromRightEyeToCursor = getDistance(RightEyeCenter.X, RightEyeCenter.Y, curPos.X, curPos.Y);
        double angleLeft = getAngleInDegrees(LeftEyeCenter.X, LeftEyeCenter.Y, curPos.X, curPos.Y);
        double angleRight = getAngleInDegrees(RightEyeCenter.X, RightEyeCenter.Y, curPos.X, curPos.Y);

        rc = new Rectangle(new Point(Math.Min((int)DistanceFromLeftEyeToCursor, EyeBallRadius - PupilRadius), 0), new Size(1, 1));
        rc.Inflate(PupilRadius, PupilRadius);
        e.Graphics.TranslateTransform(LeftEyeCenter.X, LeftEyeCenter.Y);
        e.Graphics.RotateTransform((float)angleLeft);
        e.Graphics.FillEllipse(Brushes.Blue, rc);

        rc = new Rectangle(new Point(Math.Min((int)DistanceFromRightEyeToCursor, EyeBallRadius - PupilRadius), 0), new Size(1, 1));
        rc.Inflate(PupilRadius, PupilRadius);
        e.Graphics.ResetTransform();
        e.Graphics.TranslateTransform(RightEyeCenter.X, RightEyeCenter.Y);
        e.Graphics.RotateTransform((float)angleRight);
        e.Graphics.FillEllipse(Brushes.Blue, rc);
    }

    private Double getDistance(int Ax, int Ay, int Bx, int By)
    {
        return Math.Sqrt(Math.Pow((Double)Ax - Bx, 2) + Math.Pow((Double)Ay - By, 2));
    }

    private Double getAngleInDegrees(int cx, int cy, int X, int Y)
    {
        // draw a line from the center of the circle
        // to the where the cursor is...
        // If the line points:
        // up = 0 degrees
        // right = 90 degrees
        // down = 180 degrees
        // left = 270 degrees

        Double angle;
        int dy = Y - cy;
        int dx = X - cx;
        if (dx == 0) // Straight up and down | avoid divide by zero error!
        {
            if (dy <= 0)
            {
                angle = 0;
            }
            else
            {
                angle = 180;
            }
        }
        else
        {
            angle = Math.Atan((Double)dy / (Double)dx);
            angle = angle * ((Double)180 / Math.PI);

            if (X <= cx)
            {
                angle = 180 + angle;
            }
        }

        return angle;
    }

}

      

+3


source


If you want the eye to follow the cursor, you need to calculate the angle from the eye to the cursor.

You only need to know three things:

eye position, mouse position, and distance from the center of the pupil to the center of the eye (I call your inner circle the pupil and the outer circle of the eyes). Since the eye never moves (only rotates around it in the center), you already know its position.

void direction_to_cursor(){
  float p = Math.sqrt((45 + r)*(45 + r)*2); // Distance from outer circle center to inner circle center
  // assuming you want the top left corner 63 away from 0, 0
  // r is radius of inner circle
  int x = mouseX - EyeX; // In your picture it looks like your eye is at 0,0
  int y = -(mouseY - EyeY); // inverted y axis (0 is at top)
  float dir = Math.atan2(x, y);
  int px = p * Math.cos(dir);   // x Center of inner circle
  int py = p * Math.cos(dir);   // y Center of inner circle
  px -= r;  // Get left x coordinate of circle
  py -= r;  // get right x coordinate of circle

  pea.Graphics.DrawEllipse(blackpen, px, py, 50, 50);
}

      



enter image description here

step1: Calculate distance from center of Eye to center of pupil
step2: Calculate x and y difference between the Mouse and Eye
step3: Calculate direction from eye to mouse.
step4: Calculate position of pupil from direction and distance from center of eye

      

you can use the following

void paintpanel(object obj, PaintEventArgs pea)
{
    Pen blackpen = new Pen(Color.Black, 3);
    pea.Graphics.DrawEllipse(blackpen, -125, -125, 250, 250);

    float p = Math.sqrt(2*70*70); // (45+25)*(45+25)+(45+25)*(45+25)
    float dir = Math.atan(y, x);
    int ex = Math.cos(dir) * p - 25;
    int ey = Math.sin(dir) * p - 25; 

    //  the eye that should be redrawn at every mousemovement
    pea.Graphics.DrawEllipse(blackpen, ex, ey, 50, 50);
    this.Invalidate();
}

      

+2


source







All Articles