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

How to find point on the circumference of a circle from an angle

position 包含直径变量的圆心。 enemy.position是一个正方形的左上角是敌人,size是敌人的宽和高。 我在 java.

中使用 processing.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);

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

矩形和圆上的点可以通过中心点之间的偏移量与矩形大小的最小关系来计算。
在以下算法中,矩形由中心点 (rectCenter) 和大小 (size) 定义,圆由中心点 (circleCenter) 和半径 ( 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};
}

最小示例:

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