简体   繁体   English

使眼球看/跟随光标移动(C#)

[英]Making eyeball look at/follow cursor movement (C#)

I'm stuck here. 我被困在这里 I want to have the eyes drawn while 'looking' at (the angle of) the cursor. 我希望在“观察”光标的角度时画出眼睛。 Also, it should be contained within the bigger circle/quadrant (just like an eyeball). 此外,它应该包含在更大的圆/象限内(就像一个眼球)。 Sadly, it just won't draw the eye for me at the right position/angle and at every mouse movement. 可悲的是,它不会在正确的位置/角度和每次鼠标移动时吸引我。 The only thing it will do is initially draw an ellipse at (0,0), but that's not what I want. 它唯一要做的就是在(0,0)画一个椭圆,但这不是我想要的。

My idea is to calculate the ratio of the triangles with pythagorean theorem. 我的想法是用毕达哥拉斯定理计算三角形的比率。 Then apply the right coordinates (With the correct ratio) in the drawEllipse(); 然后在drawEllipse();应用正确的坐标(使用正确的比率drawEllipse(); method. 方法。 This should be repeated everytime you move the cursor. 每次移动光标时都应重复此操作。

You can check my image for the mathematical reasoning. 您可以检查我的图像以获得数学推理。 在此输入图像描述

Here is my code, note that the panel is made in the designer mode which isn't included in this code, but shouldn't be a big deal: 这是我的代码,请注意该面板是在设计器模式下制作的,该模式不包含在此代码中,但不应该是一个大问题:

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();
        }
    }
}

Try this out: 试试这个:

在此输入图像描述

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;
    }

}

If you want to have an eye following the cursor, you'll need to calculate the angle from the eye to the cursor. 如果你想要注意光标,你需要计算从眼睛到光标的角度。

You'll need to know just three things: 你需要知道三件事:

the position of the eye, the position of the mouse, and how far the center of the pupil is from the center of the eye (I'm calling your inner circle the pupil and outer circle the eye). 眼睛的位置,鼠标的位置,以及瞳孔中心距眼睛中心的距离(我称你的内圈为瞳孔,外圈为眼睛)。 Since the eye never moves (only rotates around it's center) you already know it's 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);
}

在此输入图像描述

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 could 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM