首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于值在模具上生成pips

基于值在模具上生成pips
EN

Software Engineering用户
提问于 2016-02-25 19:40:17
回答 2查看 277关注 0票数 2

是否有一种算法来生成骰子或多米诺骨牌上的点?

我知道,通常有奇数的列和偶数的行数(除非最大的pips数不是一个完美的根)。

在这个时候,我有一个查找地图,其中存储了点在脸上的位置,根据计数。如果您想看到下面代码的运行示例,可以尝试使用论JSFiddle

代码语言:javascript
复制
var faces = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 1, 0, 0, 0, 0],
  [0, 0, 1, 0, 0, 0, 1, 0, 0],
  [0, 0, 1, 0, 1, 0, 1, 0, 0],
  [1, 0, 1, 0, 0, 0, 1, 0, 1],
  [1, 0, 1, 0, 1, 0, 1, 0, 1],
  [1, 0, 1, 1, 0, 1, 1, 0, 1],
  [1, 0, 1, 1, 1, 1, 1, 0, 1],
  [1, 1, 1, 1, 0, 1, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1, 1]
];

// Main method
(function() {
  var rows = 3;
  var columns = 3;
  var canvasList = document.querySelectorAll('canvas[id^="die-"]');
  for (var i = 0; i < canvasList.length; i++) {
    drawDie(canvasList[i].getContext('2d'), i, faces, rows, columns);
  }
}());

function drawDie(context, count, faces, rows, columns) {
  var width = context.canvas.clientWidth;
  var height = context.canvas.clientHeight;
  drawBackground(context, width, height);
  if (count > 0) {
    drawPips(context, width, height, count, faces, rows, columns);
  }
}

function drawBackground(context, width, height) {
  context.fillStyle = '#FFFFFF';
  context.strokeStyle = '#FF0000';
  roundRect(context, 0, 0, width, height, width * 0.2, true, true);
}

function drawPips(context, width, height, count, faces, rows, columns) {
  var x = measure(width, columns, 0.05);
  var y = measure(height, rows, 0.05);
  var radius = Math.min(x.off, y.off) * 0.33;
  var hue = randRange(0, 360);
  var fill = hslToHex(hue, 0.85, 0.55);
  var stroke = hslToHex(hue, 0.85, 0.33);
  var pipMap = faces[count];
  var index = 0;

  for (var yPos = y.start; yPos < y.avail; yPos += y.off) {
    for (var xPos = x.start; xPos < x.avail; xPos += x.off) {
      if (pipMap[index++] === 1) {
        drawPip(context, xPos, yPos, radius, fill, stroke);
      }
    }
  }
}

function drawPip(context, x, y, radius, fill, stroke) {
  context.beginPath();
  context.arc(x, y, radius, 0, 2 * Math.PI, false);
  context.fillStyle = fill;
  context.fill();
  context.lineWidth = 2;
  context.strokeStyle = stroke;
  context.stroke();
}

// http://stackoverflow.com/a/3368118/1762224
function roundRect(ctx, x, y, width, height, radius, fill, stroke) {
  if (typeof stroke == 'undefined') stroke = true;
  if (typeof radius === 'undefined') radius = 5;
  if (typeof radius === 'number') {
    radius = {
      tl: radius,
      tr: radius,
      br: radius,
      bl: radius
    };
  } else {
    var defaultRadius = {
      tl: 0,
      tr: 0,
      br: 0,
      bl: 0
    };
    for (var side in defaultRadius) {
      radius[side] = radius[side] || defaultRadius[side];
    }
  }
  ctx.beginPath();
  ctx.moveTo(x + radius.tl, y);
  ctx.lineTo(x + width - radius.tr, y);
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
  ctx.lineTo(x + width, y + height - radius.br);
  ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
  ctx.lineTo(x + radius.bl, y + height);
  ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
  ctx.lineTo(x, y + radius.tl);
  ctx.quadraticCurveTo(x, y, x + radius.tl, y);
  ctx.closePath();
  if (fill) ctx.fill();
  if (stroke) ctx.stroke();
}

function measure(length, partitions, inset) {
  var pad = length * inset;
  var avail = length - (pad * 2);
  var off = avail / partitions;
  var start = pad + (off / 2);

  return {
    length: length,
    pad: pad,
    avail: avail,
    off: off,
    start: start
  };
}

function hslToRgb(h, s, l) {
  var m1, m2, hue;
  var r, g, b
  if (s == 0) r = g = b = (l * 255);
  else {
    if (l <= 0.5) m2 = l * (s + 1);
    else m2 = l + s - l * s;
    m1 = l * 2 - m2;
    hue = h / 360;
    r = Math.round(hueToRgb(m1, m2, hue + 1 / 3));
    g = Math.round(hueToRgb(m1, m2, hue));
    b = Math.round(hueToRgb(m1, m2, hue - 1 / 3));
  }
  return [r, g, b];
}

function hueToRgb(m1, m2, hue) {
  var v;
  if (hue < 0) hue += 1;
  else if (hue > 1) hue -= 1;

  if (6 * hue < 1) v = m1 + (m2 - m1) * hue * 6;
  else if (2 * hue < 1) v = m2;
  else if (3 * hue < 2) v = m1 + (m2 - m1) * (2 / 3 - hue) * 6;
  else v = m1;

  return 255 * v;
}

function rgbToHex(r, g, b) {
  return '#' + [].slice.apply(arguments).map(function(c) {
    return (function(hex) {
      return hex.length === 1 ? '0' + hex : hex;
    }(Math.floor(c).toString(16)));
  }).join('');
}

function hslToHex(h, s, l) {
  return rgbToHex.apply(null, hslToRgb.apply(null, arguments));
}

function randRange(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
代码语言:javascript
复制
<canvas id="die-0" width="124" height="124"></canvas>
<canvas id="die-1" width="124" height="124"></canvas>
<canvas id="die-2" width="124" height="124"></canvas>
<canvas id="die-3" width="124" height="124"></canvas>
<canvas id="die-4" width="124" height="124"></canvas>
<canvas id="die-5" width="124" height="124"></canvas>
<canvas id="die-6" width="124" height="124"></canvas>
<canvas id="die-7" width="124" height="124"></canvas>
<canvas id="die-8" width="124" height="124"></canvas>
<canvas id="die-9" width="124" height="124"></canvas>
EN

回答 2

Software Engineering用户

发布于 2016-02-25 20:16:44

如果只考虑偶数值,算法就会变得很明显。填成对对的角,直到你用完角,然后填对边。对于奇数,只需加中间点即可。

票数 3
EN

Software Engineering用户

发布于 2016-02-25 19:57:09

一种算法是将其分解为如下内容:

  • 如果n是奇数,则显示中间点。
  • 如果n >= 2,则显示右上角和左下角。
  • 如果n >= 4,则显示左上角和右下角。
  • 如果n >= 6,则显示左中间点和右中间点。
  • 如果n >= 8,则显示顶部中心和底部中心点。

老实说,就像在代码中一样,只列出每个数字的点号是一样容易的。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/311113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档