2015-07-18 3 views
3

Я застрял здесь. Я хочу, чтобы глаза были нарисованы, когда «смотрели» на (угол) курсора. Кроме того, он должен содержаться в большом круге/квадранте (точно так же, как глазное яблоко). К сожалению, это просто не привлечет глаз для меня в правильном положении/углу и при каждом движении мыши. Единственное, что он будет делать, это сначала нарисовать эллипс в (0,0), но это не то, что я хочу.Создание глазного яблока в/перемещение курсора (C#)

Моя идея - рассчитать отношение треугольников к теореме пифагора. Затем примените правильные координаты (с правильным соотношением) в методе drawEllipse();. Это нужно повторять каждый раз, когда вы перемещаете курсор.

Вы можете проверить мое изображение для математических рассуждений. enter image description here

Вот мой код, обратите внимание, что панель выполнена в режиме конструктора, который не входит в этом коде, но не должен быть большим делом:

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

Это все 2D? –

+0

Да. Просто 2D на панели. – carrotcake

ответ

3

Попробуйте это:

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

} 
+0

ah nice thx so much: D .. Только один вопрос, почему, почему угол (в getAngleInDegrees();) впоследствии вычитается на 90 в «RotateTransform ((float) angleRight - 90) и RotateTransform ((float) angleLeft - 90); "? – carrotcake

+0

Честно? ... было очень поздно, и я, вероятно, должен был уйти спать несколько часов назад. =) Я исправил код в приведенном выше редактировании. -90 был удален из события Paint(), и getAngleInDegrees() был изменен. Имея это в виду, все еще могут быть другие «не-оптимизации», оставленные там! –

2

Если вы хотите следите за курсором, вам нужно вычислить угол от глаза до курсора.

Вам нужно знать только три вещи:

положение глаз, положение мыши, и как далеко от центра зрачка от центра глаза (я звоню ваш внутренний круг - зрачок и внешний круг - глаз). Поскольку глаз никогда не перемещается (вращается только вокруг центра), вы уже знаете, что это позиция.

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 

вы можете использовать следующую

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

 Смежные вопросы

  • Нет связанных вопросов^_^