昵称:烦夫子
类别:界面/平面设计师
年龄:38
现所在地:北京
主页浏览总数:24259
总积分:89
文章数:88
作品数:70
VC源码:
// VectorRun.cpp: implementation of the VectorRun class.
// 重新设置点
void VectorRun::ResetParam ()
{
CenterP = Vector (0, 0);
RotateP = Vector (1, 0);
OffsetP = Vector (0, 0);
}
// 简化角度
void VectorRun::SimplifyAngle (float& angle)
{
if (angle < 0)
angle += PI2 * ceil (-angle / PI2);
if (angle >= PI2)
angle -= PI2 * floor (angle / PI2);
}
int VectorRun::Intersection (Vector& inter, const Vector& p1, const Vector& p2, const Vector& l1, const Vector& l2)
//计算两条线段(p1-p2, l1-l2)的交点
//返回: 0 -- 延长相交, 1 -- 相交, -1 -- 平行
{
float m, u, v;
Vector dp = p2 - p1;
Vector dl = l1 - l2;
Vector dd = l1 - p1;
m = Det (dp, dl);
//try
//{
if (fabs (m) < MINI)
return -1;
else
{
VERIFY ( m != 0);
u = Det (dd, dl) / m;
v = Det (dp, dd) / m;
inter = p1 * (1 - u) + p2 * u; //两线的交点
return (u >= 0 && u <= 1 && v >= 0 && v <= 1) ? 1 : 0;
}
//} catch(...) {}
}
float VectorRun::PointToLine2(const Vector& pa, const Vector& pb, const Vector& pp)
//计算点P到线段(L1,L2)的距离
//总是返回正数
{
float a, b, c, d, ds;
a = pb.y - pa.y;
b = pa.x - pb.x;
c = -a*pa.x - b*pa.y;
d = sqrt(a*a + b*b);
//try
//{
if(d > 0.0001)
ds = fabs(a*pp.x + b*pp.y + c) / d;
else
{
a = pa.x - pp.x;
b = pa.y - pp.y;
ds = sqrt(a*a + b*b);
}
//} catch(...) {}
return ds;
}
float VectorRun::PointToLine(const Vector& p, const Vector& l1, const Vector& l2,Vector& vDest)//TZH(25)
//计算点P到线段(L1,L2)的距离
//以笛卡儿坐标横轴为标准
//返回负数表示垂足不在线段上
{
float len;
Vector dp, u, angle, t;
dp = l2 - l1;
len = Length (dp);
//VERIFY ( len != 0);
if (len == 0)
return Distance (p, l1);
//try
//{
angle = Vector (dp.x / len, -dp.y / len);
u = p - l1;
t = Rotate (u, angle);
float scale=t.x/len;
vDest=l1+(l2-l1)*scale; //得到垂足点
if (t.x < 0 || t.x > len)
return - fabs (t.y);
else
return fabs (t.y);
//} catch(...) {}
}
float VectorRun::PointToLine (const Vector& p, const Vector& l1, const Vector& l2)
//计算点P到线段(L1,L2)的距离
//返回负数表示垂足不在线段上
{
float len;
Vector dp, u, angle, t;
dp = l2 - l1;
len = Length (dp);
//VERIFY ( len != 0);
if (len == 0)
return Distance (p, l1);
//try
//{
angle = Vector (dp.x / len, -dp.y / len);
u = p - l1;
t = Rotate (u, angle);
if (t.x < 0 || t.x > len)
return - fabs (t.y);
else
return fabs (t.y);
//} catch(...) {}
}
float VectorRun::Delta (Vector& p0, Vector& n0, Vector& p1, Vector& n1)
//功能: 计算对于曲线段i从p0点到p1点用直线段逼近的误差值, //采用近似圆弧拟合
//参数: p0, p1 -- 曲线上两点, n0, n1 -- 曲线上两点的法矢
//返回: 误差值
{
int ret;
float l0, l1, p, cosa, cos2a;
Vector m0, m1, t;
//计算两法矢交点
ret = Intersection (t, p0, p0 + n0, p1, p1 + n1);
if (ret == -1)
return 0; //两法矢平行
else
{
m0 = p0 - t; //T 为交点,求起点到交点的矢量差
m1 = p1 - t; //求终点到交点的矢量差
l0 = Length (m0); //计算起点至交点两点间的斜长
l1 = Length (m1); //计算终点至交点两点间的斜长
//VERIFY (l0 != 0 && l1 != 0);
if( l0 <= MINI || l1 <= MINI)
return 0;
p = (l0 + l1) / 2; //两条线段点间的长度,求平均值;
//可能均分得不对,造成误差,曲线不同,
//两条边长相差会不同,可能会较大,则均分会有较大误差
//p = l0; //取起点边判
cos2a = (m0 * m1) / l0 / l1;
cosa = sqrt ((1 + cos2a) / 2);
return p * (1 - cosa); //计算 起点边 * (1-底边/起始边)相当于弦高,当弦高小于某一数值时,即为所求的点
}
}
float VectorRun::Det (float det[3][3])
//功能: 计算三阶行列式的值
//参数: det -- 行列式的元素
//返回: 行列式的值
{
return (det[0][0] * det[1][1] * det[2][2] +
det[1][0] * det[2][1] * det[0][2] +
det[2][0] * det[0][1] * det[1][2] -
det[0][0] * det[2][1] * det[1][2] -
det[1][0] * det[0][1] * det[2][2] -
det[2][0] * det[1][1] * det[0][2]);
}
//tap 得到线段的法向量
Vector VectorRun::GetVerVector(Vector v1,Vector v2,double r)
{
Vector ōffv=v2-v1;
ōffv=Rotate(offv,Vector(0,-1));
return offv/Length(offv)*r;
}
double VectorRun::CalAngel(Vector &v)
{
double nlen=sqrt((v.x * v.x + v.y * v.y));
double lRadians=asin(v.y / nlen);
lRadians=lRadians / DEGREES_TO_RADIANS ;
if(v.x<0)
{
if(lRadians>0)
lRadians=180 - lRadians;
else
lRadians=-(180 + lRadians);
}
return lRadians;
}
//tap 比较角度的大小
int VectorRun::CompareAngle(Vector sv,Vector ev)
{
sv=sv/Length(sv);
ev=ev/Length(ev);
Vector v=AngleSub(ev,sv);
if (v.y>0)
return 1;
else if (v.y==0)
return 0;
else
return -1;
}
//tap 在线段v1v2求一点,使它与p的连线垂直与v1v2
Vector VectorRun::GetVerPoint(Vector v1, Vector v2,Vector p)
{
Vector ōffv=v2-v1;
offv=Rotate(offv,Vector(0,1));
return InterPoint (v1,v2,p,p+offv);
}
Vector VectorRun::InterPoint (const Vector& p1, const Vector& p2, const Vector& l1, const Vector& l2)
//计算两条线段(p1-p2, l1-l2)的交点
//返回: interpoint 交点
{
float m, u, v;
Vector interpoint;
Vector dp = p2 - p1;
Vector dl = l1 - l2;
Vector dd = l1 - p1;
m = Det (dp, dl);
//try
//{
if (fabs (m) < MINI)
return Vector(0,0);
else
{
VERIFY ( m != 0);
u = Det (dd, dl) / m;
v = Det (dp, dd) / m;
interpoint = p1 * (1 - u) + p2 * u; //两线的交点
return interpoint;
}
//} catch(...) {}
}
//tap 得到两条交线角平分线线上的一点
Vector VectorRun::GetCirclePoint(Vector v1,Vector v2,Vector v3,Vector v4,float r)
{
Vector offv;
Vector vv[4];
if (CompareAngle(v4-v3,v2-v1)>=0)
{
ōffv=GetVerVector(v1,v2,r);
vv[0]=v1+offv;
vv[1]=v2+offv;
offv=GetVerVector(v3,v4,r);
vv[2]=v3-offv;
vv[3]=v4-offv;
}
else
{
ōffv=GetVerVector(v1,v2,r);
vv[0]=v1-offv;
vv[1]=v2-offv;
offv=GetVerVector(v3,v4,r);
vv[2]=v3+offv;
vv[3]=v4+offv;
}
return InterPoint (vv[0],vv[1],vv[2],vv[3]);
}
//tap 得到圆弧的型值点,返回型值点个数
int VectorRun::GetArcOrgPoint(Vector ctv,Vector stv,Vector edv,Vector org[] )
{
Vector ōffv=stv-ctv;
int pos=0,p;
org[pos++]=stv;
if (CompareAngle(edv-ctv,stv-ctv)>=0)
{
offv=Rotate(offv,Vector(0.996,-0.087));
p=CompareAngle(edv-ctv,offv);
while(p>0)
{
org[pos++]=ctv+offv;
ōffv=Rotate(offv,Vector(0.996,-0.087));
p=CompareAngle(edv-ctv,offv);
}
}
else
{
offv=Rotate(offv,Vector(0.996,0.087));
p=CompareAngle(edv-ctv,offv);
while(p<0)
{
org[pos++]=ctv+offv;
ōffv=Rotate(offv,Vector(0.996,0.087));
p=CompareAngle(edv-ctv,offv);
}
}
org[pos]=edv;
return pos+1;
}
BOOL VectorRun::PointInAngle(Vector v1, Vector v2,Vector v3,Vector p)//2006-3-8
//功能: 判断点p是否在v2-v1-v3的区域内
{
if ((CompareAngle(v2-v1,p-v1)>=0)&&(CompareAngle(v3-v1,p-v1)<=0)
||(CompareAngle(v2-v1,p-v1)<=0)&&(CompareAngle(v3-v1,p-v1)>=0))
return TRUE;
else
return FALSE;
}
//功能,得到形值点
int VectorRun::GetCircleOrgPoint(Vector ctv,float r,Vector org[] )
{
Vector ōffv=Vector(r,0);
for(int i=0;i<13;i++)
{
offv=Rotate(offv,Vector(0.866,0.5));
org[i]=ctv+offv;
}
return 13;
}