Pull to refresh

Глаза в форме эллипса, следящие за мышкой. (Processing 3)

Для создания глаза был написан класс, содержащий в себе несколько параметров, определяющих эллипс:

  • Большая полуось

  • Малая полуось

  • Центр

  • Фокальное расстояние

Была поставлена задача определение положения курсора на экране, относительно области эллипса.

Я использовал одно из основных свойств эллипса: Сумма расстояний от любой точки эллипса до его фокусов есть величина постоянная и равная удвоенной большей полуоси.

Однако возникает следующая проблема: как сделать так, чтобы зрачок наблюдал за курсором, не пересекая границу глазного яблока (белка).

Решением было добавление дополнительного эллипса, который являлся "барьером" (границей) для зрачка, это можно понять так: чтобы зрачок не "закатывался" за поверхность белка.

И далее задача решается довольно просто:

  1. внутри эллипса отрисовка зрачка будет происходить "классически"- на месте расположения курсора.

  2. при расположении курсора вне границ "граничного" эллипса, я буду использовать переменные хранящие в себе положение курсора, затем по простой формуле разницы нужного и текущего, я буду смещать координату курсора, к центру эллипса.

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

    Коричневый - "белок" Белый - "граничный" эллипс Зеленый - "зрачок"
    Коричневый - "белок" Белый - "граничный" эллипс Зеленый - "зрачок"
(Рис 2) Для наглядности я отображаю "вспомогательные" линии.
(Рис 2) Для наглядности я отображаю "вспомогательные" линии.

На (рис 2) линии выходят из 2х фокусов и центра "граничных" эллипсов.


//// размеры экрана
//int shirina = 640;
//int visota = 360;

// для моего монитора 1024 
int shirina = 1920;
int visota = 1080;

class Ellipses {

  int el_height;
  int el_width;

  float a;  //большая полуось а
  int b;  //малая полуось b

  int cent_x; // центр эллипса
  int cent_y;

  int focusLeft; // фокусы
  int focusRight;

  int c;// фокальное расстояние с

  // координаты зрачка
  int pos_x, pos_y;

  Ellipses(int Ewidth, int Eheight, int centr_x, int centr_y) { // конструктор (запускается один раз при создании обьекта)

    el_height = Eheight;  //высота
    el_width = Ewidth;  //ширина

    a = Ewidth/2;
    b = Eheight/2;

    // центр по умолчанию width/2 height/2 (это ширина и высота экрана)
    cent_x = centr_x;//shirina/2;// width/2;
    cent_y = centr_y;//visota/2;//height/2;

    c = int(sqrt(pow(a, 2)-pow(b, 2))); // вместо pow можно sq()

    // координаты фокусов по x
    focusLeft = cent_x-c;
    focusRight = cent_x+c;
  }

  float Svvo() { //сумма фокусных расстояний
    float summ = sqrt( pow( (mouseX - focusLeft), 2)+ pow( (mouseY - cent_y), 2)) +
      + sqrt( pow( (mouseX - focusRight), 2)+ pow( (mouseY - cent_y), 2));
    return summ;
  }

  float DistFLeft(int mouse_X, int mouse_Y) { // от мышки, до левого фокуса
    float dist = sqrt( pow( (mouse_X - focusLeft), 2)+ pow( (mouse_Y - cent_y), 2));
    return dist;
  }

  float DistFRight(int mouse_X, int mouse_Y) { // от мышки до правого фокуса
    float dist = sqrt( pow( (mouse_X - focusLeft), 2)+ pow( (mouse_Y - cent_y), 2));
    sqrt( pow( (mouse_X - focusRight), 2)+ pow( (mouse_Y - cent_y), 2));
    return dist;
  }

  float SvvoWithParam(float mouse_X, float mouse_Y) { // сумма фокусных расстояний, но с параметром
    float summ = sqrt( pow( (mouse_X - focusLeft), 2)+ pow( (mouse_Y - cent_y), 2)) +
      + sqrt( pow( (mouse_X - focusRight), 2)+ pow( (mouse_Y - cent_y), 2));
    return summ;
  }

  void pos() {
    pos_x = mouseX;
    pos_y= mouseY;
  }
}

//параметры глаз
int sh=300;
int vis = 200;

// координаты глаза
int centr_eyex = shirina*3/9; 
int centr_eyey = visota/2;

Ellipses beloc = new Ellipses(sh, vis, centr_eyex, centr_eyey); // (ширина высота) эллипса (параметры глаза)
Ellipses zrachoc = new Ellipses(beloc.el_height/3, beloc.el_height/3, centr_eyex, centr_eyey);
Ellipses edge = new Ellipses(beloc.el_width - zrachoc.el_height, beloc.el_height - zrachoc.el_height, centr_eyex, centr_eyey);


// координаты глаза
int centr_eyex1 = shirina*6/9; 
int centr_eyey1 = visota/2;

Ellipses beloc1 = new Ellipses(sh, vis, centr_eyex1, centr_eyey1); // (ширина высота) эллипса (параметры глаза)
Ellipses zrachoc1 = new Ellipses(beloc.el_height/3, beloc.el_height/3, centr_eyex1, centr_eyey1);
Ellipses edge1 = new Ellipses(beloc.el_width - zrachoc.el_height, beloc.el_height - zrachoc.el_height, centr_eyex1, centr_eyey1);



void setup() {

  //size(640, 360);
  fullScreen();

  //shirina = 640;
  //visota = 360;

  //noStroke(); // без "обводки" если убрать, то перестанет рисовать line
}

void draw() {
  background(#9ec6b7);
  ellipseMode(CENTER);  // Set ellipseMode to RADIUS

  fill(#b47d4b);  // HUE

  ellipse(beloc.cent_x, beloc.cent_y, beloc.el_width, beloc.el_height); 

  fill(210, 255, 255);
  ellipse(edge.cent_x, edge.cent_y, edge.el_width, edge.el_height);

  float mouse_X = mouseX, mouse_Y = mouseY;
  float mouse_X1 = mouseX, mouse_Y1 = mouseY;

  while (edge.SvvoWithParam(mouse_X, mouse_Y)> edge.a*2) {
    mouse_X -= 0.01*(mouse_X-edge.cent_x);
    mouse_Y -= 0.01*(mouse_Y-edge.cent_y);
  }

  fill(#363d2b);
  ellipse(mouse_X, mouse_Y, zrachoc.el_height, zrachoc.el_height);

  line(mouseX, mouseY, edge.cent_x, edge.cent_y);
  line(mouse_X, mouse_Y, edge.focusRight, edge.cent_y);
  line(mouse_X, mouse_Y, edge.focusLeft, edge.cent_y);


  //------------------------------------------------------------------------------------------------
  fill(#b47d4b);  // HUE

  ellipse(beloc1.cent_x, beloc1.cent_y, beloc1.el_width, beloc1.el_height); 

  fill(210, 255, 255);
  ellipse(edge1.cent_x, edge1.cent_y, edge1.el_width, edge1.el_height);

  //float mouse_X1 = mouseX, mouse_Y1 = mouseY;

  while (edge1.SvvoWithParam(mouse_X1, mouse_Y1)> edge1.a*2) {
    mouse_X1 -= 0.01*(mouse_X1-edge1.cent_x);
    mouse_Y1 -= 0.01*(mouse_Y1-edge1.cent_y);
  }

  fill(#363d2b);
  ellipse(mouse_X1, mouse_Y1, zrachoc1.el_height, zrachoc1.el_height);

  line(mouseX, mouseY, edge1.cent_x, edge1.cent_y);
  line(mouse_X1, mouse_Y1, edge1.focusRight, edge1.cent_y);
  line(mouse_X1, mouse_Y1, edge1.focusLeft, edge1.cent_y);
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.