在圆圈周围移动阴影

时间:2015-11-03 04:01:01

标签: javascript math transformation

我有一个每10秒绕一圈旋转的圆圈。我正在尝试投射一个朝向轨道原点(光源)倾斜的阴影,同时还要考虑相机角度。

阴影适用于某些角度,但随着相机越来越倾斜或越来越自上而下,它开始看起来不太准确,我不知道如何纠正它 - 这似乎是一个复杂的数学问题,我正在努力弄清楚如何解决。

这是动画: http://jsfiddle.net/8y2bm88w/

我为阴影绘制代码:

ctx.beginPath();

//rotate shadow with the planet
ctx.translate(originX + obj[i].x, originY + obj[i].y);
ctx.rotate(obj[i].angle); //rotate around origin
ctx.translate(-(originX + obj[i].x), -(originY + obj[i].y));


var offsetX = -(10 * Math.sin(obj[0].angle)); //i feel this is the issue
var offsetY = 0; //this too

ctx.rect(originX + obj[i].x + offsetX, originY + obj[i].y + offsetY - 10, 20, 20);
ctx.fillStyle = 'rgba(213,0,0,0.9)'; //red shadow - easier to see
ctx.fill();

代码通过JSFiddle更有意义,因为它将代码置于更多上下文中。

所以我认为这与offsetXoffsetY变量的数学有关,因为用户改变了摄像机角度,偏移量需要适应和改变影子移动。但是,这真的让人困惑如何解决。

1 个答案:

答案 0 :(得分:7)

你正在点击这个,因为你的obj[i].angle基于ellipsecoördinates,而不是自上而下的视图的xycoördinates(实际上是你正在生成其他所有东西,所以我们不需要为它做计算。)

你需要两个角度,所以我为另一个角度添加了第二个属性。旋转上下文需要椭圆角度,因此您可以垂直于原点的矢量。新角度用于计算。您可以将其视为非2D映射版本。

obj[i].trueAngle = angle;

现在我们有了合作的价值,我建议为“黑暗面”绘制一个半圆,然后根据需要使用您选择的曲线添加或切出该区域以完成阴影,例如< / p>

// centre on planet
ctx.translate(originX + obj[i].x, originY + obj[i].y);
ctx.rotate(obj[i].angle - Math.PI / 2);
// semicircle dark side
ctx.arc(0, 0, 12, 0, Math.PI, false);
// path along terminator
var offset_terminator = -20 * Math.sin(obj[0].trueAngle) * (1 - camera.angle);
ctx.bezierCurveTo(-7, offset_terminator, 7, offset_terminator, 12, 0);
//fill
ctx.fillStyle = 'rgba(213,0,0,0.9)'; //red shadow - easier to see
ctx.fill();

在这里,我也让阴影比行星大几倍,我只是玩数字,直到找到一些看起来不错的颜色。

请注意我设置了旋转,因此0, 0是行星的中间, x轴沿终结器移动

DEMO