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 + -
显示快捷键?