Building out react-native-maps and trying to decide the pros and cons of using animateToRegion vs. animateCamera. In the past we've handled everything on a region basis.
Seems like region would be a better choice, as you won't have to worry about differences between elevation and zoom, while also having a more granular control of the exact region being displayed if needed.
Anyone have any thoughts or experiences that have led them to one or the other?
I just made this switch myself. I found that animateCamera() is more versatile and allows for cleaner syntax.
The biggest pro for animateCamera() is that you can do multiple animations from a single method call.
An example of centering to coords and turning the camera 180 degrees with animateCamera():
this.map.animateCamera({
center: {
latitude: 0,
longitude: 0,
},
heading: 180,
});
If you wanted to do the same thing with animateToRegion() you would need to call two methods:
this.map.animateToRegion({
latitude: 0,
longitude: 0,
});
this.map.animateCamera({
heading: 180,
});
Not as clean.
As of right now, a con for animateCamera() is that you don't seem to be able to pass a latitudeDelta and longitudeDelta into the center property like you can with region, specified here.
In short, if you don't need to use a latitudeDelta and longitudeDelta then animateCamera() is the way to go. If I had to speculate, I would say animateToRegion() is going to be deprecated like the other methods sometime in the future in favor of animateCamera().
Related
I'm trying to display the wind on a map. For each pin on my map, I'd like to change color and orientation in order to represent the force and the heading of the wind.
Here's what I've done :
var pinWindLabel = Ti.UI.createLabel({ width:Ti.UI.SIZE, height:Ti.UI.SIZE, text:'\ue958', font:{fontFamily:Ti.App.ICONS, fontSize:25}, touchEnabled:false });
var pinWind = Ti.UI.createView({width:Ti.UI.SIZE, height:Ti.UI.SIZE});
pinWind.add(pinWindLabel);
And, in the API response :
for(var k=0; k<res.length; k++){
if(res[k].wind_avg < 10){
pinWindLabel.setColor('green');
} else{
pinWindLabel.setColor('blue');
}
var pin = Map.createAnnotation({
latitude: res[k].lat,
longitude: res[k].lng,
image:pinWind.toImage(),
});
annotations.push(pin);
}
I had difficulties to change the color of each pin. Without the 'toImage()', I think it's not possible. But now, it works :)
Now I'd like to change its orientation. But even with this code, the pin has always the same orientation :
var pinWindLabel = Ti.UI.createLabel({ width:Ti.UI.SIZE, height:Ti.UI.SIZE, text:'\ue958', font:{fontFamily:Ti.App.ICONS, fontSize:25}, touchEnabled:false });
var pinWind = Ti.UI.createView({width:Ti.UI.SIZE, height:Ti.UI.SIZE});
pinWind.transform = Ti.UI.create2DMatrix({rotate: 236});
pinWind.add(pinWindLabel);
So, how can I do to, first of all, rotate all pins, and, after, rotate each pin in the for loop ?
Thanks a lot :)
As advised in comments section, in this case, it's more efficient to use pre-rotated image files Click here to see Rotated Pins as pins.
Though you will need to create many images, but it's most efficient solution across all platforms without much code & complexity.
Another point to note is that modifying images at run-time takes more computation power, so it's always recommended to apply least modifications especially on images at run-time. Always have optimal-resolution & least-size images for faster loading.
There is an Android as well as iOS application that I am working on.
Both the applications use google's PlaceAutocomplete controller to get a location's lat-long. In iOS we get lat-long upto 6 decimal places sometimes 5 also. Where as in android we get more than 6 decimal places. The precision of the same location coordinate for Android and iOS differs.
For example consider location Pune
Android Latlng: 18.520431,73.856744
iOS Latlng: 18.52043,73.856744
So as you can see there is difference between the precision of latitudes of the same location.
Is there a way to avoid this as my application needs comparison of these lat-longs?
You should not rely on the precision of the coordinates to compare them because they can change or, as you experiment, vary between platforms.
Instead, you can set a tolerance to determine if two locations are the same. For example:
float YOUR_TOLERANCE = 1; // 1 meter
if (location.distanceTo(otherLocation) < YOUR_TOLERANCE) {
// Both locations are considered the same
}
In android also there is three type of location :
GPS_PROVIDER
NETWORK_PROVIDER
PASSIVE_PROVIDER
So, as per my coding experience i come to know that if you use :
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, new MyLocationListener());
you will get long precision of decimal like more then 14+ and if you will you use fusion of them with this :
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, my_google_listener);
then you will get 6 to 7 digit of precision. try it !!!
I'm using Nativescript 1.6 and this component https://github.com/bradmartin/nativescript-floatingactionbutton
I would like to have some nice "material design effect" when you click on this button and then navigate to another page. It's a bit hacky but it does the job and looks quite nice (i probably should use fragment transitions with shared elements when i was in native Android world, but im not)
My current attempt:
XML:
<FAB:fab tap="tap"
loaded="buttonLoaded"
row="1"
icon="res://ic_add_white_24dp"
rippleColor="#f1f1f1"
class="fab-button" />
JS:
fabButton.icon = ""; // Error! ResourceNotFoundException
fabButton.animate({
scale: { x: 20, y: 20 },
translate: { x: -200, y: -200 },
duration: 300
}).then(function(){
navigation.goToDetailPage();
fabButton.animate({ // reset button to original state
scale: { x: 1, y: 1 },
translate: { x: 0, y: 0 },
delay: 100,
duration: 0
});
});
2 questions:
How can i remove the icon, just for a nicer effect? "", {}, null are not allowed, should i really create a transparent png for this?
Is there a better way to restore/reset element after an animation?
If the exception is ResourceNotFoundException that looks like a native exception thrown so it doesn't look like you'll be able to set a null value. Your best option is probably an empty .png. I suppose the plugin could check for a null value and bypass the native exception but for now that's not the case. You could make a PR with this feature if you wanted.
As for resetting an element to its original state, what you are doing is what I would do. I don't think there would be a "better" way because once you've changed the state with the initial animation, the native setTranslateX/Y and other methods to run the animation have changed the items location/position/color, etc. So what you are doing is probably the best approach.
I'd like to see this animation if you don't mind, looks like something other devs might want :) Maybe record a .gif and attach here for others to see as a reference. If you don't have a tool to record a .gif here is what I use: http://www.cockos.com/licecap/ when I record from the emulators.
Hope this helps some.
I'm interested in AR applications of mobile devices and naturally I would like to make better use of the compass.
The only issue I've been having to work against isn't how twitchy the compass is. (Angular Smoothing seems to solve this issue just fine) My main issue is that when the device is held Vertical the compass values start freaking out. Causing an on screen compass to flip about all over the place. I don't have a lot of experience with mobile application development so I'm not sure what would be causing this issue, if its a Unity issue or if its just a limitation of the digital compass. I know other apps do seem to be able to use the compass fine in any orientation, but this is all stupidly new to me.
I've definitely tried moving the phone in a figure of 8. The device I have to play around with is a Nexus 4.
using UnityEngine;
using System.Collections;
public class Compass : MonoBehaviour {
// Use this for initialization
void Start () {
Input.location.Start ();
Input.compass.enabled = true;
}
// Update is called once per frame
void Update ()
{
var heading = Input.compass.trueHeading;
transform.eulerAngles = new Vector3 (0, 0, heading);
}
}
Preamble :)
First of, I'm not an expert (unfortunately) in subjects that I will talk about. But still, I've decided to share my thoughts.
Theory
The problem can be generalized in the following way. You want to have some continuous function that takes a 3D vector (which is device orientation in your case) and returns another vector that is orthogonal to original vector. Theory says (see hairy ball theorem) that for some arguments that function will return zero vectors. In case when such a function is compass, zero vectors are returned when device is oriented vertical (and this fells quite natural if you have ever used an ordinary compass).
Practice
Sometimes you want your app to tell which side of the world does phone back (rear camera) is pointing to.
Or maybe even you want combined approach:
If the phone is oriented flat, show what is the phone's top pointing to.
If the phone is oriented vertical, show what is the phone's back pointing to.
In both cases you need to use gyroscope in addition to compass.
I try to create game for Android and I have problem with high speed objects, they don't wanna to collide.
I have Sphere with Sphere Collider and Bouncy material, and RigidBody with this param (Gravity=false, Interpolate=Interpolate, Collision Detection = Continuous Dynamic)
Also I have 3 walls with Box Collider and Bouncy material.
This is my code for Sphere
function IncreaseBallVelocity() {
rigidbody.velocity *= 1.05;
}
function Awake () {
rigidbody.AddForce(4, 4, 0, ForceMode.Impulse);
InvokeRepeating("IncreaseBallVelocity", 2, 2);
}
In project Settings I set: "Min Penetration For Penalty Force"=0.001, "Solver Interation Count"=50
When I play on the start it work fine (it bounces) but when speed go to high, Sphere just passes the wall.
Can anyone help me?
Thanks.
Edited
var hit : RaycastHit;
var mainGameScript : MainGame;
var particles_splash : GameObject;
function Awake () {
rigidbody.AddForce(4, 4, 0, ForceMode.Impulse);
InvokeRepeating("IncreaseBallVelocity", 2, 2);
}
function Update() {
if (rigidbody.SweepTest(transform.forward, hit, 0.5))
Debug.Log(hit.distance + "mts distance to obstacle");
if(transform.position.y < -3) {
mainGameScript.GameOver();
//Application.LoadLevel("Menu");
}
}
function IncreaseBallVelocity() {
rigidbody.velocity *= 1.05;
}
function OnCollisionEnter(collision : Collision) {
Instantiate(particles_splash, transform.position, transform.rotation);
}
EDITED added more info
Fixed Timestep = 0.02 Maximum Allowed Tir = 0.333
There is no difference between running the game in editor player and on Android
No. It looks OK when I set 0.01
My Paddle is Box Collider without Rigidbody, walls are the same
There are all in same layer (when speed is normal it all works) value in PhysicsManager are the default (same like in image) exept "Solver Interation Co..." = 50
No. When I change speed it pass other wall
I am using standard cube but I expand/shrink it to fit my screen and other objects, when I expand wall more then it's OK it bouncing
No. It's simple project simple example from Video http://www.youtube.com/watch?v=edfd1HJmKPY
I don't use gravity
See:
Similar SO Question
A community script that uses ray tracing to help manage fast objects
UnityAnswers post leading to the script in (2)
You could also try changing the fixed time step for physics. The smaller this value, the more times Unity calculates the physics of a scene. But be warned, making this value too small, say <= 0.005, will likely result in an unstable game, especially on a portable device.
The script above is best for bullets or small objects. You can manually force rigid body collisions tests:
public class example : MonoBehaviour {
public RaycastHit hit;
void Update() {
if (rigidbody.SweepTest(transform.forward, out hit, 10))
Debug.Log(hit.distance + "mts distance to obstacle");
}
}
I think the main problem is the manipulation of Rigidbody's velocity. I would try the following to solve the problem.
Redesign your code to ensure that IncreaseBallVelocity and every other manipulation of Rigidbody is called within FixedUpdate. Check that there are no other manipulations to Transform.position.
Try to replace setting velocity directly by using AddForce or similar methods so the physics engine has a higher chance to calculate all dependencies.
If there are more items (main player character, ...) involved related to the physics calculation, ensure that their code runs in FixedUpdate too.
Another point I stumbled upon were meshes that are scaled very much. Having a GameObject with scale <= 0.01 or >= 100 has definitely a negative impact on physics calculation. According to the docs and this Unity forum entry from one of the gurus you should avoid Transform.scale values != 1
Still not happy? OK then the next test is starting with high velocities but no acceleration. At this phase we want to know, if the high velocity itself or the acceleration is to blame for the problem. It would be interesting to know the velocities' values at which the physics engine starts to fail - please post them so that we can compare them.
EDIT: Some more things to investigate
6.7 m/sec does not sound that much so that I guess there is a special reason or a combination of reasons why things go wrong.
Is your Maximum Allowed Timestep high enough? For testing I suggest 5 to 10x Fixed Timestep. Note that this might kill the frame rate but that can be dfixed later.
Is there any difference between running the game in editor player and on Android?
Did you notice any drops in frame rate because of the 0.01 FixedTimestep? This would indicate that the physics engine might be in trouble.
Could it be that there are static colliders (objects having a collider but no Rigidbody) that are moved around or manipulated otherwise? This would cause heavy recalculations within PhysX.
What about the layers: Are all walls on the same layer resp. are the involved layers are configured appropriately in collision detection matrix?
Does the no-bounce effect always happen at the same wall? If so, can you just copy the 1st wall and put it in place of the second one to see if there is something wrong with this specific wall.
If not to much effort, I would try to set up some standard cubes as walls just to be sure that transform.scale is not to blame for it (I made really bad experience with this).
Do you manipulate gravity or TimeManager.timeScale from within a script?
BTW: are you using gravity? (Should be no problem just