如何在处理中计算从 mouseX、mouseY 到矩形的 dist()

发布于 2024-10-19 01:34:00 字数 341 浏览 5 评论 0原文

如果它是到某个点的距离

dist(mouseX, mouseY, x, y)

point(x,y)

那么我如何计算从鼠标当前位置到

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

谢谢的距离()

If it was the dist to a point it would be

dist(mouseX, mouseY, x, y)

for

point(x,y)

but how can I calculate dist() from the mouse's current position to

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

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

杯别 2024-10-26 01:34:00

像这样的事情应该可以做到:

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

基本上,您需要弄清楚闭合点是在一侧还是在角落。这张图可能会有所帮助,它显示了点在不同位置处距矩形的距离:
在此处输入图像描述

Something like this should do it:

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

Basically, you need to figure out if the closes point is on one of the sides, or in the corner. This picture may help, it shows the distance of a point from a rectangle for different positions of the point:
enter image description here

别闹i 2024-10-26 01:34:00

这是一个有点交互式的程序,可以实现您正在寻找的内容。如果您愿意,可以将其放入“处理”中并运行它。

编辑:这是一个屏幕截图:

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

}

Here's a somewhat interactive program which accomplishes what you're looking for. You can drop it into Processing and run it if you would like.

EDIT: Here's a 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);

}
铁憨憨 2024-10-26 01:34:00

这就是我用的。如果您只对相对距离感兴趣,则可能不需要取平方根,这应该会稍微快一些。

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

This is what I use. If you are only interested in the relative distance there is probably no need to take the square root which should make it slightly quicker.

- (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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文