如何在 p5.js 中的圆弧段上添加标签?

How to add labels onto segments of a circle in p5.js?

我正在做一个 p5.js 的项目,我画一个圆,画圆弧(红色直线)来分隔圆,然后在每条红线(蓝线)之间画另一个圆弧。这个想法看起来像下面包含的图片:

我感到困惑的是如何在圆图中定位标签,以便它们位于圆内但在蓝色弧线外的每个段中。我的问题是如何为该图添加文本标签,使其看起来像下图?

到目前为止,这是生成第一张图片(没有标签的圆圈)的缩短代码:

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(255);
  let startX = 50;
  let startY = 50;
  
  let data = [1, 2, 3, 4];
  let width = 80;
  let angle = -Math.PI / 2;
  let radianPer = Math.PI * 2 / Object.keys(data).length;

  noStroke();
  fill(255);
  ellipse(startX, startY, width, width);
  Object.keys(data).forEach(i => {
      fill(255);
      stroke(255, 0, 0);
      arc(startX, startY, width, width, angle, angle + radianPer, PIE);
      fill(255);

      stroke(0, 0, 255);
      arc(startX, startY, width / 2, width / 2, angle, angle + radianPer, PIE);
      angle += radianPer;
    
      // add label here
  });
}

编辑 (02/05/22):更新代码以匹配屏幕截图示例。

在一段弧的中间显示标签涉及使用该弧的中间的角度以及正弦和余弦函数来找到 X 和 Y 坐标。有关详细信息,请参阅维基百科上的 trigonometric functions 文章。

function setup() {
  createCanvas(400, 400);

  // Text settings
  textAlign(CENTER, CENTER);
}

function draw() {
  background(255);
  let startX = 50;
  let startY = 50;

  let data = [1, 2, 3, 4];
  let width = 80;
  let angle = -Math.PI / 2;
  let radianPer = (Math.PI * 2) / Object.keys(data).length;

  noStroke();
  fill(255);
  ellipse(startX, startY, width, width);
  Object.keys(data).forEach((i) => {
    fill(255);
    stroke(255, 0, 0);
    arc(startX, startY, width, width, angle, angle + radianPer, PIE);
    fill(255);

    stroke(0, 0, 255);
    arc(startX, startY, width / 2, width / 2, angle, angle + radianPer, PIE);

    // add label here
    let textAngle = angle + radianPer / 2;

    // Use sine and cosine to determine the position for the text
    // Since sine is opposite / hypotenuse, taking the sine of the angle and
    // multiplying by distance gives us the vertical offset (i.e. the Y
    // coordinate).
    // Likewise with cosine for the X coordinate
    noStroke();
    fill(0);
    text(
      data[i].toString(),
      startX + cos(textAngle) * width / 2 * 0.75,
      startY + sin(textAngle) * width / 2 * 0.75
    );

    // Don't update angle until after calculating the angle for the label
    angle += radianPer;
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>