📄 图形相交—相切view.cpp
字号:
b=-(l2[0]-l1[0]);
c1=-l1[0]*l2[1]+l2[0]*l1[1];
dd=sqrt(a*a+b*b);
d=-(a*c[0]+b*c[1]+c1)/dd;//计算圆心到直线的有向距离
if(fabs(d)>fabs(c[2])) return -1; //直线与圆不相交相离
else if(fabs(d)==fabs(c[2])) //直线与圆相切
{
xa=(b*b*c[0]-a*b*c[1]-a*c1)/(dd*dd);//A点坐标
ya=-(a*a*c[1]-a*b*c[0]-b*c1)/(dd*dd);
sa=a/dd;
ca=-a/dd;
dp=sqrt(c[2]*c[2]-d*d);
p1[0]=xa-dp*ca;
p1[1]=ya-dp*sa;
return 0;
}
else if(fabs(d)<fabs(c[2]))
{xa=(b*b*c[0]-a*b*c[1]-a*c1)/(dd*dd);//A点坐标
ya=-(a*a*c[1]-a*b*c[0]-b*c1)/(dd*dd);
sa=a/dd;
ca=-a/dd;
dp=sqrt(c[2]*c[2]-d*d);
p1[0]=xa-dp*ca;
p1[1]=ya-dp*sa;
p2[0]=xa+dp*ca;
p2[1]=ya+dp*sa;
return 1; //直线与圆相交
}
}
/////////////////////////////////////////////////////////////////////////////
// CMyView message handlers
void CMyView::OnLineLine()
{
// TODO: Add your command handler code here
RedrawWindow();
PushNum=1;
CDC*pDC=GetDC(); //获得绘图类指针
pDC->TextOut(0,5,"用鼠标右键在窗口取选取四个点,当鼠标右键按下第5次求交点");
ReleaseDC(pDC);
}
void CMyView::OnLineCiercle1()
{
// TODO: Add your command handler code here
PushNum=2;
Mydraw();
}
void CMyView::OnCircleCircle()
{
// TODO: Add your command handler code here
PushNum=4;
Mydraw();
}
void CMyView::OnLineCircle()
{
// TODO: Add your command handler code here
PushNum=3;
Mydraw();
}
void CMyView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(PushNum=1)
{
num++;
if(num<5)
{ P2[num].x=point.x; //初始化给相应变量
P2[num].y=point.y;
}
else if(num=5)
{
CDC *pDC=GetDC(); //获得CDC对象
CPen pen1(PS_SOLID,1,(COLORREF)255),pen2(PS_SOLID,1,(COLORREF)255*255);
CPen* pOldPen=pDC->SelectObject(&pen1); //设置画线颜色
pDC->MoveTo(P2[1].x,P2[1].y); //在P0点显示小十字光标
pDC->LineTo(P2[2].x,P2[2].y);
pDC->MoveTo(P2[3].x,P2[3].y);
pDC->LineTo(P2[4].x,P2[4].y);
pDC->SelectObject(pOldPen);
P1x=P2[1].x;
P1y=P2[1].y;
P2x=P2[2].x;
P2y=P2[2].y;
P3x=P2[3].x;
P3y=P2[3].y;
P4x=P2[4].x;
P4y=P2[4].y;
int k=PLL(P1x,P1y,P2x,P2y,P3x,P3y,P4x,P4y,Px,Py); //调用两线段相交子程序
switch(k)
{case -1:pDC->TextOut(10,50,"两线段平行或重合!");
break;
case 0:pDC->TextOut(10,50,"无效交点!");
break;
case 1:pDC->TextOut(10,50,"您选取的四个点分别为:");
CString a1,a2;
a1.Format("%e %e %e %e",P1x,P1y,P2x,P2y); //将数字转化为字符串
a2.Format("%e %e %e %e",P3x,P3y,P4x,P4y);
// pDC->TextOut(0,40,a);
a1.Format("%e %e",P1x,P1y,P2x,P2y); //将数字转化为字符串
a2.Format("%e %e",P3x,P3y,P4x,P4y); //将数字转化为字符串
pDC->TextOut(10,70,a1);
pDC->TextOut(10,90,a1);
pDC->TextOut(10,110,"有效交点为:");
CString b;
b.Format("%e %e",Px,Py); //将数字转化为字符串
pDC->TextOut(10,130,b);
break;
}
ReleaseDC(pDC); //释放CDC对象
}
}
CView::OnRButtonDown(nFlags, point);
}
void CMyView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if(PushNum==2)
{
switch(nChar){
case VK_UP: //上下左右键选择
l1[1]-=2;
Mydraw();
break;
case VK_DOWN:
l1[1]+=2;
Mydraw();
break;
case VK_RIGHT:
l2[0]+=2;
Mydraw();
break;
case VK_LEFT:
l2[0]-=2;
Mydraw();
break;
default:
break;
}
}
if(PushNum==3)
{
switch(nChar){
case VK_UP: //上下左右键选择
P0[1]-=2;
Mydraw();
break;
case VK_DOWN:
P0[1]+=2;
Mydraw();
break;
case VK_RIGHT:
P0[0]+=2;
Mydraw();
break;
case VK_LEFT:
P0[0]-=2;
Mydraw();
break;
default:
break;
}
}
if(PushNum==4)
{
switch(nChar){
case VK_UP: //上下左右键选择
c1[1]-=2;
Mydraw();
break;
case VK_DOWN:
c1[1]+=2;
Mydraw();
break;
case VK_RIGHT:
c2[2]+=2;
Mydraw();
break;
case VK_LEFT:
c2[2]-=2;
Mydraw();
break;
default:
break;
}
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CMyView::OnPlaneCylinder()
{
// TODO: Add your command handler code here
RedrawWindow();
int i;
float beta=0.0,db=3.14159/18.0,a;
float x0=300,y0=200; //初始化圆柱底圆中心坐标显示位置
float p1[3],pp1[3],p2[3],pp2[3]; //p1,pp1为椭圆截交线上点变换前后的坐标,p2,pp2为椭圆截交线上点变换前后的坐标,
float x1,y1,x2,y2;
float p0[3],R,H,alfa;
p0[0]=p0[1]=p0[2]=100;
R=100,H=100,alfa=30;//初始化圆柱与截交面与底面夹角
a=R*tan(alfa*db*0.1);
CDC*pDC=GetDC();
p1[0]=p2[0]=p0[0]+R;//计算底面初始点坐标
p1[1]=p2[1]=p0[1];
p1[2]=p0[2]+H+a;
p2[2]=p0[2];
Tiso(p1,x0,y0,pp1);//正等测变换
Tiso(p2,x0,y0,pp2);
x1=pp1[0],y1=pp1[1];
x2=pp2[0],y2=pp2[2];
pDC->MoveTo(x1,y1); //连接z方向竖线
pDC->LineTo(x2,y2);
pDC->TextOut(250,80,"平面截圆柱体");
for(i=1;i<=36;i++) //按36等分计算和绘制圆柱截交线
{
beta+=db;
p1[0]=p2[0]=p0[0]+R*cos(beta);
p1[1]=p2[1]=p0[1]+R*sin(beta);
p1[2]=p0[2]+H+a*(1.0-sin(beta));
p2[2]=p2[0];
Tiso(p1,x0,y0,pp1);
Tiso(p2,x0,y0,pp2);
CPen pen(PS_SOLID,1,(COLORREF)255);
CPen* pOldPen=pDC->SelectObject(&pen); //设置画线颜色
pDC->MoveTo(x1,y1); //连接椭圆截交线
pDC->LineTo(pp1[0],pp1[1]);
pDC->SelectObject(pOldPen);
x1=pp1[0],y1=pp1[1];
x2=pp2[0],y2=pp2[2];
pDC->MoveTo(x1,y1); //连接z方向竖线
pDC->LineTo(x2,y2);
}
ReleaseDC(pDC);
}
void CMyView::OnPlaneCone()
{
RedrawWindow();
int i;
float beta=0.0,db=3.14159/18.0,a,r1;
float x0=300,y0=200; //初始化圆柱底圆中心坐标显示位置
float p1[3],pp1[3],p2[3],pp2[3]; //p1,pp1为椭圆截交线上点变换前后的坐标,p2,pp2为椭圆截交线上点变换前后的坐标,
float x1,y1,x2,y2;
float p0[3],R,H,alfa,theta;
p0[0]=p0[1]=p0[2]=100; //初始化圆锥、截交面与底面夹角
R=50,H=100,theta=250,alfa=-30;
r1=R-H*sin(theta*db*0.1);
a=r1*tan(alfa*db*0.1);
CDC*pDC=GetDC();
p1[0]=p0[0]+r1;
p2[0]=p0[0]+R;//计算底面初始点坐标
p1[1]=p2[1]=p0[1];
p1[2]=p0[2]+H+a;
p2[2]=p0[2];
Tiso(p1,x0,y0,pp1);//正等测变换
Tiso(p2,x0,y0,pp2);
x1=pp1[0],y1=pp1[1];
x2=pp2[0],y2=pp2[2];
pDC->MoveTo(x1,y1); //连接z方向竖线
pDC->LineTo(x2,y2);
pDC->TextOut(250,60,"平面截圆锥体");
for(i=1;i<=36;i++) //按72等分计算和绘制圆柱截交线
{
beta+=db;
p1[0]=p0[0]+r1*cos(beta);
p2[0]=p0[0]+R*cos(beta);
p1[1]=p0[1]+r1*sin(beta);
p2[1]=p0[1]+R*sin(beta);
p1[2]=p0[2]+H+a*(1.0-sin(beta));
p2[2]=p0[2];
Tiso(p1,x0,y0,pp1);
Tiso(p2,x0,y0,pp2);
CPen pen(PS_SOLID,1,(COLORREF)255);
CPen* pOldPen=pDC->SelectObject(&pen); //设置画线颜色
pDC->MoveTo(x1,y1); //连接椭圆截交线
pDC->LineTo(pp1[0],pp1[1]);
pDC->SelectObject(pOldPen);
x1=pp1[0],y1=pp1[1];
x2=pp2[0],y2=pp2[2];
pDC->MoveTo(x1,y1); //连接z方向竖线
pDC->LineTo(x2,y2);
}
ReleaseDC(pDC);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -