Как рассчитать dist () от mouseX, mouseY до прямоугольника в обработке - PullRequest
5 голосов
/ 25 февраля 2011

Если бы это было dist до точки, это было бы

dist(mouseX, mouseY, x, y)

для

point(x,y)

, но как я могу вычислить dist () из текущей позиции мыши в

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

Спасибо

Ответы [ 3 ]

6 голосов
/ 25 февраля 2011

Что-то вроде этого должно сделать это:

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

По сути, вам нужно выяснить, находится ли точка закрытия на одной из сторон или в углу.Это изображение может помочь, оно показывает расстояние от точки до прямоугольника для различных положений точки: enter image description here

1 голос
/ 25 февраля 2011

Вот несколько интерактивная программа, которая выполняет то, что вы ищете.Вы можете поместить его в «Обработка» и запустить его, если хотите.

РЕДАКТИРОВАТЬ: Вот снимок экрана:

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 голосов
/ 22 марта 2013

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

- (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;
}
...