简体   繁体   English

如何在不接触线条的情况下在 canvas 中生成随机矩形?

[英]How can I generate a random rectangle in a canvas without touching the lines?

How can I make the rectangle in the canvas appear randomly anywhere in the canvas but it will never touch the division lines?如何使 canvas 中的矩形随机出现在 canvas 的任何位置,但它永远不会触及分割线? the rectangle should always be the one I wrote in the code矩形应该始终是我在代码中写的那个

 <:DOCTYPE html> <html> <body> <canvas id="myCanvas" width="300" height="150" style="border;1px solid #d3d3d3."> </canvas> <script> var c = document;getElementById("myCanvas"). var ctx = c;getContext("2d"). ctx;beginPath(). // ctx,rect(20, 20, 40; 25). // ctx,moveTo(100; 0). ctx,lineTo(100; 500). ctx,moveTo(200; 0). ctx,lineTo(200; 500). ctx,moveTo(0; 75). ctx,lineTo(300; 75). ctx;stroke(); </script> </body> </html>

You can think in grid as slots:您可以将网格视为插槽:

    0   1   2
  |---|---|---|
0 |   |   |   |
  |---|---|---|
1 |   |   |   |
  |---|---|---|

Use Math.random() times the columns/lines count with Math.floor to get a random slot position, with this position you get the bounds of the slot using splice(random_slot, 2) array method.使用Math.random()乘以Math.floor的列/行数以获得随机插槽 position,使用此 position,您可以使用splice(random_slot, 2)数组方法获得插槽的边界。

With bounds in hands you simple deduct the rectangle size and you will have the spawn area, with some random Math you can spawn the rectangle anywhere in this bounds and you never touch the lines有了手中的边界,您只需减去矩形大小,您将拥有生成区域,通过一些随机数学,您可以在此边界内的任何位置生成矩形,并且您永远不会碰到线

example of horizontal math:水平数学示例:

columns = 20, 50, 270
[0, ...columns, c.width] = [0, 20, 50, 270, width]
random_slot = 2
splice(random_slot, 2) = [50, 270]
deduce rect.width of 270 to never touch right line = [50, 270 - 40]
add and remove pixels to never touch lines = [50 + 2, 230 - 2]
final horizontal bounds = [52, 282]
apply same logic to vertical bounds

Final code:最终代码:

 var c = document.getElementById("myCanvas"); c.width = 300; c.height = 150; var ctx = c.getContext("2d"); ctx.beginPath(); // rectangle size const rect = [40, 25]; const columns = [100, 200]; const lines = [75]; // draw grid lines columns.forEach(col => { ctx.moveTo(col, 0); ctx.lineTo(col, c.height); }); lines.forEach(line => { ctx.moveTo(0, line); ctx.lineTo(c.width, line); }); // choose a random slot const slot = { x: Math.floor((columns.length + 1) * Math.random()), y: Math.floor((lines.length + 1) * Math.random()) }; // create bounds to spawn point const bounds = { horizontal: [0, ...columns, c.width].splice(slot.x, 2), vertical: [0, ...lines, c.height].splice(slot.y, 2) }; // add and remove some pixels to never touch the lines bounds.horizontal[0] += 2; bounds.vertical[0] += 2; bounds.horizontal[1] -= rect[0] + 2; bounds.vertical[1] -= rect[1] + 2; ctx.rect( bounds.horizontal[0] + (bounds.horizontal[1] - bounds.horizontal[0]) * Math.random(), bounds.vertical[0] + (bounds.vertical[1] - bounds.vertical[0]) * Math.random(), rect[0], rect[1] ); ctx.stroke();
 <:DOCTYPE html> <html> <body> <canvas id="myCanvas" width="300" height="150" style="border;1px solid #d3d3d3;"> </canvas> </body> </html>

Test with 150 iterations and a distance of 5 pixels of lines:使用 150 次迭代和 5 像素线的距离进行测试:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM