Add MatrixFloat2D and MatrixFixed2D operations to GMISC.
Add polygon demo
This commit is contained in:
parent
74c23de1d2
commit
87242d0a6c
3
demos/modules/gdisp/polygons/demo.mk
Normal file
3
demos/modules/gdisp/polygons/demo.mk
Normal file
@ -0,0 +1,3 @@
|
||||
DEMODIR = $(GFXLIB)/demos/modules/gdisp/polygons
|
||||
GFXINC += $(DEMODIR)
|
||||
GFXSRC += $(DEMODIR)/main.c
|
66
demos/modules/gdisp/polygons/gfxconf.h
Normal file
66
demos/modules/gdisp/polygons/gfxconf.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _GFXCONF_H
|
||||
#define _GFXCONF_H
|
||||
|
||||
/* The operating system to use. One of these must be defined - preferably in your Makefile */
|
||||
//#define GFX_USE_OS_CHIBIOS FALSE
|
||||
//#define GFX_USE_OS_WIN32 FALSE
|
||||
//#define GFX_USE_OS_LINUX FALSE
|
||||
//#define GFX_USE_OS_OSX FALSE
|
||||
|
||||
/* GFX sub-systems to turn on */
|
||||
#define GFX_USE_GDISP TRUE
|
||||
#define GFX_USE_GMISC TRUE
|
||||
|
||||
/* Features for the GDISP sub-system. */
|
||||
#define GDISP_NEED_VALIDATION TRUE
|
||||
#define GDISP_NEED_CLIP TRUE
|
||||
#define GDISP_NEED_CONVEX_POLYGON TRUE
|
||||
|
||||
/* For this demo define either:
|
||||
* GMISC_NEED_MATRIXFLOAT2D to use floating point math operations
|
||||
*
|
||||
* or
|
||||
*
|
||||
* GMISC_NEED_MATRIXFIXED2D to use fixed point math operations.
|
||||
*
|
||||
* If you choose floating point you may optionally define GMISC_NEED_FASTTRIG.
|
||||
* If you choose fixed point you MUST define GMISC_NEED_FIXEDTRIG for this demo.
|
||||
*/
|
||||
|
||||
//#define GMISC_NEED_FASTTRIG TRUE
|
||||
//#define GMISC_NEED_MATRIXFLOAT2D TRUE
|
||||
|
||||
#define GMISC_NEED_FIXEDTRIG TRUE
|
||||
#define GMISC_NEED_MATRIXFIXED2D TRUE
|
||||
|
||||
#endif /* _GFXCONF_H */
|
||||
|
160
demos/modules/gdisp/polygons/main.c
Normal file
160
demos/modules/gdisp/polygons/main.c
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gfx.h"
|
||||
#include <string.h>
|
||||
|
||||
#define FRAME_DELAY 100 /* The interframe delay in milliseconds */
|
||||
|
||||
// Our shape definition
|
||||
static const point shape[] = {
|
||||
{ 10, 10 },
|
||||
{ 10, 15 },
|
||||
{ 17, 17 },
|
||||
{ 20, 5 },
|
||||
{ 10, 0 },
|
||||
{ 3, -10},
|
||||
{ -7, -15},
|
||||
{ -15, -15},
|
||||
{ -13, -12 },
|
||||
{ -8, 0 },
|
||||
};
|
||||
|
||||
#define NUM_POINTS (sizeof(shape)/sizeof(shape[0]))
|
||||
|
||||
// Where we put our calculated points
|
||||
static point result[NUM_POINTS];
|
||||
static point oldresult[NUM_POINTS];
|
||||
|
||||
// Make fixed point and floating point options look pretty similar
|
||||
#if GMISC_NEED_MATRIXFLOAT2D
|
||||
static MatrixFloat2D m1, m2;
|
||||
typedef float mtype;
|
||||
#define FP2MTYPE(f) (f)
|
||||
#define INT2MTYPE(i) (i)
|
||||
#elif GMISC_NEED_MATRIXFIXED2D
|
||||
static MatrixFixed2D m1, m2;
|
||||
typedef fixed mtype;
|
||||
#define FP2MTYPE(f) FP2FIXED(f)
|
||||
#define INT2MTYPE(i) FIXED(i)
|
||||
#else
|
||||
#error "Either GMISC_NEED_MATRIXFLOAT2D or GMISC_NEED_MATRIXFIXED2D must be defined for this demo"
|
||||
#endif
|
||||
|
||||
|
||||
int main(void) {
|
||||
coord_t width, height;
|
||||
mtype scalex, scaley;
|
||||
mtype scaleincx, scaleincy;
|
||||
mtype translatex, translatey;
|
||||
mtype transincx, transincy;
|
||||
mtype transmaxx, transmaxy;
|
||||
mtype transminx, transminy;
|
||||
int angle;
|
||||
int angleinc;
|
||||
|
||||
// Initialize and clear the display
|
||||
gfxInit();
|
||||
gdispClear(White);
|
||||
|
||||
// Get the screen size
|
||||
width = gdispGetWidth();
|
||||
height = gdispGetHeight();
|
||||
|
||||
// Initial position, rotation and scale
|
||||
scalex = scaley = FP2MTYPE(1.0);
|
||||
translatex = INT2MTYPE(width/2);
|
||||
translatey = INT2MTYPE(height/2);
|
||||
angle = 0;
|
||||
|
||||
// How much to change the position, rotation and scale each cycle
|
||||
scaleincx = scaleincy = FP2MTYPE(0.5);
|
||||
transincx = INT2MTYPE(2);
|
||||
transincy = INT2MTYPE(-2);
|
||||
angleinc = 2;
|
||||
transmaxx = INT2MTYPE(width - 15);
|
||||
transminx = INT2MTYPE(15);
|
||||
transmaxy = INT2MTYPE(height - 15);
|
||||
transminy = INT2MTYPE(15);
|
||||
|
||||
while(TRUE) {
|
||||
|
||||
// Move to the new location, rotation and scale
|
||||
scalex += scaleincx;
|
||||
scaley += scaleincy;
|
||||
angle += angleinc;
|
||||
if (angle >= 360)
|
||||
angle -= 360;
|
||||
translatex += transincx;
|
||||
translatey += transincy;
|
||||
|
||||
// Adjust our speed etc
|
||||
if (scalex > FP2MTYPE(10.0)) scaleincx = FP2MTYPE(-0.3);
|
||||
else if (scalex < FP2MTYPE(1.0)) scaleincx = FP2MTYPE(0.5);
|
||||
if (scaley > FP2MTYPE(7.0)) scaleincy = FP2MTYPE(-0.25);
|
||||
else if (scaley < FP2MTYPE(1.0)) scaleincy = FP2MTYPE(0.3);
|
||||
if (translatex > transmaxx || translatex < transminx) transincx = -transincx;
|
||||
if (translatey > transmaxy || translatey < transminy) transincy = -transincy;
|
||||
|
||||
// Build a matrix of all the operations we want to do and then apply it to all the shape points
|
||||
#if GMISC_NEED_MATRIXFLOAT2D
|
||||
gmiscMatrixFloat2DApplyScale(&m1, 0, scalex, scaley);
|
||||
gmiscMatrixFloat2DApplyRotation(&m2, &m1, angle);
|
||||
gmiscMatrixFloat2DApplyTranslation(&m1, &m2, translatex, translatey);
|
||||
gmiscMatrixFloat2DApplyToPoints(result, shape, &m1, NUM_POINTS);
|
||||
#else
|
||||
gmiscMatrixFixed2DApplyScale(&m1, 0, scalex, scaley);
|
||||
gmiscMatrixFixed2DApplyRotation(&m2, &m1, angle);
|
||||
gmiscMatrixFixed2DApplyTranslation(&m1, &m2, translatex, translatey);
|
||||
gmiscMatrixFixed2DApplyToPoints(result, shape, &m1, NUM_POINTS);
|
||||
#endif
|
||||
|
||||
// Clear the old shape
|
||||
gdispDrawPoly(0, 0, oldresult, NUM_POINTS, White);
|
||||
gdispFillConvexPoly(0, 0, oldresult, NUM_POINTS, White);
|
||||
|
||||
// Play the new shape position
|
||||
// NOTE: Because our shape is not a true convex polygon, we get some frames
|
||||
// where the line outline and the filled shape don't match. This is
|
||||
// expected due to the shapes non-convex nature and was left in the
|
||||
// demo to demonstrate this exact point.
|
||||
gdispFillConvexPoly(0, 0, result, NUM_POINTS, Red);
|
||||
gdispDrawPoly(0, 0, result, NUM_POINTS, Blue);
|
||||
|
||||
// Make sure the display is updated
|
||||
gdispFlush();
|
||||
|
||||
// Save the results so we can clear them next cycle
|
||||
memcpy(oldresult, result, sizeof(result));
|
||||
|
||||
// Delay for a while
|
||||
gfxSleepMilliseconds(FRAME_DELAY);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ DEPRECATE: gwinAttachMouse() is now handled automaticly.
|
||||
FEATURE: Added MAX11802 touch driver by user steved
|
||||
FEATURE: Added STM32F429i-Discovery board support
|
||||
FEATURE: Added DejaVuSans20 and DejaVuSans20_aa built-in fonts
|
||||
FEATURE: Added MatrixFloat2D and MatrixFixed2D operations to GMISC
|
||||
FEATURE: Added polygon drawing demo (with rotation, scaling and translation)
|
||||
|
||||
|
||||
*** Release 2.1 ***
|
||||
|
@ -279,5 +279,7 @@
|
||||
//#define GMISC_NEED_INVSQRT FALSE
|
||||
// #define GMISC_INVSQRT_MIXED_ENDIAN FALSE
|
||||
// #define GMISC_INVSQRT_REAL_SLOW FALSE
|
||||
//#define GMISC_NEED_MATRIXFLOAT2D FALSE
|
||||
//#define GMISC_NEED_MATRIXFIXED2D FALSE
|
||||
|
||||
#endif /* _GFXCONF_H */
|
||||
|
196
src/gmisc/gmisc_matrix2d.c
Normal file
196
src/gmisc/gmisc_matrix2d.c
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/gmisc/gmisc_matrix2d.c
|
||||
* @brief GMISC 2D matrix operations code.
|
||||
*/
|
||||
#include "gfx.h"
|
||||
|
||||
#if GFX_USE_GMISC
|
||||
|
||||
#if GMISC_NEED_MATRIXFLOAT2D
|
||||
|
||||
#if !GMISC_NEED_FASTTRIG
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
void gmiscMatrixFloat2DSetIdentity(MatrixFloat2D *m) {
|
||||
m->a00 = m->a11 = m->a22 = 1.0;
|
||||
m->a01 = m->a02 = m->a10 = m->a12 = m->a20 = m->a21 = 0.0;
|
||||
}
|
||||
|
||||
void gmiscMatrixFloat2DMultiply(MatrixFloat2D *dst, const MatrixFloat2D *src1, const MatrixFloat2D *src2) {
|
||||
dst->a00 = src1->a00*src2->a00 + src1->a01*src2->a10 + src1->a02*src2->a20;
|
||||
dst->a01 = src1->a00*src2->a01 + src1->a01*src2->a11 + src1->a02*src2->a21;
|
||||
dst->a02 = src1->a00*src2->a02 + src1->a01*src2->a12 + src1->a02*src2->a22;
|
||||
dst->a10 = src1->a10*src2->a00 + src1->a11*src2->a10 + src1->a12*src2->a20;
|
||||
dst->a11 = src1->a10*src2->a01 + src1->a11*src2->a11 + src1->a12*src2->a21;
|
||||
dst->a12 = src1->a10*src2->a02 + src1->a11*src2->a12 + src1->a12*src2->a22;
|
||||
dst->a20 = src1->a20*src2->a00 + src1->a21*src2->a10 + src1->a22*src2->a20;
|
||||
dst->a21 = src1->a20*src2->a01 + src1->a21*src2->a11 + src1->a22*src2->a21;
|
||||
dst->a22 = src1->a20*src2->a02 + src1->a21*src2->a12 + src1->a22*src2->a22;
|
||||
}
|
||||
|
||||
void gmiscMatrixFloat2DApplyTranslation(MatrixFloat2D *dst, const MatrixFloat2D *src, float tx, float ty) {
|
||||
if (src) {
|
||||
dst->a00 = src->a00; dst->a01 = src->a01; dst->a02 = src->a02+tx;
|
||||
dst->a10 = src->a10; dst->a11 = src->a11; dst->a12 = src->a12+ty;
|
||||
dst->a20 = src->a20; dst->a21 = src->a21; dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = 1.0; dst->a01 = 0.0; dst->a02 = tx;
|
||||
dst->a10 = 0.0; dst->a11 = 1.0; dst->a12 = ty;
|
||||
dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void gmiscMatrixFloat2DApplyScale(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy) {
|
||||
if (src) {
|
||||
dst->a00 = src->a00*sx; dst->a01 = src->a01*sy; dst->a02 = src->a02;
|
||||
dst->a10 = src->a10*sx; dst->a11 = src->a11*sy; dst->a12 = src->a12;
|
||||
dst->a20 = src->a20*sx; dst->a21 = src->a21*sy; dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = sx; dst->a01 = 0.0; dst->a02 = 0.0;
|
||||
dst->a10 = 0.0; dst->a11 = sy; dst->a12 = 0.0;
|
||||
dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void gmiscMatrixFloat2DApplyShear(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy) {
|
||||
if (src) {
|
||||
dst->a00 = src->a00 + src->a01*sy; dst->a01 = src->a00*sx + src->a01; dst->a02 = src->a02;
|
||||
dst->a10 = src->a10 + src->a11*sy; dst->a11 = src->a10*sx + src->a11; dst->a12 = src->a12;
|
||||
dst->a20 = src->a20 + src->a21*sy; dst->a21 = src->a20*sx + src->a21; dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = 1.0; dst->a01 = sx; dst->a02 = 0.0;
|
||||
dst->a10 = sy; dst->a11 = 1.0; dst->a12 = 0.0;
|
||||
dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void gmiscMatrixFloat2DApplyRotation(MatrixFloat2D *dst, const MatrixFloat2D *src, int angle) {
|
||||
float s, c;
|
||||
|
||||
#if GMISC_NEED_FASTTRIG
|
||||
s = fsin(angle);
|
||||
c = fcos(angle);
|
||||
#else
|
||||
c = angle*M_PI/180;
|
||||
s = sin(c);
|
||||
c = cos(c);
|
||||
#endif
|
||||
|
||||
if (src) {
|
||||
dst->a00 = src->a00*c - src->a01*s; dst->a01 = src->a00*s + src->a01*c; dst->a02 = src->a02;
|
||||
dst->a10 = src->a10*c - src->a11*s; dst->a11 = src->a10*s + src->a11*c; dst->a12 = src->a12;
|
||||
dst->a20 = src->a20*c - src->a21*s; dst->a21 = src->a20*s + src->a21*c; dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = c; dst->a01 = s; dst->a02 = 0.0;
|
||||
dst->a10 = -s; dst->a11 = c; dst->a12 = 0.0;
|
||||
dst->a20 = 0.0; dst->a21 = 0.0; dst->a22 = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void gmiscMatrixFloat2DApplyToPoints(point *dst, const point *src, const MatrixFloat2D *m, int cnt) {
|
||||
float x;
|
||||
|
||||
for( ;cnt--; dst++, src++) {
|
||||
x = src->x; // This allows in-place operation
|
||||
dst->x = round(x*m->a00+src->y*m->a01+m->a02);
|
||||
dst->y = round(x*m->a10+src->y*m->a11+m->a12);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GMISC_NEED_MATRIXFLOAT2D
|
||||
|
||||
#if GMISC_NEED_MATRIXFIXED2D
|
||||
|
||||
void gmiscMatrixFixed2DSetIdentity(MatrixFixed2D *m) {
|
||||
m->a00 = m->a11 = m->a22 = FIXED(1);
|
||||
m->a01 = m->a02 = m->a10 = m->a12 = m->a20 = m->a21 = 0;
|
||||
}
|
||||
|
||||
void gmiscMatrixFixed2DMultiply(MatrixFixed2D *dst, const MatrixFixed2D *src1, const MatrixFixed2D *src2) {
|
||||
dst->a00 = FIXEDMUL(src1->a00,src2->a00) + FIXEDMUL(src1->a01,src2->a10) + FIXEDMUL(src1->a02,src2->a20);
|
||||
dst->a01 = FIXEDMUL(src1->a00,src2->a01) + FIXEDMUL(src1->a01,src2->a11) + FIXEDMUL(src1->a02,src2->a21);
|
||||
dst->a02 = FIXEDMUL(src1->a00,src2->a02) + FIXEDMUL(src1->a01,src2->a12) + FIXEDMUL(src1->a02,src2->a22);
|
||||
dst->a10 = FIXEDMUL(src1->a10,src2->a00) + FIXEDMUL(src1->a11,src2->a10) + FIXEDMUL(src1->a12,src2->a20);
|
||||
dst->a11 = FIXEDMUL(src1->a10,src2->a01) + FIXEDMUL(src1->a11,src2->a11) + FIXEDMUL(src1->a12,src2->a21);
|
||||
dst->a12 = FIXEDMUL(src1->a10,src2->a02) + FIXEDMUL(src1->a11,src2->a12) + FIXEDMUL(src1->a12,src2->a22);
|
||||
dst->a20 = FIXEDMUL(src1->a20,src2->a00) + FIXEDMUL(src1->a21,src2->a10) + FIXEDMUL(src1->a22,src2->a20);
|
||||
dst->a21 = FIXEDMUL(src1->a20,src2->a01) + FIXEDMUL(src1->a21,src2->a11) + FIXEDMUL(src1->a22,src2->a21);
|
||||
dst->a22 = FIXEDMUL(src1->a20,src2->a02) + FIXEDMUL(src1->a21,src2->a12) + FIXEDMUL(src1->a22,src2->a22);
|
||||
}
|
||||
|
||||
void gmiscMatrixFixed2DApplyTranslation(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed tx, fixed ty) {
|
||||
if (src) {
|
||||
dst->a00 = src->a00; dst->a01 = src->a01; dst->a02 = src->a02+tx;
|
||||
dst->a10 = src->a10; dst->a11 = src->a11; dst->a12 = src->a12+ty;
|
||||
dst->a20 = src->a20; dst->a21 = src->a21; dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = FIXED(1); dst->a01 = 0; dst->a02 = tx;
|
||||
dst->a10 = 0; dst->a11 = FIXED(1); dst->a12 = ty;
|
||||
dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
|
||||
}
|
||||
}
|
||||
|
||||
void gmiscMatrixFixed2DApplyScale(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy) {
|
||||
if (src) {
|
||||
dst->a00 = FIXEDMUL(sx,src->a00); dst->a01 = FIXEDMUL(sy,src->a01); dst->a02 = src->a02;
|
||||
dst->a10 = FIXEDMUL(sx,src->a10); dst->a11 = FIXEDMUL(sy,src->a11); dst->a12 = src->a12;
|
||||
dst->a20 = FIXEDMUL(sx,src->a20); dst->a21 = FIXEDMUL(sy,src->a21); dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = sx; dst->a01 = 0; dst->a02 = 0;
|
||||
dst->a10 = 0; dst->a11 = sy; dst->a12 = 0;
|
||||
dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
|
||||
}
|
||||
}
|
||||
|
||||
void gmiscMatrixFixed2DApplyShear(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy) {
|
||||
if (src) {
|
||||
dst->a00 = src->a00 + FIXEDMUL(sy,src->a01); dst->a01 = FIXEDMUL(sx,src->a00) + src->a01; dst->a02 = src->a02;
|
||||
dst->a10 = src->a10 + FIXEDMUL(sy,src->a11); dst->a11 = FIXEDMUL(sx,src->a10) + src->a11; dst->a12 = src->a12;
|
||||
dst->a20 = src->a20 + FIXEDMUL(sy,src->a21); dst->a21 = FIXEDMUL(sx,src->a20) + src->a21; dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = FIXED(1); dst->a01 = sx; dst->a02 = 0;
|
||||
dst->a10 = sy; dst->a11 = FIXED(1); dst->a12 = 0;
|
||||
dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
|
||||
}
|
||||
}
|
||||
|
||||
#if GMISC_NEED_FIXEDTRIG
|
||||
void gmiscMatrixFixed2DApplyRotation(MatrixFixed2D *dst, const MatrixFixed2D *src, int angle) {
|
||||
fixed s, c;
|
||||
|
||||
s = ffsin(angle);
|
||||
c = ffcos(angle);
|
||||
|
||||
if (src) {
|
||||
dst->a00 = FIXEDMUL(c,src->a00) - FIXEDMUL(s,src->a01); dst->a01 = FIXEDMUL(s,src->a00) + FIXEDMUL(c,src->a01); dst->a02 = src->a02;
|
||||
dst->a10 = FIXEDMUL(c,src->a10) - FIXEDMUL(s,src->a11); dst->a11 = FIXEDMUL(s,src->a10) + FIXEDMUL(c,src->a11); dst->a12 = src->a12;
|
||||
dst->a20 = FIXEDMUL(c,src->a20) - FIXEDMUL(s,src->a21); dst->a21 = FIXEDMUL(s,src->a20) + FIXEDMUL(c,src->a21); dst->a22 = src->a22;
|
||||
} else {
|
||||
dst->a00 = c; dst->a01 = s; dst->a02 = 0;
|
||||
dst->a10 = -s; dst->a11 = c; dst->a12 = 0;
|
||||
dst->a20 = 0; dst->a21 = 0; dst->a22 = FIXED(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void gmiscMatrixFixed2DApplyToPoints(point *dst, const point *src, const MatrixFixed2D *m, int cnt) {
|
||||
coord_t x;
|
||||
|
||||
for( ;cnt--; dst++, src++) {
|
||||
x = src->x; // This allows in-place operation
|
||||
dst->x = NONFIXED(x*m->a00+src->y*m->a01+m->a02+FIXED0_5);
|
||||
dst->y = NONFIXED(x*m->a10+src->y*m->a11+m->a12+FIXED0_5);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GMISC_NEED_MATRIXFIXED2D
|
||||
|
||||
#endif // GFX_USE_GMISC
|
@ -25,6 +25,9 @@
|
||||
/* Type definitions */
|
||||
/*===========================================================================*/
|
||||
|
||||
// Forward definition
|
||||
typedef struct point point;
|
||||
|
||||
/**
|
||||
* @brief Sample data formats
|
||||
* @note These are defined regardless of whether you use the GMISC module
|
||||
@ -60,11 +63,13 @@ typedef int32_t fixed;
|
||||
* @brief Macros to convert to and from a fixed point.
|
||||
* @{
|
||||
*/
|
||||
#define FIXED(x) ((fixed)(x)<<16) /* @< integer to fixed */
|
||||
#define NONFIXED(x) ((x)>>16) /* @< fixed to integer */
|
||||
#define FIXED0_5 32768 /* @< 0.5 as a fixed (used for rounding) */
|
||||
#define FP2FIXED(x) ((fixed)((x)*65536.0)) /* @< floating point to fixed */
|
||||
#define FIXED2FP(x) ((double)(x)/65536.0) /* @< fixed to floating point */
|
||||
#define FIXED(x) ((fixed)(x)<<16) /* @< integer to fixed */
|
||||
#define NONFIXED(x) ((x)>>16) /* @< fixed to integer */
|
||||
#define FIXED0_5 32768 /* @< 0.5 as a fixed (used for rounding) */
|
||||
#define FP2FIXED(x) ((fixed)((x)*65536.0)) /* @< floating point to fixed */
|
||||
#define FIXED2FP(x) ((double)(x)/65536.0) /* @< fixed to floating point */
|
||||
#define FIXEDMUL(a,b) ((fixed)((((long long)(a))*(b))>>16)) /* @< fixed,fixed multiplication */
|
||||
#define FIXEDMULINT(a,b) ((a)*(b)) /* @< integer,fixed multiplication */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@ -90,6 +95,7 @@ extern "C" {
|
||||
#if GMISC_NEED_ARRAYOPS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Convert from one array format to another array format.
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_ARRAYOPS
|
||||
*
|
||||
* @param[in] srcfmt The format of the source array
|
||||
* @param[in] src The source array
|
||||
@ -131,6 +137,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief Fast Table Based Trig functions
|
||||
* @return A double in the range -1.0 .. 0.0 .. 1.0
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_FASTTRIG
|
||||
*
|
||||
* @param[in] degrees The angle in degrees (not radians)
|
||||
*
|
||||
@ -145,6 +152,7 @@ extern "C" {
|
||||
*
|
||||
* @brief Fast Table Based Trig functions
|
||||
* @return A double in the range -1.0 .. 0.0 .. 1.0
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_FASTTRIG
|
||||
*
|
||||
* @param[in] degrees The angle in degrees 0 .. 359
|
||||
*
|
||||
@ -166,6 +174,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief Fast Table Based Trig functions
|
||||
* @return A fixed point in the range -1.0 .. 0.0 .. 1.0
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG
|
||||
*
|
||||
* @param[in] degrees The angle in degrees (not radians)
|
||||
*
|
||||
@ -180,6 +189,7 @@ extern "C" {
|
||||
*
|
||||
* @brief Fast Table Based Trig functions
|
||||
* @return A fixed point in the range -1.0 .. 0.0 .. 1.0
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG
|
||||
*
|
||||
* @param[in] degrees The angle in degrees 0 .. 359
|
||||
*
|
||||
@ -195,10 +205,11 @@ extern "C" {
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
#if GMISC_NEED_INVSQRT
|
||||
#if GMISC_NEED_INVSQRT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Fast inverse square root function (x^-1/2)
|
||||
* @return The approximate inverse square root
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_INVSQRT
|
||||
*
|
||||
* @param[in] n The number to find the inverse square root of
|
||||
*
|
||||
@ -212,6 +223,243 @@ extern "C" {
|
||||
*/
|
||||
float invsqrt(float n);
|
||||
#endif
|
||||
|
||||
#if GMISC_NEED_MATRIXFLOAT2D || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief A matrix for doing 2D graphics using floats
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*/
|
||||
typedef struct MatrixFloat2D {
|
||||
float a00, a01, a02;
|
||||
float a10, a11, a12;
|
||||
float a20, a21, a22;
|
||||
} MatrixFloat2D;
|
||||
|
||||
/**
|
||||
* @brief Apply the matrix to a set of points
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*
|
||||
* @param[in] dst The destination array of points
|
||||
* @param[in] src The source array of points
|
||||
* @param[in] m The matrix to apply
|
||||
* @param[in] cnt How many points are in the array
|
||||
*
|
||||
* @note In-place matrix application is allowed ie. dst = src
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFloat2DApplyToPoints(point *dst, const point *src, const MatrixFloat2D *m, int cnt);
|
||||
|
||||
/**
|
||||
* @brief Set the 2D matrix to the identity matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*
|
||||
* @param[in] m The matrix to set to identity
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFloat2DSetIdentity(MatrixFloat2D *m);
|
||||
|
||||
/**
|
||||
* @brief Multiple two 2D matrixes together
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src1 The first source matrix
|
||||
* @param[in] src2 The second source matrix
|
||||
*
|
||||
* @note In-place matrix application is NOT allowed ie. dst != src1, dst != src2
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFloat2DMultiply(MatrixFloat2D *dst, const MatrixFloat2D *src1, const MatrixFloat2D *src2);
|
||||
|
||||
/**
|
||||
* @brief Add an x,y translation to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] tx, ty The x and y translation to apply
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation requiring no multiplication.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFloat2DApplyTranslation(MatrixFloat2D *dst, const MatrixFloat2D *src, float tx, float ty);
|
||||
|
||||
/**
|
||||
* @brief Add x,y scaling to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] sx, sy The scaling to apply in the x and y direction. Negative numbers give reflection.
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation requiring no multiplication.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFloat2DApplyScale(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy);
|
||||
|
||||
/**
|
||||
* @brief Add x,y shear to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] sx, sy The shear to apply in the x and y direction.
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation requiring no multiplication.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFloat2DApplyShear(MatrixFloat2D *dst, const MatrixFloat2D *src, float sx, float sy);
|
||||
|
||||
/**
|
||||
* @brief Add rotation to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFLOAT2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] angle The angle to apply in degrees (not radians).
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation.
|
||||
* @note If GMISC_NEED_FASTTRIG is defined then the fast table sin and cos lookup's will be used
|
||||
* rather than the C library versions.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFloat2DApplyRotation(MatrixFloat2D *dst, const MatrixFloat2D *src, int angle);
|
||||
#endif
|
||||
|
||||
#if GMISC_NEED_MATRIXFIXED2D || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief A matrix for doing 2D graphics using fixed point maths
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
|
||||
*/
|
||||
typedef struct MatrixFixed2D {
|
||||
fixed a00, a01, a02;
|
||||
fixed a10, a11, a12;
|
||||
fixed a20, a21, a22;
|
||||
} MatrixFixed2D;
|
||||
|
||||
/**
|
||||
* @brief Apply the matrix to a set of points
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
|
||||
*
|
||||
* @param[in] dst The destination array of points
|
||||
* @param[in] src The source array of points
|
||||
* @param[in] m The matrix to apply
|
||||
* @param[in] cnt How many points are in the array
|
||||
*
|
||||
* @note In-place matrix application is allowed ie. dst = src
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFixed2DApplyToPoints(point *dst, const point *src, const MatrixFixed2D *m, int cnt);
|
||||
|
||||
/**
|
||||
* @brief Set the 2D matrix to the identity matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
|
||||
*
|
||||
* @param[in] m The matrix to set to identity
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFixed2DSetIdentity(MatrixFixed2D *m);
|
||||
|
||||
/**
|
||||
* @brief Multiple two 2D matrixes together
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src1 The first source matrix
|
||||
* @param[in] src2 The second source matrix
|
||||
*
|
||||
* @note In-place matrix application is NOT allowed ie. dst != src1, dst != src2
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFixed2DMultiply(MatrixFixed2D *dst, const MatrixFixed2D *src1, const MatrixFixed2D *src2);
|
||||
|
||||
/**
|
||||
* @brief Add an x,y translation to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] tx, ty The x and y translation to apply
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation requiring no multiplication.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFixed2DApplyTranslation(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed tx, fixed ty);
|
||||
|
||||
/**
|
||||
* @brief Add x,y scaling to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] sx, sy The scaling to apply in the x and y direction. Negative numbers give reflection.
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation requiring no multiplication.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFixed2DApplyScale(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy);
|
||||
|
||||
/**
|
||||
* @brief Add x,y shear to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] sx, sy The shear to apply in the x and y direction.
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation requiring no multiplication.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFixed2DApplyShear(MatrixFixed2D *dst, const MatrixFixed2D *src, fixed sx, fixed sy);
|
||||
|
||||
#if GMISC_NEED_FIXEDTRIG || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Add rotation to a matrix
|
||||
* @pre Requires GFX_USE_GMISC and GMISC_NEED_MATRIXFIXED2D and GMISC_NEED_FIXEDTRIG
|
||||
*
|
||||
* @param[in] dst The destination matrix
|
||||
* @param[in] src The source matrix. Can be NULL
|
||||
* @param[in] angle The angle to apply in degrees (not radians).
|
||||
*
|
||||
* @note In-place matrix operation is NOT allowed ie. dst != src
|
||||
* @note If no source matrix is provided, it is equivalent to applying the operation
|
||||
* to an identity matrix. It also is a much simpler operation requiring no multiplication.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gmiscMatrixFixed2DApplyRotation(MatrixFixed2D *dst, const MatrixFixed2D *src, int angle);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
GFXSRC += $(GFXLIB)/src/gmisc/gmisc_gmisc.c \
|
||||
$(GFXLIB)/src/gmisc/gmisc_arrayops.c \
|
||||
$(GFXLIB)/src/gmisc/gmisc_matrix2d.c \
|
||||
$(GFXLIB)/src/gmisc/gmisc_trig.c
|
||||
|
Loading…
Reference in New Issue
Block a user