📄 vec2d.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 + -