昨天发的那个帖子条件没说清,今天整理了一下问题,应该算比较清楚了,自己也推了一下,但感觉结果不太好,想求一个好的解决方法,请达人抽点宝贵时间帮忙看看。如左图:已知A,B两点的坐标,分别过A,B两点将AB顺时针旋转15度(为了便于计算,也可改为45度的一半或者其他,但最好不要大于30度)和45度,旋转后相交与C点,BE垂直AB与AC交与E,BD=1/2BE。求C,D点的坐标?
PS:主要是想通过A,B两点的坐标画一个类似右图红线画出的箭头,为了美观,所以∠CAB不能太大也不能太小。
PS:主要是想通过A,B两点的坐标画一个类似右图红线画出的箭头,为了美观,所以∠CAB不能太大也不能太小。
BD=tan(15度)*AB/2
Dx=Bx-tan(15度)*AB/2
Dy=By
过C做AB的垂线,与AB交于F点,则BF=CF=tan(15度)*AF
CF=tan(15度)*(AB+CF)
CF=tan(15度)*AB/(1-tan(15度))
Cx=Bx-tan(15度)*AB/(1-tan(15度))
Cy=By-tan(15度)*AB/(1-tan(15度))
sin15 = 0.258
cos15 = 0.966因此,可以找C点与AB的焦点G,设AB为x,BG为y,则
y = (x + y) * 0.258G求出来后,C、D的坐标就好确定了
先假设B为原点,BA为Y轴正方向,先计算出C、D点坐标,然后在旋转和平移坐标系来得到C、D点的真正坐标。
平移是point.x + x, point.y + y
旋转是point.x * x, point.y * y
直角坐标系到极坐标系转换:
ρ=sqrt(x*x+y*y)
θ=atan(y/x)
极坐标系到直角坐标系转换:
x=ρ*cos(θ)
y=ρ*sin(θ)
极坐标系旋转:
θ+=α
直角坐标系平移:
x+=a
y+=b
计算的时候用浮点数,画图的时候转成整数。
{
if (m_bPrePtReady)
{
m_bPrePtReady = FALSE;
DrawArrow(m_PrePt.x,m_PrePt.y,point.x,point.y);
}
else
{
m_bPrePtReady = TRUE;
m_PrePt = point;
}
CDialog::OnLButtonUp(nFlags, point);
}void CDrawDlg::DrawArrow(double Xa,double Ya,double Xb,double Yb)
{
double scale=sqrt((Xa-Xb)*(Xa-Xb)+(Ya-Yb)*(Ya-Yb));
double sinAngle=Yb - Ya;
double cosAngle=Xa - Xb;
double xA=Xa;
double yA=Ya;
double xC=0.36602540378443864676372317075287;
double yC=1.36602540378443864676372317075287;
double xD=0.13397459621556135323627682924706;
double yD=1.0;
double xF=0.267949192431122706472553658494;
double yF=2.0;
double lxC,lyC,lxD,lyD,lxF,lyF,rxC,ryC,rxD,ryD,rxF,ryF;
lxC = xA + sinAngle*xC - cosAngle*yC + 0.5;
lyC = yA + cosAngle*xC + sinAngle*yC + 0.5;
lxD = xA + sinAngle*xD - cosAngle*yD + 0.5;
lyD = yA + cosAngle*xD + sinAngle*yD + 0.5;
lxF = xA + sinAngle*xF - cosAngle*yF + 0.5;
lyF = yA + cosAngle*xF + sinAngle*yF + 0.5; rxC = xA + sinAngle*-xC - cosAngle*yC + 0.5;
ryC = yA + cosAngle*-xC + sinAngle*yC + 0.5;
rxD = xA + sinAngle*-xD - cosAngle*yD + 0.5;
ryD = yA + cosAngle*-xD + sinAngle*yD + 0.5;
rxF = xA + sinAngle*-xF - cosAngle*yF + 0.5;
ryF = yA + cosAngle*-xF + sinAngle*yF + 0.5;
CClientDC dc(this);
dc.MoveTo(lxF,lyF);
dc.LineTo(lxD,lyD);
dc.LineTo(lxC,lyC);
dc.LineTo(xA,yA);
dc.LineTo(rxC,ryC);
dc.LineTo(rxD,ryD);
dc.LineTo(rxF,ryF);
}
BE=2*BD=tan(π/12)*AB
BD=tan(π/12)*AB/2
D点极坐标为:
ρD=tan(π/12)*AB/2
θD=π/2
过C做AB的垂线,与AB交于F点,则
BF=CF=tan(π/12)*AF
CF=tan(π/12)*(AB+CF)
CF=AB*tan(π/12)/(1-tan(π/12))
ρC=sqrt(2)*AB*tan(π/12)/(1-tan(π/12))
θC=π/2+π/4=3*π/42、旋转坐标系,设AB与X轴夹角为α,则旋转α角度后
ρD=tan(π/12)*AB/2
θD+=α=π/2+α
ρC=sqrt(2)*AB*tan(π/12)/(1-tan(π/12))
θC+=α=3*π/4+α
Dx=ρD*cos(θD)=tan(π/12)*AB/2*cos(π/2+α)
Dy=ρD*sin(θD)=tan(π/12)*AB/2*sin(π/2+α)
Cx=ρC*cos(θC)=sqrt(2)*AB*tan(π/12)/(1-tan(π/12))*cos(3*π/4+α)
Cy=ρC*sin(θC)=sqrt(2)*AB*tan(π/12)/(1-tan(π/12))*sin(3*π/4+α)
如果Ax=Bx,且Ay>By,α=π/2
如果Ax=Bx,且Ay<By,α=-π/2
如果Ax!=Bx,且Ay>=By,α=atan((Ay-By)/(Ax-Bx))
如果Ax!=Bx,且Ay<By,α=atan((Ay-By)/(Ax-Bx))+π3、平移坐标系
Dx+=Bx
Dy+=By
Cx+=Bx
Cy+=By
然后算出其他点的坐标。(也可以自己调整一下数值,因为你好像只是做一个图示)
然后根据AB的距离进行缩放,根据AB的角度进行旋转,根据A点的位置进行平移。
我用的是日文的系统,VC6 由于编码问题写中文注释是乱码的。
稍微改了下数值,感觉还是不是很好看。void CDrawDlg::DrawArrow(double Xa,double Ya,double Xb,double Yb)
{
double sinAngle=Yb - Ya;
double cosAngle=Xa - Xb;
double xA=Xa;
double yA=Ya;
double xC=0.6;//0.36602540378443864676372317075287;
double yC=1.6;//1.36602540378443864676372317075287;
double xD=0.2;//0.13397459621556135323627682924706;
double yD=1.0;//1.0;
double xF=0.5;//0.267949192431122706472553658494;
double yF=2.3;//2.0;
double lxC,lyC,lxD,lyD,lxF,lyF,rxC,ryC,rxD,ryD,rxF,ryF;
lxC = xA + sinAngle*xC - cosAngle*yC + 0.5;
lyC = yA + cosAngle*xC + sinAngle*yC + 0.5;
lxD = xA + sinAngle*xD - cosAngle*yD + 0.5;
lyD = yA + cosAngle*xD + sinAngle*yD + 0.5;
lxF = xA + sinAngle*xF - cosAngle*yF + 0.5;
lyF = yA + cosAngle*xF + sinAngle*yF + 0.5; rxC = xA + sinAngle*-xC - cosAngle*yC + 0.5;
ryC = yA + cosAngle*-xC + sinAngle*yC + 0.5;
rxD = xA + sinAngle*-xD - cosAngle*yD + 0.5;
ryD = yA + cosAngle*-xD + sinAngle*yD + 0.5;
rxF = xA + sinAngle*-xF - cosAngle*yF + 0.5;
ryF = yA + cosAngle*-xF + sinAngle*yF + 0.5;
CClientDC dc(this);
dc.MoveTo(lxF,lyF);
dc.LineTo(lxD,lyD);
dc.LineTo(lxC,lyC);
dc.LineTo(xA,yA);
dc.LineTo(rxC,ryC);
dc.LineTo(rxD,ryD);
dc.LineTo(rxF,ryF);
}