【问题标题】:Please help me figure out how this star was made in canvas请帮我弄清楚这颗星星是如何在画布上制作的
【发布时间】:2015-11-23 05:58:26
【问题描述】:

我在网上找到了这段代码,我正在努力弄明白。

window.onload = function(){
	var canvas = document.getElementById("canvas"),
		ctx = canvas.getContext("2d");

	function drawStar(cx, cy, spikes, outerRadius, innerRadius){
		var rot = Math.PI / 2 * 3;
		var x = cx;
		var y = cy;
		var step = Math.PI / spikes;

		ctx.strokeStyle = "#000";
		ctx.beginPath();
		ctx.moveTo(cx, cy - outerRadius) //100 - 30

		for(i = 0; i < spikes; i++){
			$(".display").append(Math.cos(rot) +" , ")
			x = cx + Math.cos(rot) * outerRadius;
			y = cy + Math.sin(rot) * outerRadius;
			console.log("x : ", x, " y : ", y)
			ctx.lineTo(x,y);
			rot += step;

			x = cx + Math.cos(rot) * innerRadius;
			y = cy + Math.sin(rot) * innerRadius;
			ctx.lineTo(x,y);
			rot+= step;
		}

		ctx.lineTo(cx, cy- outerRadius);
		ctx.closePath();
		ctx.lineWidth = 1;
		ctx.strokeStyle = "blue";
		ctx.stroke()
		ctx.beginPath();
		ctx.arc(cx,cy,2, 0, (Math.PI * 2), true);
		ctx.fillStyle = "red";
		ctx.fill()
		ctx.closePath();
	}

	drawStar(75, 100, 5,45, 15) //cx,cy,spikes, outerRadius, innerRadius
}
canvas{
	background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>
<div class="display"></div>

我看到上面写着var rot = Math.PI / 2 * 3 我想这是一个 270 度角,因为 90 * 3 = 270。我需要帮助弄清楚他们是如何得到星形右上角的点的。我相信是outerRadius

他们x = cx + Math.cos(rot) * outerRadius; 是因为右上角(试图获得右上角)是 54 度的“腐烂”? .. 我认为(Math.PI / 5) * 180 / Math.PI 5 来自步进变量.. 等于 36 所以我做了 90 度 - 36 得到 54。我希望我能弄明白吗?我不确定他们为什么使用 270 度。你能详细说明一下吗?我不确定他们为什么使用var rot = Math.PI / 2 * 3,如果我稍微玩一下nums,我就会得到垃圾。我假设他们正在使用它来获得点构成的角度,但我很难将这些部分放在一起。

编辑:我把红点放在中心,以帮助我测量点到中心的角度。

【问题讨论】:

    标签: javascript math canvas trigonometry


    【解决方案1】:

    这很简单:

    • 画布中的角度是这样计算的:0 度是水平方向,顺时针方向,所以 1.5 PI(270 度)正好在顶部。

      cx + Math.cos(rot) * outerRadius = 0
      cy + Math.sin(rot) * outerRadius = outerRadius
      
    • 2 * PI 是完整的圆圈,因此要绘制每个长矛,您将在每个2 * PI/spikes 绘制它们。可以看到rot每增加一倍PI/spikes,一为内点,二为外点。

    【讨论】:

      【解决方案2】:

      我在您的演示中添加了一些文字,希望它有助于回答您的问题。

      首先,您正确地假设Math.PI / 2 * 3 与获得270 度的弧度相同。为了说明,我已将其更改为270 * Math.PI / 180,这会产生相同的结果,并且可能更易于阅读。

      它从 270 开始的原因是,如果您将画布中的旋转视为时钟,则 0 度将恰好位于 3 点钟方向,或者相对于您的上下文点位于右侧。然后,如果您旋转 270 度,您将到达上下文点正上方的 12 点。

      在您的代码中,开头的 moveTo 和循环中的第一个点完全相同(请参阅演示中的 Init 上下文点和 0.a 是如何相同的)。然后,随着rot 通过添加step 而增加,您会看到这些点是如何按顺序绘制的。从外半径移动到内半径。

      var canvas = document.getElementById("canvas"),
      ctx = canvas.getContext("2d");
      
      function drawStar(cx, cy, spikes, outerRadius, innerRadius) {
          var rot = 270 * Math.PI / 180;
          var x = cx;
          var y = cy;
          var step = Math.PI / spikes;
       
          ctx.strokeStyle = "#000";
          ctx.beginPath();
          ctx.moveTo(cx, cy - outerRadius) //100 - 30
          ctx.fillText('Init context point: x: ' + cx + ', y: ' + (cy - outerRadius), cx, cy - outerRadius - 10);
      
          for (i = 0; i < spikes; i++) {
              $(".display").append(Math.cos(rot) + " , ")
              x = cx + Math.cos(rot) * outerRadius;
              y = cy + Math.sin(rot) * outerRadius;
              console.log("x : ", x, " y : ", y)
              ctx.lineTo(x, y);
              ctx.fillStyle = 'green';
              ctx.fillText('(' + i + '.a), ' + rot * (180/Math.PI) + '°', x, y);
              rot += step;
      
              x = cx + Math.cos(rot) * innerRadius;
              y = cy + Math.sin(rot) * innerRadius;
              ctx.fillStyle = 'yellow';
              ctx.fillText('(' + i + '.b), ' + rot * (180/Math.PI) + '°', x, y);
              ctx.lineTo(x, y);
              rot += step;
          }
          // I've commented this out since closePath() in the next line will do 
          // the same as drawing the last line back to the initial context point.
          // ctx.lineTo(cx, cy - outerRadius);
          ctx.closePath();
          ctx.lineWidth = 1;
          ctx.strokeStyle = "blue";
          ctx.stroke()
          ctx.beginPath();
          ctx.arc(cx, cy, 2, 0, (Math.PI * 2), true);
          ctx.fillStyle = "red";
          ctx.fillText("x: " + cx + ', y: ' + cy, cx, cy);
          ctx.fill()
          ctx.closePath();
      }
      
      drawStar(150, 150, 5, 100, 50) //cx,cy,spikes, outerRadius, innerRadius
      canvas{
      	background: #ccc;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
      <canvas id="canvas" width="400" height="400"></canvas>
      <div class="display"></div>

      【讨论】:

      • 感谢您的回答。由 (0,a) 红点和 (1,a) 组成的天使的度数是多少?
      • 简而言之,1.a 距离中心 342 度。可以通过degrees = rad * (180/Math.PI) 获得弧度的度数。我已经编辑了演示,因此您可以根据弧度查看每个点的度数。希望对您有所帮助。
      • 嗨,所以角度是 342-270 = 72?对于角度角 (o,a)x(1,a)。或者这不是它的工作原理?
      • 是的,角度 0.a, 1.a 将是 72 度。但请记住,在画布中,点 0.a 不是 0 度,而是 270 度。但除此之外,您就明白了。
      猜你喜欢
      • 1970-01-01
      • 2011-03-25
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 2020-09-03
      相关资源
      最近更新 更多