请教一个绘图的问题!在线结贴!!

时间:2022-09-04 19:04:23
http://www.china-machine.com/MachineBase/Mechanism/elgjgfx.asp
我想做一个像上面这个网页上显示的那样(平面四杆机构),输入几个参数后由主动杆带动其他杆动起来。我现在做出来的可以根据输入参数画出这几个杆了,但就是动不起来,请问各位大哥,要怎么做才能让他动起来。输入的参数要求是:最长杆+最短杆《=其余两个杆长度之和。由于我只能给100分,如果分不够还请见谅!!

5 个解决方案

#1


你要用一个定时器
在每一个周期不断的变换可以动的那两个点的坐标。擦去原来画的三条线,用新的坐标重新画出三条线

#2


我的绘图函数是这样的
void CChildView::draw(int m_nXz, int m_nYz, float m_nL1, float m_nL2, float m_nL3, float m_nL4, float m_nKx, float m_nKy)
{
int i,k=20,m,n,ni,xa,ya,aa;
    long int j;
    int x[2][3],y[2][3],xx[720],yy[720];
    float CON,TH,g,g1,g2,g3,g4,g5,h,e,cg4,cg5;
    float x1[3],y1[3];
    
CPaintDC dc(this);

CPen pen[3];
pen[0].CreatePen(PS_SOLID,1,RGB(0,0,0));
pen[1].CreatePen(PS_SOLID,15,RGB(255,255,0));
pen[2].CreatePen(PS_SOLID,5,RGB(255,255,255));
CPen *pOldPen = dc.SelectObject(&pen[0]);

CON=(float)atan(1)*3/45;
    e=(float)sqrt(m_nKx*m_nKx+m_nKy*m_nKy);
    if(m_nKx!=0)
TH=(float)atan(m_nKy/m_nKx);
    else 
if(m_nKy>0)
TH=(float)PI/2;
    else
TH=(float)(-PI/2);
    if(m_nKx<0)
TH=(float)(TH+PI);
    if((m_nKx>0)&&(m_nKy<0))
TH=(float)(2*PI+TH);
    for(j=0;j<3;j++)
{
x[1][j]=0;y[1][j]=0;
}

dc.Ellipse(m_nXz,m_nYz+2,m_nXz+12,m_nYz+14);
dc.Ellipse(m_nXz+m_nL4*k,m_nYz+2,m_nXz+m_nL4*k+12,m_nYz+14);

dc.MoveTo(m_nXz+6,m_nYz+14);
dc.LineTo(m_nXz-6,m_nYz+26);
dc.MoveTo(m_nXz+6,m_nYz+14);
dc.LineTo(m_nXz+12,m_nYz+26);

dc.MoveTo(m_nXz+6+m_nL4*k,m_nYz+14);
dc.LineTo(m_nXz-6+m_nL4*k,m_nYz+26);
dc.MoveTo(m_nXz+6+m_nL4*k,m_nYz+14);
dc.LineTo(m_nXz+6+m_nL4*k,m_nYz+26);

dc.MoveTo(m_nXz-18,m_nYz+20);
dc.LineTo(m_nXz+18+m_nL4*k,m_nYz+20);

for(m=m_nXz-10; m<=(int)m_nXz+18+m_nL4*k; m+=10)
{
dc.MoveTo(m,m_nYz+20);
dc.LineTo(m-10,m_nYz+30);
}
for(m=0;m<2;m++)
{
for(i=0;i<=120;i++)
{
dc.SelectObject(&pen[1]);
if(kbhit())
{
aa=getch();
if(aa==ESCKEY)
{
i=121;m=2;
break;
}
}
}
}

dc.SetROP2(R2_XORPEN);

g1=CON*i;
    x1[0]=m_nL1*(float)cos(g1);
    y1[0]=m_nL1*(float)sin(g1);
    h=(float)sqrt(m_nL1*m_nL1+m_nL4*m_nL4-2*m_nL1*m_nL4*cos(g1));
    cg4=(m_nL4*m_nL4+h*h-m_nL1*m_nL1)/(2*m_nL4*h);
    g4=(float)acos(cg4);
    cg5=(m_nL3*m_nL3+h*h-m_nL2*m_nL2)/(2*m_nL3*h);
    g5=(float)acos(cg5);
    g3=(float)(PI-g4-g5);
    if(sin(g1)<0)
{
g3=(float)(PI-g5+g4);
}
    x1[1]=m_nL4+m_nL3*(float)cos(g3);
    y1[1]=m_nL3*(float)sin(g3);
    g=(float)acos((m_nL2*m_nL2+h*h-m_nL3*m_nL3)/2/m_nL2/h);
    g2=g-g4;
    if(sin(g1)<0)
{
g2=g+g4;
}
    x1[2]=x1[0]+e*(float)cos(TH+g2);
    y1[2]=y1[0]+e*(float)sin(TH+g2);
    for(j=0;j<3;j++){
x[0][j]=(int)(x1[j]*k+0.5);
y[0][j]=(int)(y1[j]*k+0.5);
}

dc.SelectObject(&pen[2]);

if(i!=0||m==1)
{
dc.MoveTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.LineTo(x[1][1]+m_nXz,m_nYz-y[1][1]);
dc.MoveTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
dc.LineTo(x[0][1]+m_nXz,m_nYz-y[0][1]);
}
  

    if(m_nKy==0)
{
if(m_nKx<0)
{
if(i!=0||m==1)
{
dc.MoveTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
dc.MoveTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
}   
     else
 if(m_nKx>m_nL2)
 {
 if(i!=0||m==1)
 {
 dc.MoveTo(x[1][1]+m_nXz,m_nYz-y[1][1]);
 dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
 dc.MoveTo(x[0][1]+m_nXz,m_nYz-y[1][1]);
 dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
 }
 }
}
}
    if(m_nKy!=0)
{
if(i!=0||m==1)
{
dc.MoveTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
dc.MoveTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
}

if(i!=0||m==1)
{
dc.MoveTo(x[1][1]+m_nXz,m_nYz-y[1][1]);
dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
dc.MoveTo(x[0][1]+m_nXz,m_nYz-y[0][1]);
dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
}
}


    if(i!=0||m==1)
{

dc.MoveTo(m_nXz+m_nL4*k,m_nYz);
dc.LineTo(x[0][1]+m_nXz,m_nYz-y[0][1]);
}
    if(i!=0||m==1)
{
dc.MoveTo(m_nXz,m_nYz);
dc.LineTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.MoveTo(m_nXz,m_nYz);
dc.LineTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
}

if(m!=1)
{
if(i!=0)
{
if(m_nKx>m_nL2)
{
xa=m_nXz+2;
if(m_nKy>0)
ya=m_nYz-2;
else
ya=m_nYz+2;
}
else 
if(m_nKx<0)
{
xa=m_nXz-2;
if(m_nKy<0)
ya=m_nYz+2;
else 
ya=m_nYz-2;
}
else 
{
xa=m_nXz;
if(m_nKy>0)
ya=m_nYz-2;
else ya=m_nYz+2;
}



dc.SetPixel(x[0][2]+xa,ya-y[0][2],RGB(255,255,255));
}

for(j=0;j<3;j++)
{
x[1][j]=x[0][j];y[1][j]=y[0][j];
}
        Sleep(50);
}

dc.SetROP2(R2_COPYPEN);

dc.SelectObject(pOldPen);


for(i=0;i<3;i++)
{
pen[i].DeleteObject();
}

return ;
}我的问题是可以画出几个杆来,但就是动不起来,请大家帮个忙,我现在是火烧眉头了。

#3


估计你是没有做到及时刷新屏幕。
你可以尝试,不断地拖动窗口的大小,看看内容是否变化。
windows的消息驱动机制是只有窗口内容发生变化的时候才重新绘制。
你可以在你的函数当中发送更新窗口内容的消息呀Invalidata和UpdateWindow。

#4


我知道我提的问题是很简单的,对熟悉vc编程的人来说根本就不值一提。但我就是比较笨,搞不清楚啊。这关系到我能否毕业的问题啊(就只有两三天就要交差了),请好心人帮个忙吧。

#5


可以把工程发给我,我帮你测试一下。一大堆代码很难让别人耐心的看完。
wzl@chinapages.com

#1


你要用一个定时器
在每一个周期不断的变换可以动的那两个点的坐标。擦去原来画的三条线,用新的坐标重新画出三条线

#2


我的绘图函数是这样的
void CChildView::draw(int m_nXz, int m_nYz, float m_nL1, float m_nL2, float m_nL3, float m_nL4, float m_nKx, float m_nKy)
{
int i,k=20,m,n,ni,xa,ya,aa;
    long int j;
    int x[2][3],y[2][3],xx[720],yy[720];
    float CON,TH,g,g1,g2,g3,g4,g5,h,e,cg4,cg5;
    float x1[3],y1[3];
    
CPaintDC dc(this);

CPen pen[3];
pen[0].CreatePen(PS_SOLID,1,RGB(0,0,0));
pen[1].CreatePen(PS_SOLID,15,RGB(255,255,0));
pen[2].CreatePen(PS_SOLID,5,RGB(255,255,255));
CPen *pOldPen = dc.SelectObject(&pen[0]);

CON=(float)atan(1)*3/45;
    e=(float)sqrt(m_nKx*m_nKx+m_nKy*m_nKy);
    if(m_nKx!=0)
TH=(float)atan(m_nKy/m_nKx);
    else 
if(m_nKy>0)
TH=(float)PI/2;
    else
TH=(float)(-PI/2);
    if(m_nKx<0)
TH=(float)(TH+PI);
    if((m_nKx>0)&&(m_nKy<0))
TH=(float)(2*PI+TH);
    for(j=0;j<3;j++)
{
x[1][j]=0;y[1][j]=0;
}

dc.Ellipse(m_nXz,m_nYz+2,m_nXz+12,m_nYz+14);
dc.Ellipse(m_nXz+m_nL4*k,m_nYz+2,m_nXz+m_nL4*k+12,m_nYz+14);

dc.MoveTo(m_nXz+6,m_nYz+14);
dc.LineTo(m_nXz-6,m_nYz+26);
dc.MoveTo(m_nXz+6,m_nYz+14);
dc.LineTo(m_nXz+12,m_nYz+26);

dc.MoveTo(m_nXz+6+m_nL4*k,m_nYz+14);
dc.LineTo(m_nXz-6+m_nL4*k,m_nYz+26);
dc.MoveTo(m_nXz+6+m_nL4*k,m_nYz+14);
dc.LineTo(m_nXz+6+m_nL4*k,m_nYz+26);

dc.MoveTo(m_nXz-18,m_nYz+20);
dc.LineTo(m_nXz+18+m_nL4*k,m_nYz+20);

for(m=m_nXz-10; m<=(int)m_nXz+18+m_nL4*k; m+=10)
{
dc.MoveTo(m,m_nYz+20);
dc.LineTo(m-10,m_nYz+30);
}
for(m=0;m<2;m++)
{
for(i=0;i<=120;i++)
{
dc.SelectObject(&pen[1]);
if(kbhit())
{
aa=getch();
if(aa==ESCKEY)
{
i=121;m=2;
break;
}
}
}
}

dc.SetROP2(R2_XORPEN);

g1=CON*i;
    x1[0]=m_nL1*(float)cos(g1);
    y1[0]=m_nL1*(float)sin(g1);
    h=(float)sqrt(m_nL1*m_nL1+m_nL4*m_nL4-2*m_nL1*m_nL4*cos(g1));
    cg4=(m_nL4*m_nL4+h*h-m_nL1*m_nL1)/(2*m_nL4*h);
    g4=(float)acos(cg4);
    cg5=(m_nL3*m_nL3+h*h-m_nL2*m_nL2)/(2*m_nL3*h);
    g5=(float)acos(cg5);
    g3=(float)(PI-g4-g5);
    if(sin(g1)<0)
{
g3=(float)(PI-g5+g4);
}
    x1[1]=m_nL4+m_nL3*(float)cos(g3);
    y1[1]=m_nL3*(float)sin(g3);
    g=(float)acos((m_nL2*m_nL2+h*h-m_nL3*m_nL3)/2/m_nL2/h);
    g2=g-g4;
    if(sin(g1)<0)
{
g2=g+g4;
}
    x1[2]=x1[0]+e*(float)cos(TH+g2);
    y1[2]=y1[0]+e*(float)sin(TH+g2);
    for(j=0;j<3;j++){
x[0][j]=(int)(x1[j]*k+0.5);
y[0][j]=(int)(y1[j]*k+0.5);
}

dc.SelectObject(&pen[2]);

if(i!=0||m==1)
{
dc.MoveTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.LineTo(x[1][1]+m_nXz,m_nYz-y[1][1]);
dc.MoveTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
dc.LineTo(x[0][1]+m_nXz,m_nYz-y[0][1]);
}
  

    if(m_nKy==0)
{
if(m_nKx<0)
{
if(i!=0||m==1)
{
dc.MoveTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
dc.MoveTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
}   
     else
 if(m_nKx>m_nL2)
 {
 if(i!=0||m==1)
 {
 dc.MoveTo(x[1][1]+m_nXz,m_nYz-y[1][1]);
 dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
 dc.MoveTo(x[0][1]+m_nXz,m_nYz-y[1][1]);
 dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
 }
 }
}
}
    if(m_nKy!=0)
{
if(i!=0||m==1)
{
dc.MoveTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
dc.MoveTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
}

if(i!=0||m==1)
{
dc.MoveTo(x[1][1]+m_nXz,m_nYz-y[1][1]);
dc.LineTo(x[1][2]+m_nXz,m_nYz-y[1][2]);
dc.MoveTo(x[0][1]+m_nXz,m_nYz-y[0][1]);
dc.LineTo(x[0][2]+m_nXz,m_nYz-y[0][2]);
}
}


    if(i!=0||m==1)
{

dc.MoveTo(m_nXz+m_nL4*k,m_nYz);
dc.LineTo(x[0][1]+m_nXz,m_nYz-y[0][1]);
}
    if(i!=0||m==1)
{
dc.MoveTo(m_nXz,m_nYz);
dc.LineTo(x[1][0]+m_nXz,m_nYz-y[1][0]);
dc.MoveTo(m_nXz,m_nYz);
dc.LineTo(x[0][0]+m_nXz,m_nYz-y[0][0]);
}

if(m!=1)
{
if(i!=0)
{
if(m_nKx>m_nL2)
{
xa=m_nXz+2;
if(m_nKy>0)
ya=m_nYz-2;
else
ya=m_nYz+2;
}
else 
if(m_nKx<0)
{
xa=m_nXz-2;
if(m_nKy<0)
ya=m_nYz+2;
else 
ya=m_nYz-2;
}
else 
{
xa=m_nXz;
if(m_nKy>0)
ya=m_nYz-2;
else ya=m_nYz+2;
}



dc.SetPixel(x[0][2]+xa,ya-y[0][2],RGB(255,255,255));
}

for(j=0;j<3;j++)
{
x[1][j]=x[0][j];y[1][j]=y[0][j];
}
        Sleep(50);
}

dc.SetROP2(R2_COPYPEN);

dc.SelectObject(pOldPen);


for(i=0;i<3;i++)
{
pen[i].DeleteObject();
}

return ;
}我的问题是可以画出几个杆来,但就是动不起来,请大家帮个忙,我现在是火烧眉头了。

#3


估计你是没有做到及时刷新屏幕。
你可以尝试,不断地拖动窗口的大小,看看内容是否变化。
windows的消息驱动机制是只有窗口内容发生变化的时候才重新绘制。
你可以在你的函数当中发送更新窗口内容的消息呀Invalidata和UpdateWindow。

#4


我知道我提的问题是很简单的,对熟悉vc编程的人来说根本就不值一提。但我就是比较笨,搞不清楚啊。这关系到我能否毕业的问题啊(就只有两三天就要交差了),请好心人帮个忙吧。

#5


可以把工程发给我,我帮你测试一下。一大堆代码很难让别人耐心的看完。
wzl@chinapages.com