Change measurement unit of Ruler in NSScrollview - objective-c

Im trying to make a drawing application. So i have a subclass of NSScrollView that i use to show the rulers.
[self setHasHorizontalRuler: true];
[self setHasVerticalRuler:YES];
[self setRulersVisible:true];
[self setAutoresizesSubviews:YES];
The problem is that the numbers of the ruler have different units that the ones i use to draw. Here the points i wanted to draw are (0,0) (22,12) and (5,7)
I know theres a register measurement unit and a set for NSRulerView and some default units, but i can't find what are the default ones, or any example of how can i use it in an NSScrollView class. Should i just multiply every coordinate for a constant? In that case what constant is that?

The default units are listed in the description of the registerUnitWithName:abbreviation:unitToPointsConversionFactor:stepUpCycle:stepDownCycle: class method, and the current ruler unit can be found from the property measurementUnits.
The description tells you the Points/Unit for each pre-defined Unit Name. The measurement unit of your drawing view is points, so to draw in ruler units take your location and multiply each coordinate by the Points/Unit for the measurementUnits of the appropriate ruler (horizontal/vertical). E.g. consider your location(5, 7) with the ruler units set to Centimeters then the Points/Unit are 28.35 and your location is (141.75, 198.44) in points.
HTH

Related

Difficulties understanding MapKit Coordinate System

I read the apple docs
"A map point is an x and y value on the Mercator map projection"
A point is a graphical unit associated with the coordinate system of a UIView
What is the difference logically between a Point and a MKPoint?
I obviously need CGPoint to display something on the screen.
So why does MapKit need MKMapPoint?
The fact that both the CGPoint and MKMapPoint structs happen to store two floating-point values named x and y is irrelevant.
They are given different names because they logically deal with different coordinate systems, transformations, ranges and scales.
A 2D world map needs a large, fixed coordinate system that allows a latitude and longitude to be converted to a fixed point on the map regardless of what portion is currently being displayed on the screen.
The range of MKMapPoint values are large since they need to represent the world's coordinates at a high-enough resolution (well beyond screen sizes).
However, you don't exactly need to care about the actual values of an MKMapPoint. Occasionally, you may need to convert a CLLocationCoordinate2D to an MKMapPoint (or the other way around) but you don't need to worry about those values nor should you store them (the docs recommend not doing this since the internal projection calculations to convert a latitude and longitude to a 2D projection may change between iOS releases).
Your usage of an MKMapPoint is only on the basis that you are dealing with the map's 2D projection independent of the device's screen size or what portion of the map is currently displaying.
I obviously need CGPoint to display something on the screen.
Yes but when adding annotations or overlays, you generally deal with CLLocationCoordinate2D values and let the map view do the conversion as needed.
MKMapPoint is a geographical point - projectively converted latitude and longitude. On the screen you have some bounded view containing your mapView. And you need to convert your geographical position (coord) to the CGPoint on your mapView
CLLocationCoordinate2D coord;
coord.latitude = location.latitude.doubleValue;
coord.longitude = location.longitude.doubleValue;
MKMapPoint point = MKMapPointForCoordinate(coord);
CGPoint cgpoint = [mapView convertCoordinate:coord toPointToView:mapView];

Visualizing the Anchor Point of a UIImageView

Is there an easy way of putting a mark (like a cross for example) on the anchor point of an UIImageView? I'm trying to line up several rotating images by their anchor point, and being able to see these points would make the job a lot easier.
Many thanks.
You are asking how to visualize the anchor point within a view but it seem to me that you are asking for it so that you can help align the anchor points. I'll try and answer both questions.
Visualizing the anchor point.
Every view on iOS have an underlying layer that has an anchor point. The anchor point is in unit coordinate space of the layer (x and y goes from 0 to 1). This means that you can multiply x by the width and y by the height to get the position of the anchor point inside the layer in the coordinate space of the view/layer. You can then place a subview/sublayer there to show the location of the anchor point.
In code you could do something like this to display a small black dot where the anchor point is.
CALayer *anchorPointLayer = [CALayer layer];
anchorPointLayer.backgroundColor = [UIColor blackColor].CGColor;
anchorPointLayer.bounds = CGRectMake(0, 0, 6, 6);
anchorPointLayer.cornerRadius = 3;
CGPoint anchor = viewWithVisibleAnchorPoint.layer.anchorPoint;
CGSize size = viewWithVisibleAnchorPoint.layer.bounds.size;
anchorPointLayer.position = CGPointMake(anchor.x * size.width,
anchor.y * size.height);
[viewWithVisibleAnchorPoint.layer addSublayer:anchorPointLayer];
You can see the result in the image below for four different rotations.
Aligning layers by their anchor point
That is cool and all but it's actually easier then that to align anchor points.
The key trick is that the position and the anchorPoint is always the same point, only in two different coordinate spaces. The position is specified in the coordinate space of the super layer. The anchor point is specified in the unit coordinate space of the layer.
The nice thing about this is that views that have their position property aligned will automatically have their anchorPoint aligned. Note that the content is drawn relative to the anchor point. Below is an example of a bunch of views that all have the same y component of their position, thus they are aligned in y.
There really isn't any special code to do this. Just make sure that the position properties are aligned.

Three.js camera tilt up or down and keep horizon level

camera.rotate.y pans left or right in a predictable manner.
camera.rotate.x looks up or down predictably when camera.rotate.y is at 180 degrees.
but when I change the value of camera.rotate.y to some new value, and then I change the value of camera.rotate.x, the horizon rotates.
I've looked for an algorithm to adjust for horizon rotation after camera.rotate.x is changed, but haven't found it.
In three.js, an object's orientation can be specified by its Euler rotation vector object.rotation. The three components of the rotation vector represent the rotation in radians around the object's internal x-axis, y-axis, and z-axis respectively.
The order in which the rotations are performed is specified by object.rotation.order. The default order is "XYZ" -- rotation around the x-axis occurs first, then the y-axis, then the z-axis.
Rotations are performed with respect to the object's internal coordinate system -- not the world coordinate system. This is important. So, for example, after the x-rotation occurs, the object's y- and z- axes will generally no longer be aligned with the world axes. Rotations specified in this way are not unique.
So, for example, if in code you specify,
camera.rotation.y = y_radians; // Y first
camera.rotation.x = x_radians; // X second
camera.rotation.z = 0;
the rotations are applied in the object's rotation.order, not in the order you specified them.
In your case, you may find it more intuitive to set rotation.order to "YXZ", which is equivalent to "heading, pitch, and roll".
For more information about Euler angles, see the Wikipedia article. Three.js follows the Tait–Bryan convention, as explained in the article.
three.js r.61
I've been looking for the same info for few days now, the trick is: use regular rotateX to look up/down, but use rotateOnWorldAxis(new THREE.Vector3(0.0, 1.0, 0.0), angle) for horiz turn (https://discourse.threejs.org/t/vertical-camera-rotation/15334).

iOS map location with x.y

I have an array of x,y points of location. I don't know how to use it because it's not long/lat.
for example: X=217338 , Y=703099
I want to know how to use it on the iphone SDK and with which framework?
Thanks in advance!
First you need to know in which format your values are.
If they are not lon/lat they can be anything like meters or inches or half arm lengths or even normalized doughnut holes.
In any case you need to come up with an conversion method because MKMapKit only understands geo coordinates (long/lat).
If you have clarified that you should take a look at the location awarness guide from apple. There are also some other good sources for mapkit stuff like raywenderlich.com.
Without knowing what is represented by those values, there isn't really anything you can do with them. Assuming you can convert them to Latitude/Longitude values, this is how you'd be able to center your map at that (X, Y) coordinate:
//Import the <MapKit/MapKit.h> and <CoreLocation/CoreLocation.h> framework
//and then this will go in your implementation file:
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(xConvertedToLat, yConvertedToLong);
//Set the region your map will display centered on the above coord and spanning 250m on x-axis and 250 on y-axis
MKCoordinateRegion region = MKCoordinateRegionMake(coord, 250, 250);
//You should have a MKMapView object
[myMapView setRegion:region animated:YES];
You can iterate through this for each object in your array, but you won't see anything appear until the last (x, y) coordinate is set.

Convert point coordinates to a new coordinate system

Let's say I have point which has the coordinates (50,100) where (0,0) is in the upper left corner of a view.
How can I get the coordinates of the same point if I want the beginning of the coordinate system to be the center of the screen (ie width/2, height/2) ?
Note that I am implementing a custom View and I am drawing inside it and I just want to convert the coordinate inside that same view. I am basically implementing a graphic calculator and I need to have my coordinate system to start in the middle of the screen so the graphics could look better.
I notice you tagged it as iOS problem, so use the method Apple have built in UIView:
(CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view
Find the midpoint you will be using, so for a 100x100 screen, this would be (50,50). Then take the point you need to convert and subtract the midpoint X value from the point X value, and then subtract the point Y value from the midpoint Y value. Notice that you are not doing the same operation on both values.
So if the point is (30,25) the new point would be (-20,25) because 30 - 50 = -20 and 50 - 25 = 25.