Angular OpenLayers - Zoom to box with bounds - openlayers-3

I tried to figure out how to zoom the map to box with bounds but couldn't find a good example.
I tried with
angular.extend($scope, {
offset: 0,
center: {
lat: 30.0047,
lon: 31.2586,
bounds: [30.566461328125,
29.766565657014183,
31.950738671875005,
30.242264176913594]
}
});
How can I set themap to zoom to the bounding box without complicate conversion of the 4 bounds to (center, zoom)?

I'm pretty sure you want
map.getView().fit(
ol.proj.transformExtent([ x1, y1, x2, y2 ], 'EPSG:COORDS', 'EPSG:MAP'),
map.getSize()
);
This is after your map exists, not on initialization.
http://openlayers.org/en/master/apidoc/ol.View.html#fit

Related

Why do we need `rotateToARCamera` in Apple's `Visualizing a Point Cloud Using Scene Depth` sample code?

Sample code: https://developer.apple.com/documentation/arkit/visualizing_a_point_cloud_using_scene_depth
In the code, when unprojecting depthmap into world point, we are using a positive z value(depth value). But in my understanding, ARKit uses right-handed coordinate system which means points with positive z value are behind the camera. So maybe we need to do some extra work to align the coordinate system(using rotateToARCamera matrix?). But I cannot understand why we need to flip both Y and Z plane.
static func makeRotateToARCameraMatrix(orientation: UIInterfaceOrientation) -> matrix_float4x4 {
// flip to ARKit Camera's coordinate
let flipYZ = matrix_float4x4(
[1, 0, 0, 0],
[0, -1, 0, 0],
[0, 0, -1, 0],
[0, 0, 0, 1] )
let rotationAngle = Float(cameraToDisplayRotation(orientation: orientation)) * .degreesToRadian
return flipYZ * matrix_float4x4(simd_quaternion(rotationAngle, Float3(0, 0, 1)))
}
Update: I guess the key point is the coordinate system used for camera intrinsics matrix's pin-hole model has an inverse direction compared to the normal camera space in ARKit.
Depth Map is a coordinate system where the Y coordinate is smaller at the top and larger at the bottom like image data, but ARKit is a coordinate system where the Y coordinate is smaller from the bottom and larger at the top.
For this reason, I think it is necessary to invert the Y coordinate.

Why is my shape distorted on rotation about the z axis?

I just started learning metal and can best show you my frustration with the following series of screenshots. From top to bottom we have
(1) My model where the model matrix is the identity matrix
(2) My model rotated 60 deg about the x axis with orthogonal projection
(3) My model rotated 60 deg about the y axis with orthogonal projection
(4) My model rotated 60 deg about the z axis
So I use the following function for conversion into normalized device coordinates:
- (CGPoint)normalizedDevicePointForViewPoint:(CGPoint)point
{
CGPoint p = [self convertPoint:point toCoordinateSpace:self.window.screen.fixedCoordinateSpace];
CGFloat halfWidth = CGRectGetMidX(self.window.screen.bounds);
CGFloat halfHeight = CGRectGetMidY(self.window.screen.bounds);
CGFloat px = ( p.x - halfWidth ) / halfWidth;
CGFloat py = ( p.y - halfHeight ) / halfHeight;
return CGPointMake(px, -py);
}
The following rotates and orthogonally projects the model:
- (matrix_float4x4)zRotation
{
self.rotationZ = M_PI / 3;
const vector_float3 zAxis = { 0, 0, 1 };
const matrix_float4x4 zRot = matrix_float4x4_rotation(zAxis, self.rotationZ);
const matrix_float4x4 modelMatrix = zRot;
return matrix_multiply( matrix_float4x4_orthogonal_projection_on_z_plane(), modelMatrix );
}
As you can see when I use the exact same method for rotating about the other two axes, it looks fine-not distorted. What am I doing wrong? Is there some sort of scaling/aspect ratio thing I should be setting somewhere? What things could it be? I've been staring at this for an embarrassingly long period of time so any help/ideas that can lead me in the right direction are much appreciated. Thank you in advance.
There's nothing wrong with your rotation or projection matrices. The visual oddity arises from the fact that you move your vertices into NDC space prior to rotation. A rectangle doesn't preserve its aspect ratio when rotating in NDC space, because the mapping from NDC back to screen coordinates is not 1:1.
I would recommend not working in NDC until the very end of the vertex pipeline (i.e., pass vertices into your vertex function in "world" space, and out to the rasterizer as NDC). You can do this with a classic construction of the orthographic projection matrix that scales and biases the vertices, correctly accounting for the non-square aspect ratio of window coordinates.

Is there a way to make a SKSpriteNode's rotation parallel to another SKSpriteNode's physics body?

Just what it says in the title, is there any way to do this kind of thing:
Is there any way to do this? If so, how would I correspond the SKAction rotateToAngle to the side facing the circle?
Thanks!
The tangent of a circle at any given point is perpendicular to a radius drawn to that point. Consider the two nodes as being in a polar coordinate system, with the origin at the center of the circle. You can convert the square's cartesian coordinates (at its center) to polar and find the angle of the proper radius:
void cartopol(CGFloat x, CGFloat y, CGFloat *radius, CGFloat *theta)
{
*radius = sqrt(x*x, y*y);
*theta = atan2(y, x);
}
(This could instead return a CGPoint if you prefer that to using out parameters, as I'll do below for the complementary function; the arithmetic is the important point.)
theta will be in radians; add or subtract π/4 to rotate it by 90˚.
To move the square around the circle, pick the angle and radius you want and convert from polar to cartesian:
CGPoint poltocar(CGFloat radius, CGFloat theta)
{
return (CGPoint){radius * cos(theta), radius * sin(theta)};
}
Very easy: add the rectangle sprite (it should not have a physics body of its own, though you could try to see if it works with a static body) as child node to the circle sprite with the physics body. Change the rectangle sprite's position to be offset from the center of its parent node, ie {100, 0} to put the circle node 100 points away from the center.
As the circle sprite & body rotate, the rectangle sprite will move and rotate along with it.

How Can I Perform a Perspective Transform Using a Homography Matrix (3x3) in JavaCV?

I have been trying for some time now to take an image of a pool table from an arbitrary angle, locate four coordinate pairs (x,y) of the corners, and rotate/warp the image such that the resulting image contains only the table from a bird's eye view. I am using JavaCV to accomplish this task. So far, I have written code which successfully calculates the four corners of the table as shown below (I have coded red cvCircles of radius 25 on the four corners).
After finding my four corners:
Corner 1 (Bottom Right)
X: 3234 Y: 1858
Corner 2 (Bottom Left)
X: 0 Y: 1801
Corner 3 (Top Right)
X: 2722 Y: 1069
Corner 4 (Top Left)
X: 523 Y: 1030
I attempted to use cvFindHomography and then cvWarpPerspectve to accomplish this. My code can be found below:
// Initialize Table Corners as Image Coordinates
float[] aImg = {
corners.get(0).x(), corners.get(0).y(), // BR X: 3234 Y: 1858
corners.get(1).x(), corners.get(1).y(), // BL X: 0 Y: 1801
corners.get(2).x(), corners.get(2).y(), // TR X: 2722 Y: 1069
corners.get(3).x(), corners.get(3).y() // TL X: 523 Y: 1030
};
// Initialize World Coordinates (Are these even correct? How do I determine these?)
float[] aWorld = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f,1.0f
};
// Create 3x3 Homography Matrix
CvMat homography = cvCreateMat(3, 3, opencv_core.CV_32FC1);
opencv_imgproc.cvGetPerspectiveTransform(aImg, aWorld, homography);
System.out.println(homography.toString());
// Create imgWarped and Warp Perspective
IplImage imgWarped = cvCreateImage(cvGetSize(img), 8, 3);
opencv_imgproc.cvWarpPerspective(img, imgWarped, homography, opencv_imgproc.CV_INTER_LINEAR, CvScalar.ZERO);
// Create Canvas and Display Image
CanvasFrame canvas = new CanvasFrame("Warped Image");
canvas.showImage(imgWarped);
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
The 3x3 Homography Matrix I'm obtaining is:
[ 0.0011688289, 7.928632E-4, -1.4279466
-8.698455E-5, 0.0049045905, -5.006235
-2.8205379E-5, 0.0015696458, 1.0 ]
**Unfortunately, the result is a purely black image containing nothing. Am I approaching this incorrectly? Any advice, code, pseudocode, etc. would be GREATLY APPRECIATED!
Thank you so much for reading.**

When drawing an arc using CGContextAddArcToPoint(), what does (x1,y1) and (x2,y2) mean?

You can use the following code to draw an arc using Quartz:
CGContextMoveToPoint(context2, x, y);
CGContextAddArcToPoint(context2, x1, y1, x2, y2, r);
In these functions, (x,y) is the starting point and r is the arc radius but what are (x1,y1) and (x2,y2)?
AddArcToPoint works like this:
where P1 is the point the path is currently at, r is the radius given to the function, and the red line is the line that addArcToPoint will add to the current path. It won't continue to the second point at x2, y2; it will stop at the end of the arc.
I have a blog post about this here.
http://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextAddArcToPoint
x1: The x-value, in user space coordinates, for the end point of the first tangent line. The first tangent line is drawn from the current point to (x1,y1).
y1: The y-value, in user space coordinates, for the end point of the first tangent line. The first tangent line is drawn from the current point to (x1,y1).
x2: The x-value, in user space coordinates, for the end point of the second tangent line. The second tangent line is drawn from (x1,y1) to (x2,y2).
y2: The y-value, in user space coordinates, for the end point of the second tangent line. The second tangent line is drawn from (x1,y1) to (x2,y2).
Here's code I just built to solve this, approaching it from the center-of-circle perspective, with declarations and sample values:
CGPoint arcCenter = CGPointMake(30,20);
float arcLengthRad = M_PI_4; // Whatever, the full span of the arc in radians
float radius = 10;
float arcCenterRad = M_PI_2; // the angle of the center of the arc, in radians
float arcP1hyp = 1/cos(arcLengthRad/2) * radius;
float arcP1x = arcCenter.x + cosf(arcCenterRad)*arcP1hyp;
float arcP1y = arcCenter.y + sinf(arcCenterRad)*arcP1hyp;
float arcP2tx = arcCenter.x + cosf(arcCenterRad+(arcLengthRad/2))*radius;
float arcP2ty = arcCenter.y + sinf(arcCenterRad+(arcLengthRad/2))*radius;
float arcP2x = (arcP1x - arcP2tx)*-1 + arcP2tx;
float arcP2y = (arcP1y - arcP2ty)*-1 + arcP2ty;
CGContextAddArcToPoint(context,
arcP1x,
arcP1y,
arcP2x,
arcP2y,
radius);
So the above code should produce a small, 45-degree angle arc at the top of a circle.
Edited:
In response to a comment received, the super-concise code listed above is shown below, with comments and wrapped in a method (plus a minor adjustment to the arcP2 calculation)
/*
EOTContext:addArcWithCenter:arcLength:radius:arcMiddlePointAngle:
Use this method for building a circle with breaks at certain points,
for example to use other CGContext methods to draw notches in the
circle, or protruding points like gear teeth.
This method builds up the values to use in CGContextAddArcToPoint(),
which are the x and y coordinates of two points. First added to
the current point in context, form two lines that are the tangents of
the entry and exit angles of the arc.
This method's arguments define the length of the arc in radians, and
the position of start and end using the angle centerpoint of the arc.
This is useful when drawing a certain defined amount of gear teeth,
rotating around the circle.
It is beyond this method's scope to maintain or calculate the
centerpoint relative to an arbitrary current point in the context, because this
is primarily used for drawing a gear/notch circle.
*/
-(void)EOTContext:(CGContext*)context
addArcWithCenter:(CGPoint)arcCenter
arcLength:(CGFloat)arcLengthRad
radius:(CGFloat)radius
arcMiddlePointAngle:(CGFloat)arcCenterRad {
/*
Calculate the hypotenuse of the larger, outer circle where the
points of the tangent lines would rest upon (imagine wrapping
the drawn circle in a bounding regular convex polygon of tangent
lines, then wrap that polygon in an outer circle)
*/
float arcP1hyp = 1/cos(arcLengthRad/2) * radius;
// Build first tangent point
CGPoint arcP1 = (CGPoint){
arcCenter.x + cosf(arcCenterRad)*arcP1hyp,
arcCenter.y + sinf(arcCenterRad)*arcP1hyp
};
// Build the final endpoint of the arc
CGPoint arcP2final = (CGPoint){
arcCenter.x + cosf(arcCenterRad+(arcLengthRad/2))*radius,
arcCenter.y + sinf(arcCenterRad+(arcLengthRad/2))*radius
};
// Build second tangent point using the first tangent point and the final point of the arc.
// This point is resting on the bounding outer circle like arcP1 is.
// This would also work using the final point itself, using the simple assignment of arcP2 = arcP2final;
// or of course simply omitting arcP2 altogether.
CGPoint arcP2 = (CGPoint){
(arcP2final.x - arcP1.x) + arcP2final.x,
(arcP2final.y - arcP1.y) + arcP2final.y
};
// The following adds an arc of a circle to the current path, using a radius and tangent points.
CGContextAddArcToPoint(context,
arcP1.x,
arcP1.y,
arcP2.x,
arcP2.y,
radius);
}
I the apple documentation it described briefly.
http://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextAddArcToPoint
x1: The x-value, in user space coordinates, for the end point of the first tangent line. The first tangent line is drawn from the current point to (x1,y1).
y1: The y-value, in user space coordinates, for the end point of the first tangent line. The first tangent line is drawn from the current point to (x1,y1).
x2: The x-value, in user space coordinates, for the end point of the second tangent line. The second tangent line is drawn from (x1,y1) to (x2,y2).
y2: The y-value, in user space coordinates, for the end point of the second tangent line. The second tangent line is drawn from (x1,y1) to (x2,y2).

Resources