⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vec2d.c

📁 傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。
💻 C
字号:
#include "vec2d.h"
#include <crblib/floatutil.h>

//--------------------------------------------------------------

const Vec2d ZeroVec2d  = {0.0f,0.0f};
const Vec2d UnitXVec2d = {1.0f,0.0f};
const Vec2d UnitYVec2d = {0.0f,1.0f};

float REGCALL Vec2d_LenSquared(const Vec2d *v)
{
return v->x * v->x + v->y * v->y;
}

float REGCALL Vec2d_Normalize(Vec2d *v)
{
float len,inv;
	len = fSqrt( v->x * v->x + v->y * v->y ) + 0.00000001f;
	inv = 1.0f / len;
	v->x *= inv;
	v->y *= inv;
return len;
}

void REGCALL Vec2d_Perp(const Vec2d *fm,Vec2d *to)
{
	assert( fm != to );
	to->x =   fm->y;
	to->y = - fm->x;
}

float REGCALL Vec2d_DotProduct(const Vec2d *a,const Vec2d *b)
{
return (a->x * b->x + a->y *b->y );
}

float REGCALL Vec2d_CrossProduct(const Vec2d *a,const Vec2d *b)
{
return (a->x * b->y - a->y *b->x );
}

float REGCALL Vec2d_InDirection(const Vec2d *vec,const Vec2d * normal,Vec2d *dir)
{
float mag;
	mag = Vec2d_DotProduct(vec,normal);
	dir->x = mag * normal->x;
	dir->y = mag * normal->y;
return mag;
}

void REGCALL Vec2d_Set( Vec2d * V, float X, float Y )
{
	assert( V ) ;

	V->x = X ;
	V->y = Y ;
}

void REGCALL Vec2d_Add( const Vec2d * pV1, const Vec2d * pV2, Vec2d * pV1PlusV2 )
{
	assert ( pV1 );
	assert ( pV2 );
	assert ( pV1PlusV2 );
	
	pV1PlusV2->x = pV1->x + pV2->x;
	pV1PlusV2->y = pV1->y + pV2->y;
}/* Vec2d_Add */

void REGCALL Vec2d_Copy(const Vec2d *VSrc, Vec2d *VDst)
{
	assert ( VSrc );
	assert ( VDst );
	
	*VDst = *VSrc;
}//Vec2d_Copy

void REGCALL Vec2d_Clear( Vec2d *V)
{
	assert ( V );
	
	V->x = 0.0f;
	V->y = 0.0f;
}//Vec2d_Clear


float REGCALL Vec2d_DistanceBetween(const Vec2d *V1, const Vec2d *V2)	// returns length of V1-V2	
{
	Vec2d B;
	
	assert( V1 );
	assert( V2 );

	Vec2d_Subtract(V1,V2,&B);
	return Vec2d_Length(&B);
}// Vec2d_DistanceBetween

// returns length of V1-V2 Squared
float REGCALL Vec2d_DistBetweenSquared(const Vec2d *V1, const Vec2d *V2)
{
	float f, d;
	
	assert( V1 );
	assert( V2 );

	f = V2->y - V1->y;
	f *= f;
	d = V2->x - V1->x;
	d *= d;

	return(d+f);

} // Vec2d_DistanceBetween

/*
float REGCALL Vec2d_Length(const Vec2d *v)
{
return fSqrt(v->x * v->x + v->y * v->y);
}
*/

float REGCALL Vec2d_Length(const Vec2d *V1)
{	
float Len;

	__asm
	{
		mov		eax,V1
		fld		[eax+0]		//	st(0) = vec->x
		fmul	[eax+0]		//	st(0) = vecX ^2

		fld		[eax+4]
		fmul	[eax+4]
							// now st(0),st(1) are Y^2,X^2
        faddp   st(1),st(0)
		fsqrt
        fstp    [Len]
	}
return Len;
}
//Vec2d_Length

void REGCALL Vec2d_Scale( const Vec2d *VSrc, float fScale, Vec2d *VDst)
{
	assert ( VSrc );
	assert ( VDst );

	VDst->x = VSrc->x * fScale;
	VDst->y = VSrc->y * fScale;
}// Vec2d_Scale


void REGCALL Vec2d_Subtract(const Vec2d *V1, const Vec2d *V2, Vec2d *V1MinusV2)
{
	assert ( V1 );
	assert ( V2 );
	assert ( V1MinusV2 );

	V1MinusV2->x = V1->x - V2->x;
	V1MinusV2->y = V1->y - V2->y;
}// Vec2d_Subtract

void REGCALL Vec2d_Perp_Clockwise( const Vec2d *pVec, Vec2d *pDest)
{
Vec2d Vec;
	// rotates by 90 clockwise:
	assert(pVec && pDest);
	Vec = *pVec;
	pDest->x =	 Vec.y;
	pDest->y = - Vec.x;
}

void REGCALL Vec2d_Perp_CClockwise( const Vec2d *pVec, Vec2d *pDest)
{
Vec2d Vec;
	assert(pVec && pDest);
	Vec = *pVec;
	// rotates by 90 counterclockwise:
	pDest->x = - Vec.y;
	pDest->y =   Vec.x;
}

void REGCALL Vec2d_Rotate( const Vec2d *pVec, float Radians, Vec2d *pDest)
{
Vec2d Vec;
float c,s;
	
	assert(pVec);
	Vec = *pVec;

	// rotates clockwise:
	//	(really? seems true)

	c = fCos(Radians);
	s = fSin(Radians);

	pDest->x = + c * Vec.x + s * Vec.y;
	pDest->y = - s * Vec.x + c * Vec.y;
}

int	REGCALL Vec2d_SideX(const Vec2d *pSeg1,const Vec2d *pSeg2,const Vec2d *pPoint)
{
float minY,maxY,minX,maxX;
	assert( pSeg1 && pSeg2 && pPoint );

	minY = min(pSeg1->y,pSeg2->y);
	maxY = max(pSeg1->y,pSeg2->y);
	minX = min(pSeg1->x,pSeg2->x);
	maxX = max(pSeg1->x,pSeg2->x);

	if ( pPoint->y < minY || pPoint->y >= maxY )
		return 0;

	if ( pPoint->x < minX )
		return -1;
	if ( pPoint->x >= maxX )
		return +1;

	{
	float testX;

	// y = mx + b	(with x and y swapped)

	testX = pSeg1->x + ( pPoint->y - pSeg1->y ) * ( pSeg2->x - pSeg1->x ) / ( pSeg2->y - pSeg1->y );

	if ( pPoint->x < testX )
		return -1;
	else
		return 1;
	}
}

void	REGCALL Vec2d_PerpNormal(const Vec2d *p1,const Vec2d *p2,Vec2d *normal)
{
	Vec2d_Subtract(p2,p1,normal);
	Vec2d_Normalize(normal);
	Vec2d_Perp_Clockwise(normal,normal);
}

void REGCALL Vec2d_AddScaled(const Vec2d * v1,const Vec2d *v2,float v2scale,Vec2d *out)
{
	out->x = v1->x + v2->x * v2scale;
	out->y = v1->y + v2->y * v2scale;
}


//--------------------------------------------------------------

void	REGCALL Box2d_SetToPoint(Box2d *b,const Vec2d *v)
{
	b->min = b->max = *v;
}

void	REGCALL Box2d_ExtendToEnclose(Box2d *b,const Vec2d *v)
{
	b->min.x = min(b->min.x,v->x);	
	b->min.y = min(b->min.y,v->y);	
	b->max.x = max(b->max.x,v->x);	
	b->max.y = max(b->max.y,v->y);	
}

bool	REGCALL Box2d_Intersects(const Box2d *b1,const Box2d *b2)
{
	if ( b2->min.x <= b1->max.x &&
		 b2->max.x >= b1->min.x &&
		 b2->min.y <= b1->max.y &&
		 b2->max.y >= b1->min.y ) return true;
return false;
}

//--------------------------------------------------------------

void	REGCALL Plane2d_Set(Plane2d * p,const Vec2d *point,const Vec2d *normal)
{
	p->normal = *normal;
	Vec2d_Normalize(&(p->normal));
	p->dist = Vec2d_DotProduct(point,&(p->normal));
}

void	REGCALL Plane2d_SetFromCClockwise(Plane2d * p,const Vec2d *p1,const Vec2d *p2)
{
	Vec2d_PerpNormal(p1,p2,&(p->normal));
	p->dist = Vec2d_DotProduct(p1,&(p->normal));
}

float	REGCALL Plane2d_Distance(const Plane2d * p,const Vec2d *v)
{
return (Vec2d_DotProduct(&(p->normal),v) - p->dist);
}

void	REGCALL Plane2d_GetPointOnPlane(const Plane2d * p,Vec2d *v)
{
	*v = p->normal;
	Vec2d_Scale(v,p->dist,v);
}


bool Plane2d_SegmentIntersection(const Plane2d *p,const Vec2d * fm,const Vec2d *to,Vec2d *hit,float *pfrac)
{
float dfm,dto,frac;
	dfm = Plane2d_Distance(p,fm);
	dto = Plane2d_Distance(p,to);

	frac = dfm / (dfm - dto);

	hit->x = fm->x + frac * (to->x - fm->x);
	hit->y = fm->y + frac * (to->y - fm->y);

	if ( pfrac ) *pfrac = frac;

	if ( dfm >= 0.0f && dto <= 0.0f )
		return true;
	else
		return false;
}

bool Plane2d_ClipSeg(const Plane2d *p,Vec2d *p0,Vec2d *p1)
{
float d0,d1,frac;
	d0 = Plane2d_Distance(p,p0);
	d1 = Plane2d_Distance(p,p1);

	if ( d0 >  0.0f && d1 >  0.0f ) // both on the front side, no collision
		return false;
	if ( d0 <= 0.0f && d1 <= 0.0f ) // both on the back side, no clipping
		return true;

	// now one is pos, one is neg

	frac = d0 / (d0 - d1);

	if ( d0 > 0 )
	{
		p0->x = p0->x + frac * (p1->x - p0->x);
		p0->y = p0->y + frac * (p1->y - p0->y);
	}
	else
	{
		p1->x = p0->x + frac * (p1->x - p0->x);
		p1->y = p0->y + frac * (p1->y - p0->y);
	}

	return true;
}
//--------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -