需要有关非重叠文本的帮助

Need assistance with non-overlapping text

我正在尝试创建彼此不重叠的随机文本。我真的是编码新手,我尝试使用 Shiffman 的非重叠圆圈教程走到这一步,但我仍然无法创建所需的输出,请帮忙。

var textFunc = [];

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

  // Lets make sure we don't get stuck in infinite loop
  var protection = 0;

  // Try to get to 500
  while (textFunc.length < 700) {
    // Pick a random Position
    var textDisp = {
      x: random(width),
      y: random(height)
    }

    // Does it overlap any previous circles?
    var overlapping = false;
    for (var j = 0; j < textFunc.length; j++) {
      var other = textFunc[j];
      var d = dist(textDisp.x, textDisp.y, other.x, other.y);
      if (d < textDisp.x && textDisp.x < other.y && other.y) {
        overlapping = true;
      }
    }

    // If not keep it!
    if (!overlapping) {
      textFunc.push(textDisp);
    }

    // Are we stuck?
    protection++;
    if (protection > 10000) {
      break;
    }
  }

  // Display all the Text
  for (var i = 0; i < textFunc.length; i++) {
    fill(random(255), random(100), random(0));
    noStroke();
    text('hahah', textFunc[i].x, textFunc[i].y);
  }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>

最小距离取决于文本的宽度和高度。半径是穿过文本覆盖区域的对角线长度的一半。对角线的长度可以通过Math.hypot():

来计算
diagonal = Math.hypot(width, height)

通过textSize()定义文本的高度(大小):

let textHeight = 12;
textSize(textHeight);

将文字添加到textDisp,通过textWidth()确定文字的宽度,计算半径:

let text = 'hahah'
let w = textWidth(text)
var textDisp = {
    x: random(width),
    y: random(height),
    t: text, 
    r: Math.hypot(w, textHeight) / 2
}

因此您可以计算半径并使用与 Ellipse No Overlap. 示例中相同的算法:

var d = dist(textDisp.x, textDisp.y, other.x, other.y);
if (d < textDisp.r + other.r) {
    overlapping = true;
}

要随机旋转文本,您需要添加一个随机角度 textDisp:

var textDisp = {
    // [...]
    a: random(180)-90,
    // [...]
}

使用translate() too move the center of the text to (0, 0). Rotate the text by rotate(), where radians() 将角度从度数转换为弧度。最后将文本移动到它的位置,按 translate().
push() respectively pop() 保存并恢复当前变换:

push();
translate(textFunc[i].x, textFunc[i].y);
rotate(radians(textFunc[i].a));
translate(-textWidth(textFunc[i].t)/2, textHeight/2);
text(textFunc[i].t, 0, 0);
pop();

看例子:

var textFunc = [];

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

    // Lets make sure we don't get stuck in infinite loop
    var protection = 0;

    let textHeight = 12;
    textSize(textHeight);
    
    // Try to get to 500
    while (textFunc.length < 700) {
        // Pick a random Position
        let text = 'hahah'
        let w = textWidth(text)
        var textDisp = {
            x: random(width),
            y: random(height),
            a: random(180)-90,
            t: text, 
            r: Math.hypot(w, textHeight) / 2
        }

        // Does it overlap any previous circles?
        var overlapping = false;
        for (var j = 0; j < textFunc.length; j++) {
            var other = textFunc[j];
            
            var d = dist(textDisp.x, textDisp.y, other.x, other.y);
            if (d < textDisp.r + other.r) {
                overlapping = true;
            }
        }

        // If not keep it!
        if (!overlapping) {
            textFunc.push(textDisp);
        }

        // Are we stuck?
        protection++;
        if (protection > 10000) {
            break;
        }
    }

    // Display all the Text
    for (var i = 0; i < textFunc.length; i++) {
        fill(random(255), random(100), random(0));
        noStroke();
        push();
        translate(textFunc[i].x, textFunc[i].y);
        rotate(radians(textFunc[i].a));
        translate(-textWidth(textFunc[i].t)/2, textHeight/2);
        text(textFunc[i].t, 0, 0);
        pop();
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>