Airplane Animatiton on GMap.net not flight in straight line - gmap.net

i am trying to ceate plane animation on gmap.net
I created the route like that:
Map.Markers.Remove(_route);
_route = new GMapRoute(PointsList.Select(x => x.Location).ToList());
Map.Markers.Add(_route);
The start flight method is :
while (!IsFlightEnded())
{
CalculateNextPoint();
_plane.Position = _nextPointInRoute;
await Task.Delay(250);
}
The calculate next point is:
private void CalculateNextPoint()
{
_nextPointInRoute.Lat += LattitudeDifference() / 100;
_nextPointInRoute.Lng += LongitudeDifference() / 100;
}
the LattitudeDifference is calculate the difference between the destanation's lat to the source's lat.
Same thing to the LongitudeDifference.
The problem is that the animation not moving on the straight route, and it is going like parabola
I even tried to use linear equation but it was the same.

Related

How to make BodyDef smooth movement

I tried to use the method setTransform like this:
#override
void update(double dt) {
super.update(dt);
increaseTimer.update(dt);
if (side == 3) {
body.setTransform(Vector2(0, gameRef.increasedHeight), 0);
}
}
But the item looks like it is flashing from point A to point B, and the Items above this body are falling. I just want this body and the items above to move smoothly in a direction , how to achieve this? Thanks, I found some methods like using MouseJoint, but I guess it is too complicated for my topic?
=========UPDATE==========
Hi spydon, thanks for reply, I checked your answer, sry I didnt describe my question clearly.
The item I want to keep moving upward is like a wall/ground so it is a static body, therefore applyLinearImpulse/applyForce does not work right (since these both works only for dynamic body?).
Therefore I found setTransform, which works for static body,
increasedHeight++; //<= in update method
body.setTransform(Vector2(0, increasedHeight), 0);
works fine which make my ground move upward in 1 unit, but if the distance is larger than 1 unit, like
increasedHeight = increasedHeight + 10;,
the ground will be beamed to top and balls on this ground will be falling, which I don't want to, I tried to make balls and ground move together upward, is it possible?
Thanks for your time!
=========2.UPDATE==========
Hi Spydon, thanks again for your help! Plz check the example I created, since this Ground didn't move upward as I expected and just stuck in the position ...
class Ground extends SpriteBodyComponent {
Vector2 groundPosition;
bool removed = false;
final velocity = Vector2(0, 1000);
Ground({Sprite sprite, Vector2 size, this.groundPosition}) : super(sprite, size);
#override
Body createBody() {
final shape = CircleShape()..radius = size.x / 4;
var position = groundPosition.clone();
var worldPosition = viewport.getScreenToWorld(position);
final fixtureDef = FixtureDef()
..shape = shape
..restitution = 0.1
..density = 0.1
..friction = 0.1;
final bodyDef = BodyDef()
..userData = this
..angularDamping = 0.1
..position = worldPosition
..type = BodyType.STATIC;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
#override
void update(double dt) {
super.update(dt);
body.setTransform(velocity * dt, 0);
print('body position == ${body.position.y}'); //<= body position == 16.667
}
}
You should almost never use setTransform on dynamic bodies, since this disturbs the physics calculations. If you are not certain that you need the physics simulation you most likely want to go with pure Flame and use one of the MoveEffects instead.
If you do need Forge2D, you should either use body.applyLinearImpulse or body.applyForce, depending on how you want to affect your bodies movement.
You can read more about it here and you can check out the flame_forge2d examples here, you can get to the code for each example by pressing < > in the upper right corner.
Reply to updated question:
You should change these things in your update method which gives you a delta time dt, this delta time you use together with the velocity that you want to the body to change with, for example:
final velocity = Vector2(0, 100); // Will move with 100px/s
#override
void update(double dt) {
if(!velocity.isZero) {
// Here you have to multiply with dt, to make the transform become px/s
body.setTransform(velocity * dt, 0);
}
}

Distance moved by XR-controller in Unity

I have been making a script in Unity that measures how far a player has moved in the real world using XRNodes like this for example with the right hand:
InputTracking.GetLocalPosition(XRNode.RightHand)
at the start of the movement and then comparing it to the end position
Now I would like to get the distance moved, even if the player moved around in a circle.
Is the a method to do this with XRNodes? Measuring total distance moved during play?
Yes, well, you could just simply sum it up every frame like
// Stores the overall moved distance
private float totalMovedDistance;
// flag to start and stop tracking
// Could also use a Coroutine if that fits you better
private bool track;
// Store position of last frame
private Vector3 lastPos;
public void BeginTrack()
{
// reset total value
totalMovedDistance = 0;
// store first position
lastPos = InputTracking.GetLocalPosition(XRNode.RightHand);
// start tracking
track = true;
}
public void EndTrack()
{
// stop tracking
track = false;
// whatever you want to do with the total distance now
Debug.Log($"Total moved distance in local space: {totalMovedDistance}", this);
}
private void Update()
{
// If not tracking do nothing
if(!track) return;
// get current controller position
var currentPos = InputTracking.GetLocalPosition(XRNode.RightHand);
// Get distance moved since last frame
var thisFrameDistance = Vector3.Distance(currentPos, lastPos);
// sum it up to the total value
totalMovedDistance += thisFrameDistance;
// update the last position
lastPos = currentPos;
}

How to change the zoom centerpoint in an ILNumerics scene viewed with a camera

I would like to be able to zoom into an ILNumerics scene viewed by a camera (as in scene.Camera) with the center point of the zoom determined by where the mouse pointer is located when I start spinning the mouse scroll wheel. The default zoom behavior is for the zoom center to be at the scene.Camera.LookAt point. So I guess this would require the mouse to be tracked in (X,Y) continuously and for that point to be used as the new LookAt point? This seems to be like this post on getting the 3D coordinates from a mouse click, but in my case there's no click to indicate the location of the mouse.
Tips would be greatly appreciated!
BTW, this kind of zoom method is standard operating procedure in CAD software to zoom in and out on an assembly of parts. It's super convenient for the user.
One approach is to overload the MouseWheel event handler. The current coordinates of the mouse are available here, too.
Use the mouse screen coordinates to acquire (to "pick") the world
coordinate corresponding to the primitive under the mouse.
Adjust the Camera.Position and Camera.ZoomFactor to 'move' the camera closer to the point under the mouse and to achieve the required 'directional zoom' effect.
Here is a complete example from the ILNumerics website:
using System;
using System.Windows.Forms;
using ILNumerics;
using ILNumerics.Drawing;
using ILNumerics.Drawing.Plotting;
using static ILNumerics.Globals;
using static ILNumerics.ILMath;
namespace ILNumerics.Examples.DirectionalZoom {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void panel2_Load(object sender, EventArgs e) {
Array<float> X = 0, Y = 0, Z = CreateData(X, Y);
var surface = new Surface(Z, X, Y, colormap: Colormaps.Winter);
surface.UseLighting = true;
surface.Wireframe.Visible = false;
panel2.Scene.Camera.Add(surface);
// setup mouse handlers
panel2.Scene.Camera.Projection = Projection.Orthographic;
panel2.Scene.Camera.MouseDoubleClick += Camera_MouseDoubleClick;
panel2.Scene.Camera.MouseWheel += Camera_MouseWheel;
// initial zoom all
ShowAll(panel2.Scene.Camera);
}
private void Camera_MouseWheel(object sender, Drawing.MouseEventArgs e) {
// Update: added comments.
// the next conditionals help to sort out some calls not needed. Helpful for performance.
if (!e.DirectionUp) return;
if (!(e.Target is Triangles)) return;
// make sure to start with the SceneSyncRoot - the copy of the scene which receives
// user interaction and is eventually used for rendering. See: https://ilnumerics.net/scene-management.html
var cam = panel2.SceneSyncRoot.First<Camera>();
if (Equals(cam, null)) return; // TODO: error handling. (Should not happen in regular setup, though.)
// in case the user has configured limited interaction
if (!cam.AllowZoom) return;
if (!cam.AllowPan) return; // this kind of directional zoom "comprises" a pan operation, to some extent.
// find mouse coordinates. Works only if mouse is over a Triangles shape (surfaces, but not wireframes):
using (var pick = panel2.PickPrimitiveAt(e.Target as Drawable, e.Location)) {
if (pick.NextVertex.IsEmpty) return;
// acquire the target vertex coordinates (world coordinates) of the mouse
Array<float> vert = pick.VerticesWorld[pick.NextVertex[0], r(0, 2), 0];
// and transform them into a Vector3 for easier computations
var vertVec = new Vector3(vert.GetValue(0), vert.GetValue(1), vert.GetValue(2));
// perform zoom: we move the camera closer to the target
float scale = Math.Sign(e.Delta) * (e.ShiftPressed ? 0.01f : 0.2f); // adjust for faster / slower zoom
var offs = (cam.Position - vertVec) * scale; // direction on the line cam.Position -> target vertex
cam.Position += offs; // move the camera on that line
cam.LookAt += offs; // keep the camera orientation
cam.ZoomFactor *= (1 + scale);
// TODO: consider adding: the lookat point now moved away from the center / the surface due to our zoom.
// In order for better rotations it makes sense to place the lookat point back to the surface,
// by adjusting cam.LookAt appropriately. Otherwise, one could use cam.RotationCenter.
e.Cancel = true; // don't execute common mouse wheel handlers
e.Refresh = true; // immediate redraw at the end of event handling
}
}
private void Camera_MouseDoubleClick(object sender, Drawing.MouseEventArgs e) {
var cam = panel2.Scene.Camera;
ShowAll(cam);
e.Cancel = true;
e.Refresh = true;
}
// Some sample data. Replace this with your own data!
private static RetArray<float> CreateData(OutArray<float> Xout, OutArray<float> Yout) {
using (Scope.Enter()) {
Array<float> x_ = linspace<float>(0, 20, 100);
Array<float> y_ = linspace<float>(0, 18, 80);
Array<float> Y = 1, X = meshgrid(x_, y_, Y);
Array<float> Z = abs(sin(sin(X) + cos(Y))) + .01f * abs(sin(X * Y));
if (!isnull(Xout)) {
Xout.a = X;
}
if (!isnull(Yout)) {
Yout.a = Y;
}
return -Z;
}
}
// See: https://ilnumerics.net/examples.php?exid=7b0b4173d8f0125186aaa19ee8e09d2d
public static double ShowAll(Camera cam) {
// Update: adjusts the camera Position too.
// this example works only with orthographic projection. You will need to take the view frustum
// into account, if you want to make this method work with perspective projection also. however,
// the general functioning would be similar....
if (cam.Projection != Projection.Orthographic) {
throw new NotImplementedException();
}
// get the overall extend of the cameras scene content
var limits = cam.GetLimits();
// take the maximum of width/ height
var maxExt = limits.HeightF > limits.WidthF ? limits.HeightF : limits.WidthF;
// make sure the camera looks at the unrotated bounding box
cam.Reset();
// center the camera view
cam.LookAt = limits.CenterF;
cam.Position = cam.LookAt + Vector3.UnitZ * 10;
// apply the zoom factor: the zoom factor will scale the 'left', 'top', 'bottom', 'right' limits
// of the view. In order to fit exactly, we must take the "radius"
cam.ZoomFactor = maxExt * .50;
return cam.ZoomFactor;
}
}
}
Note, that the new handler performs the directional zoom only when the mouse is located over an object hold by this Camera! If, instead, the mouse is placed on the background of the scene or over some other Camera / plot cube object no effect will be visible and the common zoom feature is performed (zooming in/out to the look-at point).

Forge view angle in mobile VR

When starting VR tool on mobile and watching directly ahead, I would like to have the view to show the whole model in the center of the screen. The view should be at a slight angle, so I could see the whole building floor. Currently it is directly ahead, which leaves you with a view where you cannot see the whole model. How could I achieve this?
For example, in this Autodesk example, the model is in the center when you enter VR.
http://viewervr.herokuapp.com/
Current code, with what I am trying to adjust the camera position
document.getElementById("toolbar-vrTool").addEventListener("click", function () {
let _navapi = viewer.navigation;
let _camera = _navapi.getCamera();
let xValue = viewer.getCamera().position.x;
let yValue = viewer.getCamera().position.y;
let zValue = viewer.getCamera().position.z;
zValue = zValue * 0.5;
yValue = (zValue * 0.7071) * -1;
_camera.position.set(xValue, yValue, zValue);
});
Current view
View I would like to have
There is a function named fitToView() which will do exactly what you want. But you need to wait for the geometry to be fully loaded before using it. I also added a call to setHomeViewFrom() in the example below to reset the Home position to the fitToView() position result for later navigation.
oViewer.addEventListener (Autodesk.Viewing.GEOMETRY_LOADED_EVENT, onViewerGeometryLoaded) ;
function onViewerGeometryLoaded () {
oViewer.removeEventListener (Autodesk.Viewing.GEOMETRY_LOADED_EVENT, onViewerGeometryLoaded) ;
oViewer.fitToView (true) ;
setTimeout (function () { oViewer.autocam.setHomeViewFrom (oViewer.navigation.getCamera ()) ; }, 1000) ;
}

I want to get user's height by using kinect V2 and unity3D,this code can't work well what should I do?

Attempting to get the user's height in Unity using the xbox kinect.
Below is my code and I cannot get the height.
This uses the KinectV2 interface.
// get User's height by KinectV2 and unity3D `enter code here`
float GetUserHeightByLeft(long userid)
{`enter code here`
float uheight=0.0f;
int[] joints = new int[9];
int head = (int)KinectInterop.JointType.Head;
joints[0] = head;
joints[1] = (int)KinectInterop.JointType.Neck;
int shoudlderCenter = (int)KinectInterop.JointType.SpineShoulder;
joints[2] = shoudlderCenter;
joints[3] = (int)KinectInterop.JointType.SpineMid;
joints[4] = (int)KinectInterop.JointType.SpineBase;
joints[5] = (int)KinectInterop.JointType.HipLeft;
joints[6] = (int)KinectInterop.JointType.KneeLeft;
joints[7] = (int)KinectInterop.JointType.AnkleLeft;
joints[8] = (int)KinectInterop.JointType.FootLeft;
int trackedcount = 0;
for (int i = 0; i < joints.Length; ++i)
{
if (KinectManager.Instance.IsJointTracked(userid, joints[i]))
{
++trackedcount;
}
}
//if all joints that I need have been tracked ,compute user's height
if (trackedcount == joints.Length)
{
for (int i = 0; i < joints.Length-1;++i)
{
if (KinectManager.Instance.IsJointTracked(userid, joints[i]))
{
Vector3 start= 100*KinectManager.Instance.GetJointKinectPosition(userid,joints[i]);
Vector3 end = 100*KinectManager.Instance.GetJointKinectPosition(userid,joints[i+1]);
uheight += Mathf.Abs(Vector3.Magnitude(end-start));
}
}
//some height kinectV2 can't get so I add it
uheight += 8;
}
return uheight;
}
Given your code I do see a few issues
The summation to get the total height requires all joints to be tracked at that time.
Why do you need all joints to be tracked for the height to be tracked? You should only need the head and the feet
You double check if each joint is tracked
using the left for every foot/knee/hip joint is going to give you math errors. They are offset in one direction (because our feet aren't in the center of our body)
I would track both right and left foot/knee/hip and then find the center of the two on the x axis.
If you're using the magnitude of two vectors and one knee is far in front of your hip it's going to give it an inflated value.
I would only use the y positions of your kinect joints to calculate the height.