Force compass north to portrait in samsung tablets - compass-geolocation

I've implented an app that only works in portrait mode. The app have a compass, we know that compass in samsungs tablets (e.g: samsung galaxy tab 2) and mobile devices works different, ones have NORTH (0º) in landscape an others in portrait.
We need to have all in portrait mode, in other words, we want that the NORTH (0º) in PORTRAIT. Anyone have a solution for that ?

I had the same issue with a Galaxy Note and followed advice on how to determine tablet or phone. This was in another posting but can't remember the link. The code looks like this:
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
double inches = Math.sqrt((metrics.widthPixels * metrics.widthPixels)
+ (metrics.heightPixels * metrics.heightPixels))
/ metrics.densityDpi;
// tablets typically larger than 6"" diagonally
// this is attempt to orient both player and magnetic sensors
if (inches > 6) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
After doing this, I translated the azimuth setting in the sensorlistener code:
public void onSensorChanged(SensorEvent event) {
// Note: Not all sensor events will supply both accelerometer and
// mag-field
int s = event.sensor.getType();
switch (s) {
case Sensor.TYPE_ACCELEROMETER:
aValues = lowPass(event.values.clone(), aValues);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
mValues = lowPass(event.values.clone(), mValues);
break;
}
float[] R = new float[16]; // Rotation Matrix result goes here
float[] I = new float[9]; // Inclination Matrix result goes here
float[] oValues = new float[3]; // used for new orientation
boolean success = SensorManager.getRotationMatrix(R, I, aValues,
mValues);
// if both aValues and mValues are not null success will be true
// Also returns the Inclination Matrix
if (success) {
// Now get the device's orientation from the Rotation and
// Inclination Matrices
SensorManager.getOrientation(R, oValues);
// Change Radians to Degrees
oValues[0] = (360 + (float) Math.toDegrees(oValues[0])) % 360;
oValues[1] = (float) Math.toDegrees(oValues[1]);
oValues[2] = (float) Math.toDegrees(oValues[2]);
azimuth = oValues[0];//
y_az = oValues[1];// orientationValues[1];
z_az = oValues[2];// =
// test portrait or landscape (different on Tablets)
int test = getResources().getConfiguration().orientation;
// if necessary, azimuth = azimuth+270f or + 90f %360
heading.setText("X:" + Math.round(azimuth) + " Y:"
+ Math.round(y_az) + " Z: " + Math.round(z_az)
+ " degrees");
}
}
I ended up letting the tablet stay in landscape mode since most users would orient it that way and North is at the top of the landscape. I hope my rookie code (with plenty of help from others) can help you.

Related

Angular9 Signature Pad issue: Signature drawn offset from pen touch

I implemented a signature pad using https://github.com/ramsatt/Angular9SignaturePad/tree/master/src/app/_componets/signature-pad and it works fine on smaller devices but on iPad or bigger devices like 7" upwards, it doesn't work properly.
When drawing on the screen, the resulting line has an offset from where the user touched (Signature drawn doesn't appear directly under the pen as user draws).
please how can I fix this.
So I fixed it by adding the below code and calling it in ngOnInit
resizeCanvas() {
var width = this.signaturePadElement.nativeElement.width;
var height = this.signaturePadElement.nativeElement.height;
var ratio = Math.max(window.devicePixelRatio || 1, 1);
if (ratio <= 2) {
this.signaturePadElement.nativeElement.width = width * ratio;
this.signaturePadElement.nativeElement.height = height * ratio;
this.signaturePadElement.nativeElement
.getContext("2d")
.scale(ratio, ratio);
}
then do
ngOnInit(){
this.resizeCanvas()
}
this.signaturePadElement is your Element gotten using ViewChild()

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).

Pixel perfect 2d camera in unity

I have a very simple script that updates my orthographic camera on a given resolution so that it accurately scales the view to be pixel perfect.
Here is some relevant code:
OrthographicSetting get_override(int size)
{
return Overrides.FirstOrDefault(x => x.OrthographicSize == size);
}
void update_ortho()
{
m_last_size = Screen.height;
float ref_size = (OrthographicSize / PixelsPerUnit) * 0.5f;
OrthographicSetting or = get_override(m_last_size);
float ppu = or != null ? or.PixelsPerUnit : PixelsPerUnit;
float ortho_size = (m_last_size / ppu) * 0.5f;
float multiplier = Mathf.Max(1, Mathf.Round(ortho_size / ref_size));
ortho_size /= multiplier;
this.GetComponent<Camera>().orthographicSize = ortho_size;
Debug.Log(m_last_size + " " + ortho_size + " " + multiplier + " " + ppu);
}
[System.Serializable]
public class OrthographicSetting
{
public int OrthographicSize;
public float PixelsPerUnit;
}
OrthographicSetting get_override(int size)
{
return Overrides.FirstOrDefault(x => x.OrthographicSize == size);
}
With this, i can specify a set of overrides for every resolution.
My current setup is using 100 pixels per unity unit. All of my sprites use point filtering with no compression. Yet i still get strange results. 90% of the sprites render fine, but some seem to be rendering incorrectly.
Here's a screenshot to illustrate:
I may have solved the problem. I was using a sprite shader with pixel snap turned on. if i turn off pixel snap the problem seems to more or less go away. I still get the occasional problem with game objects that aren't in "nice" positions, i dunno how to avoid that problem though...

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.

cocos2dx: Sprite3D rotating, culling error

Hi I'm trying to have 2 sprites with different z in 3d world and a camera that rotates around the center of the screen and points at the center of the screen.
Even if the sprites has different z (and zorder, I don't know if this is necessary) the sprites are always visualized while I'm expecting to have the second sprite hided from the other...
This is helloworld layer init
auto sp3d = Sprite3D::create();
sp3d->setPosition(visibleSize.width/2, visibleSize.height/2);
addChild(sp3d);
auto sprite = Sprite::create("JP9_table.png");
auto spritePos = Vec3(0,0,0);
sprite->setScale(0.3);
sprite->setPosition3D(spritePos);
sp3d->addChild(sprite,0);
auto sprite2 = Sprite::create("JP9_logo_yc.png");
auto spritePos2 = Vec3(0,0,10);
sprite2->setPosition3D(spritePos2);
sp3d->addChild(sprite2,10);
sp3d->setCullFace(GL_BACK);
sp3d->setCullFaceEnabled(true);
this->setCameraMask((unsigned short)CameraFlag::USER2, true);
camera = Camera::createPerspective(60, (float)visibleSize.width/visibleSize.height, 1.0, 1000);
camera->setCameraFlag(CameraFlag::USER2);
camera->setPosition3D(spritePos + Vec3(-200,0,800));
camera->lookAt(spritePos, Vec3(0.0,1.0,0.0));
this->addChild(camera);
this->scheduleUpdate();
angle=0;
and this is update:
void TestScene::update(float dt)
{
angle+=0.1;
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
Vec3 spritePos=Vec3(visibleSize.width/2,visibleSize.height/2,0);
camera->setPosition3D(Vec3(visibleSize.width/2,visibleSize.height/2,0) + Vec3(800*cos(angle),0,800*sin(angle)));
camera->lookAt(spritePos, Vec3(0.0,1.0,0.0));
}
I have tryed something simplier:
auto sp3d = Sprite3D::create();
sp3d->setPosition(visibleSize.width/2, visibleSize.height/2);
addChild(sp3d);
auto sprite = Sprite::create("JP9_table.png");
auto spritePos = Vec3(0,0,0);
sprite->setScale(0.3);
sprite->setPosition3D(spritePos);
sp3d->addChild(sprite,0);
auto sprite2 = Sprite::create("JP9_logo_yc.png");
auto spritePos2 = Vec3(0,0,10);
sprite2->setPosition3D(spritePos2);
sp3d->addChild(sprite2,10);
sp3d->setCullFace(GL_BACK);
sp3d->setCullFaceEnabled(true);
even with sp3d->runAction(RotateTo::create(20,vec3(0,3000,0))) same error.
Is it a cocos2dx bug?
the sprite with z=10 disappear before it is covered by the other sprite...
remain hidden for a while, and when it should be hidden completely reappear!!!
Do I have forgot something?
thanks
Maybe you should check this.
_camControlNode = Node::create();
_camControlNode->setNormalizedPosition(Vec2(.5,.5));
addChild(_camControlNode);
_camNode = Node::create();
_camNode->setPositionZ(Camera::getDefaultCamera()->getPosition3D().z);
_camControlNode->addChild(_camNode);
auto sp3d = Sprite3D::create();
sp3d->setPosition(s.width/2, s.height/2);
addChild(sp3d);
auto lship = Label::create();
lship->setString("Ship");
lship->setPosition(0, 20);
sp3d->addChild(lship);
and
_lis->onTouchMoved = [this](Touch* t, Event* e) {
float dx = t->getDelta().x;
Vec3 rot = _camControlNode->getRotation3D();
rot.y += dx;
_camControlNode->setRotation3D(rot);
Vec3 worldPos;
_camNode->getNodeToWorldTransform().getTranslation(&worldPos);
Camera::getDefaultCamera()->setPosition3D(worldPos);
Camera::getDefaultCamera()->lookAt(_camControlNode->getPosition3D());
};