This Library for DOGS-102 Graphic LCD module. Based on Igor Skochinsky's "DOGLCDDemo" program.

Dependents:   DOGS102_Example1 DOGS102_Example2

Fork of DOGLCDDemo by Igor Skochinsky

Graphics/Graphics.cpp

Committer:
ban4jp
Date:
2014-05-03
Revision:
1:2145a74df666
Parent:
0:2a5dccfd318f

File content as of revision 1:2145a74df666:

/* 
 * libmbed-graphics 2D and wireframe 3D graphics library for the MBED
 * microcontroller platform
 * Copyright (C) <2009> Michael Sheldon <mike@mikeasoft.com>
 * Optimized and adapted for AbstractLCD interface
 * Copyright (C) <2010> Igor Skochinsky <skochinsky@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "Graphics.h"

// swap two values
#define SWAP(a, b) (((a) == (b)) || (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))))

Graphics::Graphics(AbstractLCD *lcd)
    : _lcd(lcd) { 
    _cx3d = _lcd->width() / 2;
    _cy3d = _lcd->height() / 2;
    _cz3d = 150;
}

void Graphics::line(int x0, int y0, int x1, int y1, int colour) {
    // Bresenham
    //printf("line(%d, %d, %d, %d, %d)\n", x0, y0, x1, y1, colour);
    bool steep = abs(y1 - y0) > abs(x1 - x0);
    int temp, deltax, deltay, error, ystep, y, x;
    if (steep) {
        temp = y0;
        y0 = x0;
        x0 = temp;
        temp = y1;
        y1 = x1;
        x1 = temp;
    }
    if (x0 > x1) {
        temp = x1;
        x1 = x0;
        x0 = temp;
        temp = y1;
        y1 = y0;
        y0 = temp;
    }
    deltax = x1 - x0;
    deltay = abs(y1 - y0);
    error = deltax / 2;
    y = y0;
    if (y0 < y1) {
        ystep = 1;
    } else {
        ystep = -1;
    }
    for (x=x0; x<=x1; x++) {
        if (steep) {
            _lcd->pixel(y, x, colour);
        } else {
            _lcd->pixel(x, y, colour);
        }
        error = error - deltay;
        if (error < 0) {
            y = y + ystep;
            error = error + deltax;
        }
    }
}

void Graphics::line3d(int x0, int y0, int z0, int x1, int y1, int z1, int colour) {
    if (z0 + _cz3d <= 0 || z1 + _cz3d <= 0) {
        // Behind the camera
        return;
    }
    
    int u0 = _cx3d + x0 * _cz3d / (z0 + _cz3d);
    int v0 = _cy3d + y0 * _cz3d / (z0 + _cz3d);
    int u1 = _cx3d + x1 * _cz3d / (z1 + _cz3d);
    int v1 = _cy3d + y1 * _cz3d / (z1 + _cz3d);
    line(u0, v0, u1, v1, colour);
}

void Graphics::circle(int cx, int cy, int radius, int colour) {
    int x = 0;
    int y = radius;
    int d = 3 - (2 * radius);

    while (x <= y) {
        _lcd->pixel(cx + x, cy + y, colour);
        _lcd->pixel(cx + y, cy + x, colour);
        _lcd->pixel(cx - x, cy + y, colour);
        _lcd->pixel(cx + y, cy - x, colour);
        _lcd->pixel(cx - x, cy - y, colour);
        _lcd->pixel(cx - y, cy - x, colour);
        _lcd->pixel(cx + x, cy - y, colour);
        _lcd->pixel(cx - y, cy + x, colour);

        if (d<0)
            d += (4 * x) + 6;
        else
        {
            d += (4 * (x - y)) + 10;
            y--;
        }
        x++;
    }
}