调用的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();
}
评论