javascript - 如何在Canvas中绘制半径对称的六条线?

标签 javascript math html5-canvas

我正在尝试在 Canvas 中构建一个雪花绘图应用程序,与此非常相似:http://www.pumpkinpirate.info/ks/

基本上,如果您绘制一个点,则应在 Canvas 内以对称的圆形图案重复 5 次。这是一个例子:

snowflake concept

我知道如何告诉 Canvas 多次绘制某些内容,但我的数学技能有限,我想知道如何计算 5 个复制点相对于原始点的位置。

我想我必须找到 Canvas 的中间并计算从该中间到原始点的 x 和 y 位置的距离。之后,我想也许我必须找到从该点开始画圆的半径,然后......这就是我的头开始冒烟的时候。

我想知道我是否可以做一些与他们在这里所做的类似的事情: Invert X and Y coordinates on HTML5 canvas

仅作为背景,我最初使用 6 个剪裁的 Canvas ,其中 5 个进行了旋转并复制第一个 Canvas ,但我意识到这种方法并没有真正起作用,部分原因是 Canvas 会彼此稍微重叠(但有还有其他问题)。

这是我到目前为止的代码:

drawing = false;
startX = 0;
startY = 0;
imageData = null;

const canvas = document.getElementById("canvas");

canvas.addEventListener("mousedown", startPosition());
canvas.addEventListener("mouseup", endPosition());
canvas.addEventListener("mousemove", draw());

function startPosition(e) {
  const canvas = this;
  const ctx = canvas.getContext("2d");

  startX = e.clientX;
  startY = e.clientY;
  imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
  drawing = true;
}

function endPosition(e) {
  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext("2d");

  ctx.lineWidth = 4;
  ctx.lineCap = "round";
  ctx.moveTo(startX, startY);
  ctx.lineTo(e.clientX, e.clientY);
  ctx.strokeStyle = '#ffffff';
  ctx.stroke();
  ctx.beginPath();

  drawing = false;
}
function draw(e) {
  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext("2d");

  if(!drawing) {
    return;
  }

  ctx.putImageData(imageData, 0, 0);
  ctx.lineWidth = 4;
  ctx.lineCap = "round";
  ctx.moveTo(startX, startY);
  ctx.lineTo(e.clientX, e.clientY);    
  ctx.strokeStyle = '#ffffff';
  ctx.stroke();
  ctx.beginPath();
  ctx.moveTo(e.clientX, e.clientY);

  //draw line 2
  ctx.moveTo(startX - 50, startY - 50);
  ctx.lineTo(e.clientX - 50, e.clientY - 50);
  ctx.stroke();
  ctx.beginPath();
  ctx.moveTo(e.clientX - 50, e.clientY - 50);

  //draw line 3
  ctx.moveTo(startX - 100, startY - 100);
  ctx.lineTo(e.clientX - 100, e.clientY - 100);
  ctx.stroke();
  ctx.beginPath();
  ctx.moveTo(e.clientX - 100, e.clientY - 100);
}

最佳答案

围绕另一个点旋转一个点

const center = {x: 100, y: 100};   // Point to rotate around
const point = {x: ?, y: ?};        // Point to rotate
const rotate = (Math.PI * 2) / 5;  // Rotate 1/5th of 360


// Get the vector from center to point
const vx = point.x - center.x;
const vy = point.y - center.y;

// Get the transformation (2D uniform rotate)
const xAx = Math.cos(rotate);
const xAy = Math.sin(rotate); 

// Transform the vector (rotates) and translate back to center
const tx = vx * xAx - vy * xAy + center.x;
const ty = vx * xAy + vy * xAx + center.y;

作为函数

function rotate(point, center, rotate, result = {}) {
    const vx = point.x - center.x;
    const vy = point.y - center.y;
    const xAx = Math.cos(rotate);
    const xAy = Math.sin(rotate); 
    result.x = vx * xAx - vy * xAy + center.x;
    result.y = vx * xAy + vy * xAx + center.y;
    return result;
}

使用上述函数从 1 个点创建 5 个点

const slices = 5; // number of rotations
const center = {x: 100, y: 100}; // center point

// Rotates point steps times around center
// Returns array of points
function rotateAll(point, steps, result = []) {
    const ang = Math.PI * 2 / steps;
    result.push(point);                      // Add first point
    for (let rot = 1; rot < steps; rot++) {  // Add remaining points
        result.push(rotate(point, center, rot * ang));
    }
    return result;
}

// Usage
const points = rotateAll({x: 10, y: 20}, slices);

关于javascript - 如何在Canvas中绘制半径对称的六条线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59619408/

相关文章:

javascript - 无法有意发出 http 请求

javascript - 走出一个表情

python - 检查一个数字是否是另一个数字的完美幂

math - 将矩阵对角线转换为参差不齐的数组?

javascript - 如何计算动态 Canvas 上文本对象的边界框

javascript - Javascript 中的命令 fillRect() 不起作用

javascript - 用于交互式 map 的 Flash 与 JavaScript

java - 是否可以在智能手机上屏蔽 IP 地址?

javascript - javascript 中 Math.cos 函数将度数转换为弧度时出现问题

javascript - 为什么我不能在 HTML5 中用另一个空 Canvas 清除 Canvas ?