Sir*_*Sir 14 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();
Run Code Online (Sandbox Code Playgroud)
代码通过JSFiddle更有意义,因为它将代码放入更多上下文中.
所以我认为这与数学offsetX
和offsetY
变量有关,因为用户改变了摄像机角度,偏移量需要适应和改变阴影移动的方式.但是,这真的让人困惑如何解决.
你是这样做的,因为你obj[i].angle
的基础是椭圆形,而不是自上而下的视图的xy坐标(实际上你正在生成其他所有内容,因此我们不需要对它进行计算).
你将需要两个角度,所以我为另一个角度添加了第二个属性.旋转上下文需要椭圆角度,因此您可以垂直于原点的矢量.新角度用于计算.您可以将其视为非2D映射版本.
obj[i].trueAngle = angle;
Run Code Online (Sandbox Code Playgroud)
现在我们有了合作的价值,我建议为"黑暗面"绘制一个半圆,然后根据需要使用您选择的曲线添加或切出该区域以完成阴影,例如
// 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();
Run Code Online (Sandbox Code Playgroud)
在这里,我也使阴影比行星大几倍,我只是玩数字,直到我发现一些看起来不错.
请注意我设置旋转,因此0, 0
是行星的中间,x轴沿着终结器移动