I am working through an animation where I need to make this plane follow the path given and appear to be "circling" the earth. Here is the codePen, which as you can see is fairly simple.
My problem is with angles, I am trying to see how much should I rotate the plane as it moves through the path by calculating the slope of two points, and turning it into degrees.
Even though I have added an epsilon to safe-check for consistent differences across the points and every other safe-check, I am getting that as it approaches +-90 degrees, it changes signs, instead of passing to the other quadrant 120 degrees, etc.
I can understand that this is caused by the fact that
You can see this happening in the console right in the mid point (displays: slope, arctangent, degrees
).
To solve this, I am recurring to Math.atan2()
, by using newPoint.x - firstPoint.x, newPoint.y - firstPoint.y
as its arguments. It starts off with the right values (CodePen here). But it still does a funky rotation.
Here is the code (I'm not posting the SVG image because it's very large):
JS
var snap = Snap('#Globe_1_');
// Trail 1
var trail1 = snap.path('M354.3,707.9c13.9,14.5,27.9,27.2,41.7,38c13.9,10.9,27.2,19.3,39.3,25.4 c12.6,6.1,24.8,9,35.7,10.3c10.9,1.2,21.1-1.2,30.2-5.4c17-7.8,29-24.8,35.7-48.3c7.2-23.5,9-55,5.4-91.8 c-3.7-36.8-12-77.9-24.8-120.9c-12.6-43-30.2-87.6-51.9-131.7c-21.1-44.1-45.2-85.8-70.7-122.7s-50.8-69.5-77.3-95.5 c-27.2-26-52.5-43.6-75.6-53.2c-22.9-9.7-43.6-10.3-60.4-2.5c-16.3,7.8-27.9,24.2-35.1,47.7c-7.2,23.5-9.7,53.8-6.6,88.8')
.attr({
id: 'trail1',
fill:'none',
stroke: '#C25353',
strokeMiterLimit: 10
});
var len = trail1.getTotalLength();
var plane1 = snap.path('M375.7,708.4c0.1,0.8-0.7,1.8-1.6,1.9l-10.4,0.2l-8.4,15.1l-4,0l4.1-14.6l-7.8-0.2l-2.7,3.2L342,714 l1.6-4.9l-1.7-5.4l3.1,0.1l2.5,3.6l7.8,0.2l-4.3-14.6l4,0l8.3,14.7l10.4-0.2C375.5,706.7,376,707.1,375.7,708.4z') .attr({fill: '#CDCCCC' });
var initPoint = trail1.getPointAtLength( 1 ),
lastPoint,
slope = 0,
lastLen = 0;
Snap.animate(0, len, function( value ) {
movePoint = trail1.getPointAtLength( value );
if (lastPoint && ( Math.abs(lastPoint.y - movePoint.y) > 1 || Math.abs(lastPoint.x - movePoint.x) > 1 )) {
var slope_val = (lastPoint.y - movePoint.y) / (lastPoint.x - movePoint.x),
slope_atan = Math.atan2(movePoint.x - initPoint.x, movePoint.y - initPoint.y),
slope_deg = Snap.deg(slope_atan);
slope = slope_deg;
console.log('Capturing rotation', slope_val, slope_atan, slope_deg);
lastLen = value;
}
plane1.transform( 't' + parseInt(movePoint.x - 350) + ',' + parseInt( movePoint.y - 700) + 'r' + slope);
lastPoint = movePoint;
}, 5000, mina.linear);
Can you please help me out, thank you