正文

C#下用GDI绘制城墙线波浪线等线型2007-10-31 11:37:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/tujun/30619.html

分享到:

调用的API: [DllImport("gdi32.dll", EntryPoint="LineDDA")]  public static extern int LineDDA (   int   nXStart,         //   线条起点的X坐标          int   nYStart,         //   线条起点的Y坐标      int   nXEnd,          //   线条终点的X坐标      int   nYEnd,          //   线条终点的Y坐标      LineDDAProcHandle  lpLineDDAProc,   IntPtr lParam   );  public delegate void    LineDDAProcHandle(      int   X, //   被求值点的X坐标      int   Y, //   被求值点的Y坐标      ref DrawStruct   lpData );  private void    LineDDAProc(      int   X, //   被求值点的X坐标      int   Y, //   被求值点的Y坐标      ref DrawStruct   mDrawStruct )//   应用程序定义数据的指针                 {        int modvalue = mDrawStruct.nWidth;   if((X % modvalue) == 0)   {    for(int i=X-modvalue;i<X;i++)    {     int YY =  (int)(modvalue * Math.Sin(1 * 3.1415926 * i / modvalue - modvalue));     LineTo(mDrawStruct.hdc,i,YY/2 + Y);     //SetPixel(mDrawStruct.hdc,i,YY,mDrawStruct.mColor);     }   }   //SetPixel(mDrawStruct.hdc,X,YY,mDrawStruct.mColor);    } public enum dwPenStyle   {   PS_GEOMETRIC =0x10000,   PS_COSMETIC = 0   }  //publc  public enum Hatch  {   HS_BDIAGONAL,   HS_CROSS,   HS_DIAGCROSS,   HS_FDIAGONAL,   HS_HORIZONTAL,   HS_VERTICAL  }  public enum Style  {   BS_DIBPATTERN,   BS_DIBPATTERN8X8,   BS_DIBPATTERNPT,   BS_HATCHED,   BS_HOLLOW,   BS_NULL,   BS_PATTERN,   BS_PATTERN8X8,   BS_SOLID  }  [StructLayout(LayoutKind.Sequential)]   public struct LOGBRUSH  {   public Style lbStyle;   public int crColor;   public Hatch lbHatch;  }   public enum PenStyles  {   PS_SOLID,   PS_DASH,   PS_DOT,   PS_DASHDOT,   PS_DASHDOTDOT  }  [DllImport("gdi32.dll", EntryPoint="MoveToEx")]  public static extern int MoveToEx (   IntPtr hdc,   int x,   int y,   IntPtr lpPoint   );  [DllImport("gdi32.dll")]  private static extern IntPtr CreatePen(PenStyles enPenStyle, int nWidth, int crColor);  [DllImport("gdi32.dll")]  private static extern IntPtr ExtCreatePen(   int dwPenStyle,      // pen style   int dwWidth,         // pen width   ref LOGBRUSH lplb,  // brush attributes   int dwStyleCount,    // length of custom style array   IntPtr lpStyle   // custom style array   );  [DllImport("gdi32.dll")]  private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);  [DllImport("gdi32.dll")]  protected static extern bool DeleteObject(IntPtr hObject);  public struct PenStylesStu  {   public PenStyles style;   public override string ToString()   {    return style.ToString ();   }  }  //  [DllImport("gdi32.dll", EntryPoint="MoveToEx")]  //  public static extern int MoveToEx (  //   IntPtr hdc,  //   int x,  //   int y,  //   ref POINTAPI lpPoint  //   );  [StructLayout(LayoutKind.Sequential)]   public struct POINTAPI  {   public int X;   public int Y;  }  [DllImport("gdi32.dll", EntryPoint="LineTo")]  public static extern int LineTo (   IntPtr hdc,   int x,   int y   );  [DllImport("gdi32.dll", EntryPoint="EndPath")]  public static extern int EndPath (   IntPtr hdc   );  [DllImport("gdi32.dll", EntryPoint="StrokePath")]  public static extern int StrokePath (   IntPtr hdc   );  [DllImport("gdi32.dll", EntryPoint="BeginPath")]  public static extern int BeginPath (   IntPtr hdc   );  public struct StyleStu  {   public Style style;   public override string ToString()   {    return style.ToString ();   }  }  public const int PS_GEOMETRIC = 0x10000;  public const int PS_COSMETIC = 0x0;  public const int PS_ENDCAP_ROUND = 0x0;  public const int PS_ENDCAP_SQUARE = 0x100;  public const int PS_ENDCAP_FLAT = 0x200;  public const int PS_JOIN_BEVEL = 0x1000;  public const int PS_JOIN_MITER = 0x2000;  public const int PS_JOIN_ROUND = 0x0;  public const int PS_SOLID = 0;  public const int BS_SOLID = 0;  public const int PS_USERSTYLE = 7;   绘制铁路线的代码: //绘制铁路线   Graphics g = Graphics.FromHwnd(this.panel1.Handle);//在panle1上绘制   g.Clear(Color.White);   IntPtr hdc = g.GetHdc();       ///先绘制直线,比指定宽度大2   Color c = this.label3.BackColor;    //获取颜色   int nWidth = (int)this.numericUpDown1.Value;//获取线宽   LOGBRUSH   lb;   lb.crColor= GetGDIRGB(c);   lb.lbHatch = Hatch.HS_BDIAGONAL;   lb.lbStyle = Style.BS_DIBPATTERN;       IntPtr      hPen, hOldPen;   nWidth = nWidth + 2;   hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID |    PS_GEOMETRIC/* |     iEnd [i] |     iJoin [i]*/,    nWidth , ref lb,0,IntPtr.Zero);   hOldPen = SelectObject(hdc,hPen);   MoveToEx(hdc,30,50,IntPtr.Zero);   LineTo(hdc,this.panel1.Width - 60,200);   SelectObject(hdc,hOldPen);    DeleteObject(hPen);    //再绘制白色虚线,用指定的宽度   c = Color.White;   lb.crColor= GetGDIRGB(c);   lb.lbHatch = Hatch.HS_BDIAGONAL;   lb.lbStyle = Style.BS_DIBPATTERN;    int[] kkk = new int[]{nWidth * 2,nWidth * 2};   int newWidth = nWidth - (nWidth/2)+1;   if(newWidth > nWidth - 2)    newWidth = nWidth - 2;   hPen = ExtCreatePen(PS_ENDCAP_FLAT| PS_USERSTYLE | PS_GEOMETRIC/* |     iEnd [i] |     iJoin [i]*/,    newWidth , ref lb,  kkk.Length, Marshal.UnsafeAddrOfPinnedArrayElement(kkk,0));   hOldPen = SelectObject(hdc,hPen);   MoveToEx(hdc,30,50,IntPtr.Zero);   LineTo(hdc,this.panel1.Width - 60,200);   SelectObject(hdc,hOldPen);    DeleteObject(hPen);    g.ReleaseHdc(hdc);      g.Dispose(); //绘制国界线 private void button8_Click(object sender, System.EventArgs e)  {   Graphics g = Graphics.FromHwnd(this.panel1.Handle);   g.Clear(Color.White);   IntPtr hdc = g.GetHdc();      DrawStruct str = new DrawStruct();   int nWidth = (int)this.numericUpDown1.Value;   str.hdc =  hdc;   Color c = this.label3.BackColor;   str.mColor = GetGDIRGB(c);   str.nWidth = nWidth;          LOGBRUSH   lb;   lb.crColor= GetGDIRGB(c);   lb.lbHatch = Hatch.HS_BDIAGONAL;   lb.lbStyle = Style.BS_DIBPATTERN;       IntPtr      hPen, hOldPen;      hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID |    PS_GEOMETRIC/* |     iEnd [i] |     iJoin [i]*/,    1 , ref lb,0,IntPtr.Zero);   hOldPen = SelectObject(hdc,hPen);      //MoveToEx(hdc,10,50,IntPtr.Zero);   str.oldX = this.panel1.Width -30;   str.oldY = 50;   str.nWidth = nWidth;   IntPtr  ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(str));   Marshal.StructureToPtr(str,ptr,true);   MoveToEx(hdc,str.oldX,str.oldY,IntPtr.Zero);   LineDDA(str.oldX,str.oldY,50,250, new LineDDAProcHandle(LineDDAProc_Guojie),ptr);    SelectObject(hdc,hOldPen);   DeleteObject(hPen);   g.ReleaseHdc(hdc);   Marshal.DestroyStructure(ptr,typeof(DrawStruct));   g.Dispose();  } /// <summary>  /// 绘制国界线回调函数  /// </summary>  /// <param name="X"></param>  /// <param name="Y"></param>  /// <param name="mDrawStruct"></param>  private void    LineDDAProc_Guojie(      int   X, //   被求值点的X坐标      int   Y, //   被求值点的Y坐标      ref DrawStruct   mDrawStruct )//   应用程序定义数据的指针                 {        int modvalue = mDrawStruct.nWidth;   double hg = mDrawStruct.nWidth;//方波高度   //计算2点间距离,粗略计算   double distance = 0.0;   double angle = Math.Atan((double)(Y - mDrawStruct.oldY) / (double)(X - mDrawStruct.oldX));//线夹角   distance = (double)(X - mDrawStruct.oldX)*(X - mDrawStruct.oldX) + (double)(Y - mDrawStruct.oldY)*(Y - mDrawStruct.oldY);   distance = Math.Abs( Math.Sqrt(distance));    if(distance > hg *4)   {    Point P0 = Point.Empty;    Point P1 = Point.Empty;    Point P2 = Point.Empty;    Point P3 = Point.Empty;    Point P4 = Point.Empty;     P0.X = mDrawStruct.oldX;    P0.Y = mDrawStruct.oldY;          P2.X = (X +  mDrawStruct.oldX) /2;    P2.Y = (Y +  mDrawStruct.oldY) /2;     P1.X = (P2.X +  mDrawStruct.oldX) /2;    P1.Y = (P2.Y +  mDrawStruct.oldY) /2;          P4.X = X;    P4.Y = Y;     P3.X =(P4.X +  P2.X)/2;    P3.Y =(P4.Y +  P2.Y)/2;    //在P1点绘制一个点    SetPixel(mDrawStruct.hdc,P1.X,P1.Y,mDrawStruct.mColor);      //在P2处绘制一条垂直的长度为hg的线段    Point P21 = Point.Empty;    Point P22  =Point.Empty;     //P2和P21的X差 = P1和P2的Y差 , P2和P21的Y差 = P2和P1的X差    P21.X = P2.X - (P1.Y - P2.Y) /2;    P21.Y = P2.Y - (P2.X - P1.X) /2;     //P2和P22的X差    P22.X =  P2.X + (P1.Y - P2.Y) /2;    P22.Y =  P2.Y + (P2.X - P1.X) /2;     Point P41 = Point.Empty;    Point P42 = Point.Empty;     P41.X = P4.X - (P3.Y - P4.Y) /2;    P41.Y = P4.Y - (P4.X - P3.X) /2;     //P2和P22的X差    P42.X =  P4.X + (P3.Y - P4.Y) /2;    P42.Y =  P4.Y + (P4.X - P3.X) /2;        MoveToEx(mDrawStruct.hdc,P21.X,P21.Y,IntPtr.Zero);    LineTo(mDrawStruct.hdc,P22.X,P22.Y);    MoveToEx(mDrawStruct.hdc,P2.X,P2.Y,IntPtr.Zero);    LineTo(mDrawStruct.hdc,P4.X,P4.Y);    MoveToEx(mDrawStruct.hdc,P41.X,P41.Y,IntPtr.Zero);    LineTo(mDrawStruct.hdc,P42.X,P42.Y);     mDrawStruct.oldX = P4.X;    mDrawStruct.oldY = P4.Y;   }  }   ///绘制城墙线 /// <summary>  /// 绘制城墙线  /// </summary>  /// <param name="sender"></param>  /// <param name="e"></param>  private void button7_Click(object sender, System.EventArgs e)  {   Graphics g = Graphics.FromHwnd(this.panel1.Handle);   g.Clear(Color.White);   IntPtr hdc = g.GetHdc();      DrawStruct str = new DrawStruct();   int nWidth = (int)this.numericUpDown1.Value;   str.hdc =  hdc;   Color c = this.label3.BackColor;   str.mColor = GetGDIRGB(c);   str.nWidth = nWidth;          LOGBRUSH   lb;   lb.crColor= GetGDIRGB(c);   lb.lbHatch = Hatch.HS_BDIAGONAL;   lb.lbStyle = Style.BS_DIBPATTERN;       IntPtr      hPen, hOldPen;      hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID |    PS_GEOMETRIC/* |     iEnd [i] |     iJoin [i]*/,    1 , ref lb,0,IntPtr.Zero);   hOldPen = SelectObject(hdc,hPen);      //MoveToEx(hdc,10,50,IntPtr.Zero);   str.oldX = this.panel1.Width -30;   str.oldY = 50;   str.nWidth = nWidth;   IntPtr  ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(str));   Marshal.StructureToPtr(str,ptr,true);   MoveToEx(hdc,str.oldX,str.oldY,IntPtr.Zero);   LineDDA(str.oldX,str.oldY,50,50, new LineDDAProcHandle(LineDDAProc_CityWalline),ptr);    SelectObject(hdc,hOldPen);   DeleteObject(hPen);   g.ReleaseHdc(hdc);   Marshal.DestroyStructure(ptr,typeof(DrawStruct));   g.Dispose();   }   /// <summary>  /// 绘制城墙线(方波线)回调函数  /// </summary>  /// <param name="X"></param>  /// <param name="Y"></param>  /// <param name="mDrawStruct"></param>  private void    LineDDAProc_CityWalline(      int   X, //   被求值点的X坐标      int   Y, //   被求值点的Y坐标      ref DrawStruct   mDrawStruct )//   应用程序定义数据的指针                 {         {    double hg = mDrawStruct.nWidth;//方波高度    //计算2点间距离,粗略计算    double distance = 0.0;    double angle = Math.Atan((double)(Y - mDrawStruct.oldY) / (double)(X - mDrawStruct.oldX));//线夹角    distance = (double)(X - mDrawStruct.oldX)*(X - mDrawStruct.oldX) + (double)(Y - mDrawStruct.oldY)*(Y - mDrawStruct.oldY);    distance = Math.Abs( Math.Sqrt(distance));    #region 第二种算法    if(distance >=hg* 2 )//距离大于2象素    {     Point P1 = Point.Empty;     Point P2 = Point.Empty;     Point P3 = Point.Empty;     Point P4 = Point.Empty;     Point P5 = Point.Empty;     //p1     P1.X = mDrawStruct.oldX;     P1.Y = mDrawStruct.oldY;     //p5     P5.X = X;     P5.Y = Y;     //p2 P2是起始2个端点的重心     P2.X =(X + mDrawStruct.oldX) /2;     P2.Y =(Y + mDrawStruct.oldY) /2;      //p3 P3和P2的X差 == P2和P5的Y差,P3和P2的Y差 = P2和P5的X差     P3.X = P2.Y - P5.Y + P2.X;     P3.Y = P5.X - P2.X + P2.Y;     //P4 P4和P3的X差 = P5和P2的X差 P4和P3的Y差 = P2和P5的Y差     P4.X = P5.X - P2.X + P3.X;     P4.Y = P5.Y - P2.Y + P3.Y;      //绘制方波线     // MoveToEx(mDrawStruct.hdc,P1.X,P1.Y,IntPtr.Zero);     LineTo(mDrawStruct.hdc,P2.X,P2.Y);     LineTo(mDrawStruct.hdc,P3.X,P3.Y);     LineTo(mDrawStruct.hdc,P4.X,P4.Y);     LineTo(mDrawStruct.hdc,P5.X,P5.Y);      mDrawStruct.oldX = P5.X;     mDrawStruct.oldY = P5.Y;    }    #endregion         //   }     } ////绘波浪线 /// <summary>  /// 绘波浪线  /// </summary>  /// <param name="sender"></param>  /// <param name="e"></param>  private void button6_Click(object sender, System.EventArgs e)  {   Graphics g = Graphics.FromHwnd(this.panel1.Handle);   g.Clear(Color.White);   IntPtr hdc = g.GetHdc();      DrawStruct str = new DrawStruct();   str.hdc =  hdc;   int nWidth = (int)this.numericUpDown1.Value;   str.nWidth = nWidth;   Color c = this.label3.BackColor;   str.mColor = GetGDIRGB(c);    IntPtr  ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(str));   Marshal.StructureToPtr(str,ptr,true);   ////   LOGBRUSH   lb;//   lb.crColor= GetGDIRGB(c);//   lb.lbHatch = Hatch.HS_BDIAGONAL;//   lb.lbStyle = Style.BS_DIBPATTERN;////   //   IntPtr      hPen, hOldPen;   //   hPen = ExtCreatePen(PS_ENDCAP_FLAT| (int)PenStyles.PS_SOLID |//    PS_GEOMETRIC/* |//     iEnd [i] |//     iJoin [i]*/,//    nWidth , ref lb,0,IntPtr.Zero);//   hOldPen = SelectObject(hdc,hPen);    MoveToEx(hdc,10,50,IntPtr.Zero);   LineDDA(10,50,this.panel1.Width - 20,100,new LineDDAProcHandle(LineDDAProc),ptr); //   SelectObject(hdc,hOldPen);//   DeleteObject(hPen);   g.ReleaseHdc(hdc);   Marshal.DestroyStructure(ptr,typeof(DrawStruct));   g.Dispose();   }

阅读(8878) | 评论(2)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册