ModelToViewCoordinates.init(modelBounds:,viewBounds:)
The ModelToViewCoordinates
struct contains the following initializer:
/**
Create a transformation that maps the points inside the
modelBounds rectangle to the greatest possible area inside
of the viewBounds rectangle.
...
*/
public init(modelBounds: CGRect, viewBounds: CGRect)
You will use this for the “zoom to max” feature at the end of Part 2.
This initializer is the most subtle part of ModelToViewCoordinates
, so you may want to implement it after the other methods.
And there are a number of ways to compute the zoomScale
and viewOffset
properties described in the documentation. My testBounds()
unit test for this initializer assumes that you set zoomScale
and viewOffset
so that the center point of the modelBounds
rectangle will be translated to be at the center point of the viewBounds
rectangle. While not strictly necessary, adopting the same strategy will enable you to pass the testBounds()
unit test without changing it. Below is more detail about each of the four cases tested in testBounds()
to illustrate how this initializer behaves:
Let
t1 = ModelToViewCoordinates(modelBounds: b1, viewBounds: b2)
whereb1 = CGRect(x: 0, y: 0, width: 400, height: 200) b2 = CGRect(x: 0, y: 0, width: 200, height: 100)
In this case,
t1.zoomScale = 0.5
. With that zoom scale, the center ofb1 = (200, 100)
is scaled to be at the center ofb2 = (100, 50)
, so no offset is needed, andt1.viewOffset = (0,0)
.The following shows how the center, top-left, and bottom-right points of
b1
are translated intob2
’s coordinates. Note that we cover all ofb2
withb1
’s translation.Let
t2 = ModelToViewCoordinates(modelBounds: b1, viewBounds: b3)
whereb1 = CGRect(x: 0, y: 0, width: 400, height: 200) b3 = CGRect(x: 0, y: 0, width: 200, height: 50)
In this case,
t2.zoomScale = 0.25
. With that zoom scale, the center ofb1 = (200, 100)
is scaled to be at(50, 25)
. However, the center ofb3 = (100, 25)
, so we must offset the scaled center ofb1
byt2.viewOffset = (50, 0)
to get the centers to align properly. Given this offset, the origin(0,0)
inb1
’s coordinate system appears at(50,0)
inb1
’s coordinate system.The following shows how the center, top-left, and bottom-right points of
b1
are translated intob3
’s coordinates. In this case, some ofb3
is not covered byb1
’s translation.Let
t3 = ModelToViewCoordinates(modelBounds: b4, viewBounds: b1)
whereb4 = CGRect(x: -1, y: -1, width: 2, height: 2) b1 = CGRect(x: 0, y: 0, width: 400, height: 200)
In this case,
t3.zoomScale = 100
. With that zoom scale, the center ofb4 = (0, 0)
is scaled to be at(0, 0)
. However, the center ofb1 = (200, 100)
, so we must offset the scaled center ofb4
byt3.viewOffset = (200, 100)
to get the centers to align properly. Given this offset, the origin(0,0)
inb4
’s coordinate system appears at(200, 100)
inb1
’s coordinate system.The following shows how the center, top-left, and bottom-right points of
b4
are translated intob1
’s coordinates:Let
t4 = ModelToViewCoordinates(modelBounds: b4, viewBounds: b3)
whereb4 = CGRect(x: -1, y: -1, width: 2, height: 2) b3 = CGRect(x: 0, y: 0, width: 200, height: 50)
In this case,
t4.zoomScale = 25
. With that zoom scale, the center ofb4 = (0, 0)
is scaled to be at(0, 0)
. However, the center ofb3 = (100, 25)
, so we must offset the scaled center ofb4
byt4.viewOffset = (100, 25)
to get the centers to align properly. Given this offset, the origin(0,0)
inb4
’s coordinate system appears at(100, 25)
inb3
’s coordinate system.The following shows how the center, top-left, and bottom-right points of
b4
are translated intob3
’s coordinates: