view doodle/tk/pixel_model.d @ 70:0e61702c6ea6

Checkpoint
author "David Bryant <bagnose@gmail.com>"
date Sat, 14 Aug 2010 20:05:55 +0930
parents
children 0f7cf6c6f206
line wrap: on
line source

module doodle.tk.pixel_model;

public {
    import doodle.tk.geometry;
}

// FIXME consider using the term Screen instead of Pixel...

class PixelModel {
    this(in double zoom, in Rectangle canvasBounds, in Rectangle viewBounds) {
        _zoom = zoom;
        _viewBounds = viewBounds;
        _canvasBounds = canvasBounds;

        _viewCentre = _canvasBounds.centre;
    }

    void consolidateCanvasBounds(in Rectangle requiredCanvasBounds) {
        Rectangle r = pixelToModel(_viewBounds);
        _canvasBounds = r | requiredCanvasBounds;
    }

    // For normalZoom 1.0 -> 100% means the presentation on the screen is
    // one-to-one with real-life
    double normalZoom(in double pixelsPerMillimetre) { return _zoom / pixelsPerMillimetre; }

    Point modelToPixel(in Point model) const { return _viewBounds.centre + _zoom * (model - _viewCentre); }
    Point pixelToModel(in Point pixel) const { return _viewCentre + (pixel - _viewBounds.centre) / _zoom; }
    Vector modelToPixel(in Vector model) const { return _zoom * model; }
    Vector pixelToModel(in Vector pixel) const { return pixel / _zoom; }
    Rectangle modelToPixel(in Rectangle model) const { return Rectangle(modelToPixel(model.position), modelToPixel(model.size)); }
    Rectangle pixelToModel(in Rectangle model) const { return Rectangle(pixelToModel(model.position), pixelToModel(model.size)); }

    private {
        // Screen units are pixels
        // Model units are millimetres
        double _zoom;               // pixels-per-millimetre
        Rectangle _viewBounds;      // pixel: bounds of the viewport in pixels
        Point _viewCentre;          // model: where in the model is the centre of our view
        Rectangle _canvasBounds;    // model: the bounds of the canvas in millimetres
    }
}