/// <inheritdoc/> public void Initialize( MapRendererBase mapRenderer, MapScene mapScene, float animationTimeScale, MapSceneAnimationKind mapSceneAnimationKind) { if (mapRenderer == null) { throw new ArgumentNullException(nameof(mapRenderer)); } if (mapScene == null) { throw new ArgumentNullException(nameof(mapScene)); } _runningTime = 0; _startMercatorCenter = mapRenderer.Center.ToMercatorCoordinate(); _startZoomLevel = mapRenderer.ZoomLevel; mapScene.GetLocationAndZoomLevel(mapRenderer, out var endLocation, out _endZoomLevel); _endZoomLevel = _endZoomLevel < mapRenderer.MinimumZoomLevel ? mapRenderer.MinimumZoomLevel : _endZoomLevel; _endZoomLevel = _endZoomLevel > mapRenderer.MaximumZoomLevel ? mapRenderer.MaximumZoomLevel : _endZoomLevel; _endMercatorCenter = endLocation.ToMercatorCoordinate(); _startHeightInMercator = ZoomLevelToMercatorAltitude(_startZoomLevel); _endHeightInMercator = ZoomLevelToMercatorAltitude(_endZoomLevel); // Determine if we should use a bow animation or a linear animation. // Simple rule for now: If the destination is already visible, use linear; otherwise, bow. _isLinearAnimation = mapSceneAnimationKind == MapSceneAnimationKind.Linear || mapSceneAnimationKind == MapSceneAnimationKind.SmoothLinear || mapRenderer.Bounds.Intersects(endLocation); _isSmoothed = mapSceneAnimationKind == MapSceneAnimationKind.SmoothLinear; // While linear animation doesn't follow the same code path as the bow animation, we can still use this function to compute // a reasonable duration for the linear animation. ComputeBowAnimationInitialValues( P, V * animationTimeScale, out _u0, out _u1, out _w0, out _, // w1 out _r0, out _, // r1 out _S, out _animationTime); // Tweaking the resulting animation time to speed up slower animations and slow down the shorter animation. _animationTime /= 6.0; // Normalize. _animationTime = Math.Pow(_animationTime, 1.0 / 3.0); // Rescale. _animationTime *= 6.0; // Convert back to original range. }