70
|
1 module doodle.tk.pixel_model;
|
|
2
|
|
3 public {
|
|
4 import doodle.tk.geometry;
|
|
5 }
|
|
6
|
|
7 // FIXME consider using the term Screen instead of Pixel...
|
|
8
|
|
9 class PixelModel {
|
|
10 this(in double zoom, in Rectangle canvasBounds, in Rectangle viewBounds) {
|
|
11 _zoom = zoom;
|
|
12 _viewBounds = viewBounds;
|
|
13 _canvasBounds = canvasBounds;
|
|
14
|
|
15 _viewCentre = _canvasBounds.centre;
|
|
16 }
|
|
17
|
|
18 void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) {
|
|
19 Rectangle r = pixelToModel(_viewBounds);
|
|
20 _canvasBounds = r | requiredCanvasBounds;
|
|
21 }
|
|
22
|
|
23 // For normalZoom 1.0 -> 100% means the presentation on the screen is
|
|
24 // one-to-one with real-life
|
|
25 double normalZoom(in double pixelsPerMillimetre) { return _zoom / pixelsPerMillimetre; }
|
|
26
|
|
27 Point modelToPixel(in Point model) const { return _viewBounds.centre + _zoom * (model - _viewCentre); }
|
|
28 Point pixelToModel(in Point pixel) const { return _viewCentre + (pixel - _viewBounds.centre) / _zoom; }
|
|
29 Vector modelToPixel(in Vector model) const { return _zoom * model; }
|
|
30 Vector pixelToModel(in Vector pixel) const { return pixel / _zoom; }
|
|
31 Rectangle modelToPixel(in Rectangle model) const { return Rectangle(modelToPixel(model.position), modelToPixel(model.size)); }
|
|
32 Rectangle pixelToModel(in Rectangle model) const { return Rectangle(pixelToModel(model.position), pixelToModel(model.size)); }
|
|
33
|
|
34 private {
|
|
35 // Screen units are pixels
|
|
36 // Model units are millimetres
|
|
37 double _zoom; // pixels-per-millimetre
|
|
38 Rectangle _viewBounds; // pixel: bounds of the viewport in pixels
|
|
39 Point _viewCentre; // model: where in the model is the centre of our view
|
|
40 Rectangle _canvasBounds; // model: the bounds of the canvas in millimetres
|
|
41 }
|
|
42 }
|