2011-02-25 8 views
5

Se era il dist ad un punto sarebbecome calcolare la dist() da mouseX, mouseY ad un rettangolo in Processing

dist(mouseX, mouseY, x, y) 

per

point(x,y) 

ma come posso calcolare dist() dalla posizione corrente del mouse per

rectMode(CORNERS); 
rect(x1,y2,x2,y2); 

Grazie

+0

Se '(mouseX, mouseYY)' si trova nel rettangolo, vuoi che la distanza sia 0? O intendi la distanza dal confine del rettangolo? –

+0

@Jan sarebbe la distanza dal limite del rettangolo –

risposta

6

Qualcosa del genere dovrebbe farlo:

float distrect(float x, float y, float x1, float y1, float x2, float y2){ 
    float dx1 = x - x1; 
    float dx2 = x - x2; 
    float dy1 = y - y1; 
    float dy2 = y - y2; 

    if (dx1*dx2 < 0) { // x is between x1 and x2 
    if (dy1*dy2 < 0) { // (x,y) is inside the rectangle 
     return min(min(abs(dx1), abs(dx2)),min(abs(dy1),abs(dy2))); 
    } 
    return min(abs(dy1),abs(dy2)); 
    } 
    if (dy1*dy2 < 0) { // y is between y1 and y2 
    // we don't have to test for being inside the rectangle, it's already tested. 
    return min(abs(dx1),abs(dx2)); 
    } 
    return min(min(dist(x,y,x1,y1),dist(x,y,x2,y2)),min(dist(x,y,x1,y2),dist(x,y,x2,y1))); 
} 

In sostanza, è necessario capire se il punto chiude è su uno dei lati, o in un angolo. Questa immagine può aiutare, mostra la distanza di un punto da un rettangolo per diverse posizioni del punto: enter image description here

+0

+1 Ho usato la tua idea nidificata min (min()) piuttosto che impostare min_dist, controllandola contro un min_dist temporaneo, impostando un nuovo min_dist, ecc. – gary

1

Ecco un programma un po 'interattivo che realizza ciò che stai cercando. Puoi lasciarlo in Processing ed eseguirlo se vuoi.

EDIT: Ecco uno screenshot:

rectangleDistance.pde

// Declare vars. 
int x_click = -20;  // Initializes circle and point off-screen (drawn when draw executes) 
int y_click = -20; 
float temp = 0.0; 
float min_dist = 0.0; 
int x1, x2, x3, x4, y1, y2, y3, y4; 

// Setup loop. 
void setup() { 
    size(400, 400); 

// Calculate the points of a 40x40 centered rectangle 
    x1 = width/2 - 20; 
    y1 = height/2 - 20; 
    x2 = width/2 + 20; 
    y2 = y1; 
    x3 = x1; 
    y3 = height/2 + 20; 
    x4 = x2; 
    y4 = y3; 
} 


// Draw loop. 
void draw(){ 
    background(255); 

    // Draws a purple rectangle in the center of the screen. 
    rectMode(CENTER); 
    fill(154, 102, 200); 
    rect(width/2, height/2, 40, 40); 

    // Draws an orange circle where the user last clicked. 
    ellipseMode(CENTER); 
    fill(204, 102, 0); 
    ellipse(x_click, y_click, 10, 10); 

    // Draws black point where the user last clicked. 
    fill(0); 
    point(x_click, y_click); 

    // Draws min dist onscreen. 
    textAlign(CENTER); 
    fill(0); 
    text("min dist = " + min_dist, width/2, height/2 + 150); 
} 


void mousePressed(){ 
    x_click = mouseX; 
    y_click = mouseY; 

    // If the click isn't perpendicular to any side of the rectangle, the min dist is a corner. 
    if (((x_click <= x1) || (x_click >= x2)) && ((y_click <= y1) || (y_click >= y3)) ) { 
    min_dist = min(min(dist(x1,y1,x_click,y_click),dist(x2,y2,x_click,y_click)), min(dist(x3,y3,x_click,y_click),dist(x4,y4,x_click,y_click))); 

    } else if((x_click > x1) && (x_click < x2) && ((y_click < y1) || (y_click > y3))) { 
    // outside of box, closer to top or bottom 
    min_dist = min(abs(y_click - y1), abs(y_click - y3)); 

    } else if((y_click > y1) && (y_click < y3) && ((x_click < x1) || (x_click > x2))) { 
    // outside of box, closer to right left 
    min_dist = min(abs(x_click - x1), abs(x_click - x2)); 
    } else { 
    // inside of box, check against all boundaries 
    min_dist = min(min(abs(y_click - y1), abs(y_click - y3)),min(abs(x_click - x1), abs(x_click - x2))); 
    } 
    // Print to console for debugging. 
    //println("minimum distance = " + min_dist); 

} 
0

Questo è quello che uso. Se sei interessato solo alla distanza relativa, probabilmente non è necessario prendere la radice quadrata che dovrebbe renderla leggermente più veloce.

- (NSInteger) distanceFromRect: (CGPoint) aPoint rect: (CGRect) aRect 
{ 
    NSInteger posX = aPoint.x; 
    NSInteger posY = aPoint.y; 

    NSInteger leftEdge = aRect.origin.x; 
    NSInteger rightEdge = aRect.origin.x + aRect.size.width; 

    NSInteger topEdge = aRect.origin.y; 
    NSInteger bottomEdge = aRect.origin.y + aRect.size.height; 

    NSInteger deltaX = 0; 
    NSInteger deltaY = 0; 

    if (posX < leftEdge)  deltaX = leftEdge - posX; 
    else if (posX > rightEdge) deltaX = posX - rightEdge; 

    if (posY < topEdge)   deltaY = topEdge - posY; 
    else if (posY > bottomEdge) deltaY = posY - bottomEdge; 

    NSInteger distance = sqrt(deltaX * deltaX + deltaY * deltaY); 

    return distance; 
} 
Problemi correlati