Я рекомендую использовать PVector
для вычисления.
Создать функцию, которая вычисляет точку на форме:
PVector fSahpe(float a) {
float r = 200;
float x = r * sin(a);
float y = -r *(pow(cos(a),2)/(2-cos(a)));
return new PVector(x, y);
}
Вы должны найти точка на фигуре, которая ближе всего к положению мыши. Найти ближайшую точку, пока вы рисуете форму. Обратите внимание, что поскольку форма переведена, положение мыши, которое используется для сравнения положения мыши с точкой на фигуре, должно быть смещено в противоположном направлении:
PVector m = new PVector(mouseX-width/2, mouseY-height/2);
dist()
можно использовать для вычисления евклидова расстояния между 2 точками:
float mindist = 1000;
float mina = 0;
for(float a=0; a < TWO_PI; a+=0.01) {
PVector p = fSahpe(a);
// [...]
float dist = PVector.dist(p, m);
if (dist < mindist) {
mindist = dist;
mina = a;
}
}
Определить пороговое расстояние. Если расстояние от мыши до ближайшей точки на кривой падает ниже расстояния, нарисуйте касательную:
if (mindist < 10) {
// [...] draw tangent
}
Вычислите 2 точки на кривой, которые находятся близко друг к другу, где одна точка точка, ближайшая к курсору мыши:
PVector p0 = fSahpe(mina);
PVector p1 = fSahpe(mina+0.01);
Эти 2 точки находятся на аппроксимированной касательной. Вычислить вектор из одной точки в другую и масштабировать его до определенной длины (длина равна половине длины касательной):
PVector dir = PVector.sub(p1, p0);
dir.normalize().mult(100);
Вычислить начальную точку и конечную точку касательной:
PVector l0 = PVector.add(p0, dir);
PVector l1 = PVector.sub(p0, dir);
См. Полный пример:
void setup() {
size(500, 500);
}
PVector fSahpe(float a) {
float r = 200;
float x = r * sin(a);
float y = -r *(pow(cos(a),2)/(2-cos(a)));
return new PVector(x, y);
}
void draw(){
background(0);
translate(width/2, height/2);
noFill();
strokeWeight(1);
stroke(255);
float mindist = 1000;
float mina = 0;
PVector m = new PVector(mouseX-width/2, mouseY-height/2);
beginShape();
for(float a=0; a < TWO_PI; a+=0.01) {
PVector p = fSahpe(a);
vertex(p.x, p.y);
float dist = PVector.dist(p, m);
if (dist < mindist) {
mindist = dist;
mina = a;
}
}
endShape();
if (mindist < 10) {
PVector p0 = fSahpe(mina);
PVector p1 = fSahpe(mina+0.01);
PVector dir = PVector.sub(p1, p0);
dir.normalize().mult(100);
PVector l0 = PVector.add(p0, dir);
PVector l1 = PVector.sub(p0, dir);
strokeWeight(3);
stroke(255, 0, 0);
line(l0.x, l0.y, l1.x, l1.y);
}
}