editor.c
来自「嵌入式GUI OpenGL源代码。OpenGL是嵌入式开发中常用的一种GUI系统」· C语言 代码 · 共 1,373 行 · 第 1/3 页
C
1,373 行
tg = &upoint->last->tg;
if ( tg->x1 != tg->x0 ) {
t1 = (tg->y1-tg->y0) / (tg->x1-tg->x0);
} else {
t1 = (tg->y1-tg->y0)*10000.;
}
GetPolynome(
upoint->last->mode,
upoint->last->x,
upoint->last->y,
t1,
upoint->x,
upoint->y,
t0,
upoint->last->polynome
);
for ( i=1+(int) upoint->last->x; i<(int) upoint->x; i++ ) {
val = Polynome4((float) i, upoint->last->polynome)/(float)MAXNDX;
TabCmpnt(cmpnt,i) = INF( SUP(val,0.), 1. );
}
}
if ( upoint->next != NULL ) {
tg = &upoint->next->tg;
if ( tg->x1 != tg->x0 ) {
t1 = (tg->y1-tg->y0) / (tg->x1-tg->x0);
} else {
t1 = (tg->y1-tg->y0)*10000.;
}
GetPolynome(
upoint->mode,
upoint->x,
upoint->y,
t0,
upoint->next->x,
upoint->next->y,
t1,
upoint->polynome
);
for ( i=1+(int) upoint->x; i<(int) upoint->next->x; i++ ) {
val = Polynome4( (float) i, upoint->polynome )/(float)MAXNDX;
TabCmpnt(cmpnt,i) = INF( SUP(val,0.), 1. );
}
TabCmpnt(cmpnt,(int) upoint->next->x) = upoint->next->y/(float)MAXNDX;
}
}
/*---------------------------------------------------------------------------*
* freePointList
*---------------------------------------------------------------------------*/
static void
freePointList( UserPoint *upoint )
{
while (upoint != NULL)
{
UserPoint *unext = upoint->next;
freePoint( upoint );
upoint = unext;
}
}
/*---------------------------------------------------------------------------*
* clonePointList
*---------------------------------------------------------------------------*/
static UserPoint *
clonePointList( UserPoint *base )
{
UserPoint *clone, *upoint;
if (base == NULL) return NULL;
newPoint( clone );
upoint = clone;
memcpy( upoint, base, sizeof(UserPoint) );
upoint->last = NULL;
upoint->next = NULL;
while (base->next != NULL)
{
base = base->next;
newPoint( upoint->next );
memcpy( upoint->next, base, sizeof(UserPoint) );
upoint->next->last = upoint;
upoint->next->next = NULL;
upoint = upoint->next;
}
return clone;
}
/*---------------------------------------------------------------------------*
* ApplyCMap
*---------------------------------------------------------------------------*/
void
ApplyCMap(void)
{
int i;
for (i=0; i<4; i++) if ( modifiedCurve[i] )
{
freePointList( userPointSvg[i] );
userPointSvg[i] = clonePointList( userPoint[i] );
modifiedCurve[i] = 0;
}
}
/*---------------------------------------------------------------------------*
* ResetCMap
*---------------------------------------------------------------------------*/
void
ResetCMap(void)
{
int i;
UserPoint *upoint;
for (i=0; i<4; i++) if ( modifiedCurve[i] )
{
freePointList( userPoint[i] );
userPoint[i] = clonePointList( userPointSvg[i] );
modifiedCurve[i] = 0;
for (upoint=userPoint[i]; upoint!=NULL; upoint=upoint->next )
YACME_update( i, upoint );
}
}
/*---------------------------------------------------------------------------*
* InsertPoint
*---------------------------------------------------------------------------*/
int
InsertPoint( PickObject *obj )
{
float dx, dy, slope, coeff[4];
int i;
Tangente *tg;
UserPoint *upoint, *userpoint;
upoint = userPoint[obj->cmpnt];
while ( (int) upoint->next->x <= obj->ndx ) {
upoint = upoint->next;
if ( upoint->next == NULL ) return 0;
}
if ( (int) upoint->x == obj->ndx ) {
obj->upoint = upoint;
return POINT;
}
newPoint( userpoint );
userpoint->x = (float) obj->ndx;
userpoint->y = Polynome4( obj->ndx, upoint->polynome );
userpoint->y = SUP( INF(userpoint->y, (float)MAXNDX), 0. );
userpoint->mode = upoint->mode;
for ( i=0; i<4; i++ ) {
userpoint->polynome[i] = upoint->polynome[i];
}
userpoint->next = upoint->next;
userpoint->last = upoint;
upoint->next = userpoint;
userpoint->next->last = userpoint;
/*
calcul de slope = P'(index)
---------------------------
*/
if ( userpoint->y == (float)MAXNDX || userpoint->y == 0. ) {
dx = 25.;
dy = 0.;
} else {
coeff[0] = userpoint->polynome[0]*3.;
coeff[1] = userpoint->polynome[1]*2.;
coeff[2] = userpoint->polynome[2];
slope = coeff[0];
for (i=1; i<3; i++) {
slope *= (float) obj->ndx;
slope += coeff[i];
}
/*
Rappel :
cos( arctg(x) ) = 1/sqr( 1 + x^2 );
sin( arctg(x) ) = |x|/sqr( 1 + x^2 );
*/
dx = 25. / fsqrt( slope*slope + 1. );
dy = dx*slope;
}
dx *= LUTRATIO;
dy *= LUTRATIO;
tg = &userpoint->tg;
tg->x0 = userpoint->x - dx;
tg->x1 = userpoint->x + dx;
tg->y0 = userpoint->y - dy;
tg->y1 = userpoint->y + dy;
obj->upoint = userpoint;
return POINT;
}
/*---------------------------------------------------------------------------*
* DeletePoint
*---------------------------------------------------------------------------*/
void
DeletePoint( int cmpnt, UserPoint *upoint )
{
if ( upoint == NULL || upoint->last == NULL || upoint->next == NULL )
return;
upoint->last->next = upoint->next;
upoint->next->last = upoint->last;
YACME_update( cmpnt, upoint->last );
freePoint( upoint );
}
/*---------------------------------------------------------------------------*
* MovePoint
*---------------------------------------------------------------------------*/
int
MovePoint( int mousex, int mousey )
{
float x, y, dx, dy, minx, maxx;
OrthoTransform( mousex, mousey, &x, &y );
y = SUP( INF(y,(float)MAXNDX), 0. );
x = ((x-(int)x)<.5) ? (float)(int)x : (float)(int)(x+1);
y = ((y-(int)y)<.5) ? (float)(int)y : (float)(int)(y+1);
if ( curPoint->next != NULL && curPoint->last!= NULL )
{
minx = curPoint->last->x + 1.;
maxx = curPoint->next->x - 1.;
x = SUP( INF(x, maxx), minx );
dx = (float)x - curPoint->x;
curPoint->x = (float) x;
curPoint->tg.x0 += (float) dx;
curPoint->tg.x1 += (float) dx;
}
dy = (float)y - curPoint->y;
curPoint->y = (float)y;
curPoint->tg.y0 += (float) dy;
curPoint->tg.y1 += (float) dy;
return 1;
}
/*---------------------------------------------------------------------------*
* MoveTangente
*---------------------------------------------------------------------------*/
int
MoveTangente( int sens, int mousex, int mousey )
{
float x, y, dx, dy, slope;
Tangente *tg;
OrthoTransform( mousex, mousey, &x, &y );
if ( sens == -1 )
{
x = INF(x, curPoint->x);
}
else
{
x = SUP(x, curPoint->x);
}
if ( x != curPoint->x )
{
slope = (curPoint->y - y);
slope /= (curPoint->x - x);
dx = 25. / fsqrt( slope*slope + 1. );
dy = dx*slope;
}
else
{
dx = 0.;
dy = (curPoint->y < y) ? sens*25. : -sens*25.;
}
dx *= LUTRATIO;
dy *= LUTRATIO;
tg = &curPoint->tg;
tg->x0 = curPoint->x;
tg->y0 = curPoint->y;
if ( curPoint->last != NULL ) {
tg->x0 -= dx;
tg->y0 -= dy;
}
tg->x1 = curPoint->x;
tg->y1 = curPoint->y;
if ( curPoint->next != NULL )
{
tg->x1 += dx;
tg->y1 += dy;
}
return 1;
}
/*---------------------------------------------------------------------------*
* GetPolynome
*---------------------------------------------------------------------------*/
/*
we want a polynom P(x) = Ax^3 + Bx^2 + Cx + D
so that : P(a0) = b0, P'(a0) = t0, P(a1) = b1, P'(a1) = t1
i.e.
| a0^3 a0^2 a0 1 | |A| |b0|
| a1^3 a1^2 a1 1 | |B| = |b1|
| 3a0^2 2a0 1 0 | |C| |t0|
| 3a1^2 2a1 1 0 | |D| |t1|
*/
void
GetPolynome(
int mode,
float a0, float b0, float t0,
float a1, float b1, float t1,
float coeff[4] )
{
Matrix mat, INV_mat;
int i;
float val;
switch (mode)
{
case CONSTANT:
/* we want P(x) = b0 */
coeff[0] = 0.;
coeff[1] = 0.;
coeff[2] = 0.;
coeff[3] = b0;
break;
case LINEAR:
/*
we want P(x) = b0 + (x-a0)/(a1-a0)*(b1-b0)
i.e. P(x) = x*[(b1-b0)/(a1-a0)] + b0 - a0*[(b1-b0)/(a1-a0)]
*/
val = (b1-b0)/(a1-a0);
coeff[0] = 0.;
coeff[1] = 0.;
coeff[2] = val;
coeff[3] = b0 - a0*val;
break;
case POLYNOMIAL:
/*
we want a polynom P(x) = Ax^3 + Bx^2 + Cx + D
so that : P(a0) = b0, P'(a0) = t0, P(a1) = b1, P'(a1) = t1
i.e.
| a0^3 a0^2 a0 1 | |A| |b0|
| a1^3 a1^2 a1 1 | |B| = |b1|
| 3a0^2 2a0 1 0 | |C| |t0|
| 3a1^2 2a1 1 0 | |D| |t1|
*/
val = 1.;
for (i=3; i>=0; i--)
{
mat[0][i] = val;
val *= a0;
}
val = 1.;
for (i=3; i>=0; i--)
{
mat[1][i] = val;
val *= a1;
}
mat[2][3] = 0.;
mat[2][2] = 1.;
mat[2][1] = 2.*a0;
mat[2][0] = 3.*a0*a0;
mat[3][3] = 0.;
mat[3][2] = 1.;
mat[3][1] = 2.*a1;
mat[3][0] = 3.*a1*a1;
invertmat( mat, INV_mat );
for (i=0; i<4; i++)
coeff[i] = INV_mat[i][0]*b0 +
INV_mat[i][1]*b1 +
INV_mat[i][2]*t0 +
INV_mat[i][3]*t1;
break;
}
}
/*---------------------------------------------------------------------------*
* OrthoTransform
*---------------------------------------------------------------------------*/
void
OrthoTransform( int mx, int my, float *x, float *y )
{
float xf, yf;
xf = (float) mx;
xf /= (float) W;
xf *= (float) (RIGHT - LEFT);
xf += (float) LEFT;
yf = (float) my;
yf /= (float) H;
yf *= (float) (TOP - BOTTOM);
yf += (float) BOTTOM;
*x = xf;
*y = yf;
}
/*---------------------------------------------------------------------------*
* Polynome4
*---------------------------------------------------------------------------*/
float
Polynome4( float x, float *coeff )
{
int j;
float val = coeff[0];
for (j=1; j<4; j++) {
val *= x;
val += coeff[j];
}
return val;
}
/*---------------------------------------------------------------------------*
* MAIN
*---------------------------------------------------------------------------*/
#ifdef YACME_DBG
#include "RGBA.h"
int
main( int argc, char *argv[] )
{
glutInit( &argc, argv );
YACME_init(
0, 0, WINWIDTH, WINHEIGHT,
256, (float**)RGBA,
NULL, NULL
);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?