如何从角度找到圆的圆周上的点

发布于 2025-01-30 18:57:11 字数 510 浏览 3 评论 0原文

位置保持直径变量的圆的中心。 敌人。位置是一个正方形的左上角,正方形是敌人,大小是敌人的宽度和高度。 我正在使用Java中的Procesing.core.papplet库中的PVECTOR和LINE()。

我要做的是从圈子到敌人绘制一条线。该线应该看起来像从敌人的中心向POS(圆圈的中心)开始,但停在圆形的表面上。据我所知,我在下面留下的代码有效,但仅在敌人位于玩家右边的情况下,否则,该线在圆形表面的位置被倒向另一侧

PVector riseRun = PVector.sub(position, enemy.position);
float angle = atan(riseRun.y/riseRun.x);
        
line(position.x + (cos(angle) * diameter/2), position.y + (sin(angle) * diameter/2), enemy.position.x + (enemy.size/2), enemy.position.y + enemy.size/2);

position holds the center of a circle with a diameter variable.
enemy.position is the top left corner of a square which is an enemy, size is the width and height of the enemy.
I am using pVector and line() from the processing.core.pApplet library in java.

What I'm trying to do is draw a line from the circle to an enemy. The line should look like it started from the centre of the enemy towards pos (centre of the circle) but stops on the surface of the circle. From what I can tell, the code I have left below works but only in cases where the enemy is to the right of the player, otherwise, the line's position on the surface of the circle is inverted to the other side,

PVector riseRun = PVector.sub(position, enemy.position);
float angle = atan(riseRun.y/riseRun.x);
        
line(position.x + (cos(angle) * diameter/2), position.y + (sin(angle) * diameter/2), enemy.position.x + (enemy.size/2), enemy.position.y + enemy.size/2);

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

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

发布评论

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

评论(1

请止步禁区 2025-02-06 18:57:11

您可以通过在圆形中心和矩形中心给出的直线上找到矩形上的点来找到矩形的侧面。

矩形和圆上的点可以通过中心点和矩形大小之间的偏移的最小关系来计算。
在以下算法中,矩形由中心点(Rectcenter)和大小(size)定义,并且圆由中心点定义(CircleCenter))和半径(半径):

PVector[] intersectRectangleCircle(PVector rectCenter, PVector size, PVector circleCenter, float radius) {
    
  PVector offset  = PVector.sub(circleCenter, rectCenter);
    if (offset.x == 0 && offset.y == 0)
        return null;
      
    float ratio;  
    if (offset.x == 0)   
        ratio = size.y / abs(offset.y);
    else if (offset.y == 0) 
        ratio = size.x / abs(offset.x);
    else
        ratio  = min(size.x / abs(offset.x), size.y / abs(offset.y));
    ratio *= 0.5;
    
    PVector p1 = PVector.add(rectCenter, PVector.mult(offset, ratio));
    offset.normalize();
    PVector p2 = PVector.sub(circleCenter, offset.mult(radius));
    return new PVector[]{p1, p2};
}

最小示例:

“”

void setup() {
    size(500, 500);
}

PVector[] intersectRectangleCircle(PVector rectCenter, PVector size, PVector circleCenter, float radius) {
    
  PVector offset  = PVector.sub(circleCenter, rectCenter);
    if (offset.x == 0 && offset.y == 0)
        return null;
      
    float ratio;  
    if (offset.x == 0)   
        ratio = size.y / abs(offset.y);
    else if (offset.y == 0) 
        ratio = size.x / abs(offset.x);
    else
        ratio  = min(size.x / abs(offset.x), size.y / abs(offset.y));
    ratio *= 0.5;
    
    PVector p1 = PVector.add(rectCenter, PVector.mult(offset, ratio));
    offset.normalize();
    PVector p2 = PVector.sub(circleCenter, offset.mult(radius));
    return new PVector[]{p1, p2};
}

void draw() {
    background(160);
    
    float sizeX = 150;
    float sizeY = 100;
    float rectX = width/2-sizeX/2;
    float rectY = height/2-sizeY/2;
    float radius = 50;
    float centerX = mouseX;
    float centerY = mouseY;
    
    PVector[] outerPoints = intersectRectangleCircle(
        new PVector(rectX+sizeX/2, rectY+sizeY/2),
        new PVector(sizeX, sizeY),
        new PVector(centerX, centerY),
        radius
    );
  
    noFill();
    strokeWeight(3);
    stroke(0, 128, 0);
    circle(centerX, centerY, radius*2);
    stroke(0, 0, 128);
    rect(rectX, rectY, sizeX, sizeY);
    
    if (outerPoints != null) {
         stroke(128, 0, 0);
         strokeWeight(1);
         line(rectX+sizeX/2, rectY+sizeY/2, centerX, centerY);
         stroke(255, 0, 0);
         strokeWeight(3);
         line(outerPoints[0].x, outerPoints[0].y, outerPoints[1].x, outerPoints[1].y);
         fill(128, 0, 0);
         circle(outerPoints[0].x, outerPoints[0].y, 8);
         circle(outerPoints[1].x, outerPoints[1].y, 8);
    }
}

You can find the side of the rectangle by finding the point on the rectangle that lies on the straight line given by the center of the circle and the center of the rectangle.

The point on the rectangle and the circle can be computed by the minimum relation of the offset between the center points and the size of the rectangle.
In the following algorithm, the rectangle is defined by the center point (rectCenter) and the size (size) and the circle is defined by the center point (circleCenter) and the radius (radius):

PVector[] intersectRectangleCircle(PVector rectCenter, PVector size, PVector circleCenter, float radius) {
    
  PVector offset  = PVector.sub(circleCenter, rectCenter);
    if (offset.x == 0 && offset.y == 0)
        return null;
      
    float ratio;  
    if (offset.x == 0)   
        ratio = size.y / abs(offset.y);
    else if (offset.y == 0) 
        ratio = size.x / abs(offset.x);
    else
        ratio  = min(size.x / abs(offset.x), size.y / abs(offset.y));
    ratio *= 0.5;
    
    PVector p1 = PVector.add(rectCenter, PVector.mult(offset, ratio));
    offset.normalize();
    PVector p2 = PVector.sub(circleCenter, offset.mult(radius));
    return new PVector[]{p1, p2};
}

Minimal example:

void setup() {
    size(500, 500);
}

PVector[] intersectRectangleCircle(PVector rectCenter, PVector size, PVector circleCenter, float radius) {
    
  PVector offset  = PVector.sub(circleCenter, rectCenter);
    if (offset.x == 0 && offset.y == 0)
        return null;
      
    float ratio;  
    if (offset.x == 0)   
        ratio = size.y / abs(offset.y);
    else if (offset.y == 0) 
        ratio = size.x / abs(offset.x);
    else
        ratio  = min(size.x / abs(offset.x), size.y / abs(offset.y));
    ratio *= 0.5;
    
    PVector p1 = PVector.add(rectCenter, PVector.mult(offset, ratio));
    offset.normalize();
    PVector p2 = PVector.sub(circleCenter, offset.mult(radius));
    return new PVector[]{p1, p2};
}

void draw() {
    background(160);
    
    float sizeX = 150;
    float sizeY = 100;
    float rectX = width/2-sizeX/2;
    float rectY = height/2-sizeY/2;
    float radius = 50;
    float centerX = mouseX;
    float centerY = mouseY;
    
    PVector[] outerPoints = intersectRectangleCircle(
        new PVector(rectX+sizeX/2, rectY+sizeY/2),
        new PVector(sizeX, sizeY),
        new PVector(centerX, centerY),
        radius
    );
  
    noFill();
    strokeWeight(3);
    stroke(0, 128, 0);
    circle(centerX, centerY, radius*2);
    stroke(0, 0, 128);
    rect(rectX, rectY, sizeX, sizeY);
    
    if (outerPoints != null) {
         stroke(128, 0, 0);
         strokeWeight(1);
         line(rectX+sizeX/2, rectY+sizeY/2, centerX, centerY);
         stroke(255, 0, 0);
         strokeWeight(3);
         line(outerPoints[0].x, outerPoints[0].y, outerPoints[1].x, outerPoints[1].y);
         fill(128, 0, 0);
         circle(outerPoints[0].x, outerPoints[0].y, 8);
         circle(outerPoints[1].x, outerPoints[1].y, 8);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文