简体   繁体   中英

Orthogonal projection of a point onto a line in processing?

I have a line segment and a circle in my processing sketch. I want the center of the circle, point q, to find the closest point, p, on the line segment and the circle will move towards it. I'm not quite sure how to code this (in processing), so any suggestions would be great! Thanks! This is my code so far:

int xPos1 = 200;
int yPos1 = 200;
int xp1 = 50;
int yp1 = 50;
int xp2 = 350;
int yp2 = 50;

void setup() {
    size(400, 400); 
    strokeWeight(2);
    line(xp1, yp1, xp2, yp2);
    strokeWeight(1);
}

void draw() {
    drawCircle();
}

void drawCircle() {
    fill(50, 120, 120);
    //circle
    ellipse(xPos1, yPos1, 75, 75); 
    //circle center
    ellipse(xPos1, yPos1, 7, 7);  
    fill(255);
    text("Q", xPos1 + 15, yPos1 + 5);
    fill(50, 120, 120);
}

The projection of a point onto a line is as follows:

Start with a line of the form x = a + t * n and a point p.


The vector compontent representing the nearest point on the line from the point p is:

(a - p) - ((a - p) dot n)n

so we have: p + (a - p) - ((a - p) dot n)n

after some simplification we have: a - ((a - p) dot n)n


Note that ((a - p) dot n) n is the vector component that represents the position along the line from the nearest point to the beginning (ie from nearest point to p back to a)

Let's use PVector s to make life a bit easier.

PVector p = new PVector(200, 200);
PVector a = new PVector(50, 50);
PVector b = new PVector(350, 50);
PVector n = new PVector(350, 50); // |p2 - p1|

void setup() {
    size(400, 400); 
    strokeWeight(2);
    strokeWeight(1);

    // initialize our normalized (unit length) line direction
    n.sub(a);
    n.normalize();
}

void draw() {
    drawCircle();
}

PVector getNearestPointOnLine(PVector p, PVector a, PVector n){
    // the notation turns the computation inside out,
    // but this is equivalent to the above equation
    PVector q = PVector.mult(n, -PVector.sub(a, p).dot(n));
    q.add(a);
    return q;
}

void drawCircle() {
    // lets draw everything here where we can see it
    background(255, 255, 255);
    line(a.x, a.y, b.x, b.y);

    fill(50, 120, 120);
    //circle

    // NOTE: this may require hooking up a mouse move event handler
    p.x = mouseX;
    p.y = mouseY;
    PVector q = getNearestPointOnLine(p, a, n);

    ellipse(q.x, q.y, 75, 75); 
    //circle center
    ellipse(q.x, q.y, 7, 7);  
    fill(0); // make text visible on white background
    text("Q", q.x + 15, q.y + 5);
    //fill(50, 120, 120);
}

Reference: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM