2011-02-25 4 views
5

czy to dist do punktu byłobyjak obliczyć dist() z mouseX, mouseY do prostokąta w przetwarzaniu

dist(mouseX, mouseY, x, y) 

dla

point(x,y) 

ale jak mogę obliczyć dist() od bieżącej pozycji myszy do

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

Dzięki

+0

Jeśli '(mouseX, mouseY)' znajduje się wewnątrz prostokąta, czy chcesz, aby odległość wynosiła 0? A może masz na myśli odległość do granicy prostokąta? –

+0

@Jeżeli byłaby to odległość do granicy prostokąta –

Odpowiedz

6

Coś jak to powinno zrobić:

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))); 
} 

Zasadniczo, trzeba dowiedzieć się, czy punkt zamyka się na jednej ze stron, albo w kącie. Ten obrazek może pomóc, pokazuje odległość punktu od prostokąta dla różnych pozycji punktu: enter image description here

+0

+1 Użyłem zagnieżdżonego min (min()) pomysłu, zamiast ustawiać min_dist, sprawdzając go przed temp min_dist, ustawiając nowy min_dist, itp. – gary

1

Oto nieco interaktywny program, który spełnia to, czego szukasz. Możesz upuścić go do Przetwarzania i uruchomić go, jeśli chcesz.

EDIT: Oto zrzut ekranu:

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

To właśnie używam. Jeśli interesuje Cię tylko względny dystans, prawdopodobnie nie musisz brać pierwiastka kwadratowego, który powinien uczynić go nieco szybszym.

- (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; 
} 
Powiązane problemy