Касательная к кривой - PullRequest
1 голос
/ 10 апреля 2020

Я новичок в кодировании, и у меня есть проблема, я хотел бы нарисовать программу, в которой есть кривая, но на данный момент у меня есть чертеж stati c, но я не знаю, как создать касательная линия на кривой благодаря его производной, когда мышь двигается ...

This is all I have for now
    void draw(){
      background(255);
       noFill();
       stroke(0);
       beginShape();
       for(float a=0; a < TWO_PI; a+=0.01) {
         float r=78;
         float x=sin (a);
         float y=(pow(cos(a),2)/(2-cos(a)))

Моя идея состояла в том, чтобы создать курсор, который перемещается по кривой, и каждый сгенерированный тима является собственным касательным.

ОГРОМНОЕ СПАСИБО !!!!!

1 Ответ

1 голос
/ 10 апреля 2020

Я рекомендую использовать 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);
    }
}
...