Глаза в форме эллипса, следящие за мышкой. (Processing 3)
Для создания глаза был написан класс, содержащий в себе несколько параметров, определяющих эллипс:
Большая полуось
Малая полуось
Центр
Фокальное расстояние
Была поставлена задача определение положения курсора на экране, относительно области эллипса.
Я использовал одно из основных свойств эллипса: Сумма расстояний от любой точки эллипса до его фокусов есть величина постоянная и равная удвоенной большей полуоси.
Однако возникает следующая проблема: как сделать так, чтобы зрачок наблюдал за курсором, не пересекая границу глазного яблока (белка).
Решением было добавление дополнительного эллипса, который являлся "барьером" (границей) для зрачка, это можно понять так: чтобы зрачок не "закатывался" за поверхность белка.
И далее задача решается довольно просто:
внутри эллипса отрисовка зрачка будет происходить "классически"- на месте расположения курсора.
при расположении курсора вне границ "граничного" эллипса, я буду использовать переменные хранящие в себе положение курсора, затем по простой формуле разницы нужного и текущего, я буду смещать координату курсора, к центру эллипса.
как только координата уменьшится, будет выполнятся условие пункта (1) и зрачок будет отрисован на пересечении линии эллипса и прямой, соединяющей центр глаза и текущее положение курсора.
Коричневый - "белок" Белый - "граничный" эллипс Зеленый - "зрачок"

На (рис 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);
}