DashLine的绘图算法

tutuaction 2003-07-17 01:48:27
对于DashLine,就是类似于虚线的样式,从起点到终点按照Dash的长度相间绘制。
比如:Dash的长度为10,实线为黑色,则从起点开始画长度为10的黑色实线,然后
相隔长度为10的长度相同方向重新绘制长度为10的黑色实线
题目如下:
1、一条多个直线段组成的相连的折线,起点和终点可以重合
2、每一条线段可以以任意的角度延伸,0度或者90度或者180度
3、Dash的长度为16
4、从起点到终点沿着折线方线Dash的长度必须为16,包含拐角处,比如上一段线段最后实线长度为3,那么下一条线段的开始要绘制13的实线
5、用C#语法5个小时内完成编码、调试

这是国内一家著名的GIS软件开发公司招聘产品部研发工程师的笔试题
...全文
152 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
jjkcom 2003-07-21
  • 打赏
  • 举报
回复
对于角度的判断的确有问题
我也知道
jjkcom 2003-07-18
  • 打赏
  • 举报
回复
我的代码出来了,采用7个点测试,并且为了显示效果,画出了对照线:
private ArrayList ptAryList=new System.Collections.ArrayList();//存储构造后的点数组
private double SingleLine(Point point1,Point point2,double its)
{
double TotleLineLen;//线段长度
double deltaX;//X轴上的投影
double deltaY;//Y轴上的投影
int StrokeLen;//dashline的长度
nt FregNum;//线段含有StrokeLen*2的整数倍
double itsSingle;//上一次的余差
double angle;
Point Tmppt1=new Point();

StrokeLen=20;
deltaX=(double)(point2.X - point1.X );
deltaY=(double)(point2.Y - point1.Y );
if (deltaX==0 && deltaY>0)
{
angle=Math.PI/2;
}
else if(deltaX==0 && deltaY<0)
{
angle=3*Math.PI/2;
}
else if(deltaY==0 && deltaX>0)
{
angle=0*Math.PI/2;
}
else if(deltaY==0 && deltaX<0)
{
angle=2*Math.PI/2;
}
else

{
angle=Math.Atan(deltaY/deltaX);//线段的角度
}

Point[] AryPoint;

Tmppt1.X=(int)(point1.X-Math.Cos(angle)*its);
Tmppt1.Y=(int)(point1.Y-Math.Sin(angle)*its);
TotleLineLen= Math.Sqrt(deltaX*deltaX + deltaY*deltaY)+its;//线段的长度
FregNum=(int) TotleLineLen / StrokeLen;
itsSingle=TotleLineLen-FregNum*StrokeLen;
if(FregNum==0)
{
AryPoint=new Point[2];
AryPoint[0]=point1;
AryPoint[1]=point2;
}
else
{
AryPoint=new Point[FregNum+2];
AryPoint[0]=point1;
for(int i=1;i<AryPoint.Length-1;i++)
{
AryPoint[i].X=(int)(Tmppt1.X+Math.Cos(angle)*StrokeLen*i);
AryPoint[i].Y=(int)(Tmppt1.Y+Math.Sin(angle)*StrokeLen*i);

}
AryPoint[AryPoint.Length-1].X=point2.X;
AryPoint[AryPoint.Length-1].Y=point2.Y;
}
for(int i=0;i<AryPoint.Length;i++)
{
ptAryList.Add(AryPoint[i]);
}
return itsSingle;

}
private void Pline(Point[] pt)
{
Point pt1=new Point();
Point pt2=new Point();
double its;
double Tmpits;
its=0;
ptAryList.Clear();
for(int i=1;i<pt.Length;i++)
{
pt1=pt[i-1];
pt2=pt[i];
Tmpits=SingleLine(pt1,pt2,its);
its=Tmpits;

}

}
private void button1_Click(object sender, System.EventArgs e)
{
Graphics dc=this.CreateGraphics();
Pen BlackPen=new Pen(Color.Black,8);
Pen WhitePen=new Pen(Color.White,1);
Point[] px=new Point[7];
px[0].X=10;
px[0].Y=10;

px[1].X=40;
px[1].Y=100;

px[2].X=80;
px[2].Y=120;

px[3].X=100;
px[3].Y=180;

px[4].X=200;
px[4].Y=180;

px[5].X=210;
px[5].Y=180;

px[6].X=210;
px[6].Y=80;

Pline(px);
dc.Clear(Color.White);
//开始绘制对照实线线
for(int i=1;i<px.Length;i++)
{
dc.DrawLine(BlackPen,px[i-1],px[i]);
}
//开始绘制dash线

Point tmpPtStart,tmpPtEnd;
for(int i=1;i<ptAryList.Count;i=i+2)
{
tmpPtStart=(Point)ptAryList[i-1];
tmpPtEnd=(Point)ptAryList[i];

dc.DrawLine(WhitePen,tmpPtStart,tmpPtEnd);
}

}
我测试了,成功了,但是可能很多地方可以优化
jjkcom 2003-07-18
  • 打赏
  • 举报
回复
我的看法是:
1、对于数组px按照方向不同,分成单独的线段
2、对于每一条单独线段根据Dashline的要求,重新构造pt的Point树组,并且计算余差
3、对于构造pt,可以根据Dashline的要求,从起点开始,考虑上一条线段的余差,Dash长度
的奇数倍就是要画的实线,并且最后计算出本次的余差。
4、对于pt数组,只要从头开始到尾连起来就行了

说明:属于个人暂时看法,没有优化

我试一下,成功了,就马上把代码贴出来,楼主要给分呦,呵呵
tutuaction 2003-07-18
  • 打赏
  • 举报
回复
你有一个bug,我测试出来了
关于角度angle的计算
我修正了一下:
if (deltaX==0 && deltaY>0)
{
angle=Math.PI/2;
}
else if(deltaX==0 && deltaY<0)
{
angle=3*Math.PI/2;
}
else if(deltaY==0 && deltaX>0)
{
angle=0*Math.PI/2;
}
else if(deltaY==0 && deltaX<0)
{
angle=2*Math.PI/2;
}

else if(deltaX>0 && deltaY>0)
{
angle=Math.Atan(deltaY/deltaX);
}

else if(deltaX<0 && deltaY>0)
{
angle=Math.PI+Math.Atan(deltaY/deltaX);
}

else if(deltaX<0 && deltaY<0)
{
angle=2*Math.PI+Math.Atan(deltaY/deltaX);
}
else

{
angle=Math.Atan(deltaY/deltaX);//线段的角度
}

另外我认为你的arraylist存储了一半的不用数据
可以优化
tutuaction 2003-07-17
  • 打赏
  • 举报
回复
更正一下
Pen BlackPen=new Pen(Color.Black,8);
应该为:
Pen BlackPen=new Pen(Color.Black,1);
我的笔误
tutuaction 2003-07-17
  • 打赏
  • 举报
回复
这个程序的主体结构已经给出了,只需要在空白处补充相应的代码即可
要求尽量逻辑清晰,代码简单
private void button1_Click(object sender, System.EventArgs e)
{
Graphics dc=this.CreateGraphics();
Pen BlackPen=new Pen(Color.Black,8);
Point[] px=new Point[5];
px[0].X=10;
px[0].Y=10;

px[1].X=40;
px[1].Y=100;

px[2].X=80;
px[2].Y=120;

px[3].X=100;
px[3].Y=180;
px[4].X=210;
px[4].Y=80;
.....(这是需要补充的代码)
}
1,bmp_in.zip
在多文档客户区中增加位图底图演示程序(59KB)
2,bmp_in2.zip
在多文档客户区中增加位图底图(27KB)
3,bitmap_ocx.zip
一个自适应大小的位图控件(3KB)
4,bitmap_ocx2.zip
一个自适应大小的位图控件演示程序(21KB)
5,dashline.zip
一个简单的虚线类(46KB)
6,rotatedc2.zip
旋转你的图形-高级内存设备描述表演示程序(49KB)
7,rotatedc.zip
旋转你的图形-高级内存设备描述表(21KB)
8,jtdraw.zip
JTDraw -- 一个绘画的例子(165KB)
9,autofont.zip
自动字体处理类(3KB)
10,colorapp.zip
CColor - 在一个类中包括了RGB和HLS设定可执行程序(10KB)
11,colorapp2.zip
CColor - 在一个类中包括了RGB和HLS设定(20KB)
12,jpeg.zip
操作JPEG的库和源程序(390KB)
13,dibimage.zip
这个例子功能强大,能够以多种方式处理位图文件,强烈推荐 COOL(112KB)
14,ssbase.zip
屏幕保护程序基类(27KB)
15,quiz_scr.zip
十分简单的屏幕保护程序(32KB)
16,gpslib.zip
在你的应用程序中添加对GPS(全球定位系统)的支持,提供的DLL可被其它开发软件所利用(83KB)
17,throw.zip
平抛运动演示程序(40.8k VC 作者:添翼虎)(41KB)
18,dodib.zip
处理位图的例子(112KB)
19,ampuisrc.zip
类似于WinAMP的图形界面(50KB)
20,Gray.zip
一个基于DirectX的图象灰度处理示例,可是MMX的新作了(57KB)
21,Screen.zip
一个基于DirectX的截图示例,又是MMX的新作^o^,你看懂了话都能截图了(14KB)
22,opengl1.zip
OpenGL三维图形程序设计(539kb)
23,wingrap.zip
Windows图形编程(189kb)
24,Graphics.zip
VC图形编程的一个简单工程<1450kb>
25,DIBShow.zip
设备无关位图的一个里例子<1830kb>
26,Clock.zip
一个数字时钟的图形的工程<1450kb>
27,PAINTOBJ.zip
一个类似于画图的小程序<1450kb>
28,detect.zip
用差影法检测图象(25KB)
29,maslog.zip
综合录井图(418KB)
30,mfdraw.zip
多功能绘图(175KB)
31,mftab.zip
自由表格(63KB)
32,cimage.zip
一套图像处理程序,支持JPEG、GIF和PNG三种格式(892KB)
33,thinkr30.zip
简单的电子表格程序(141KB)
34,aseasy5.zip
另一个电子表格程序(319KB)
35,free.zip
一个电子表格程序,它能从脚本中处理数据(17KB)
36,iedit32.zip
在DOS中创建或编辑WINDOWS的图标(69KB)
37,giflt150.zip
保持GIF的可视面但减小它的大小25%(50KB)
38,gds31f.zip
观看,替换和转换 GIF/JPG/PCX/TIF/IFF/LBM/DL/ HAM/BMP/RLE/TGA/MAC/WPG/CUT/ANSI/TXT/IMG/ PBM/CUT/GL/FLI/MPG, 显示极小的图象(370KB)
39,fview10.zip
观看JPEG/GIF/TARGA 文件(72KB)
40,dta22b2.zip
从TGA文件创建FLI/FLC动画(254KB)
41,dfe-104.zip
显示字体编辑器能为EGA和VGA显示器创建新字体(219KB)
42,cmorph21.zip
create morphed images with TGA/IMG/BMP/GIF/IPI/PCX files(630KB)
43,bmp2ico.zip
转换BMP文件到WINDOWS 3.X的ICO文件(22KB)
44,alch151.zip
图形转换器(359KB)
45,aaplay10.zip
Autodesk Animator's FLI player(53KB)
46,a2r103.zip
转换ANSI 屏幕到RIP格式(17KB)
47,show204.zip
GIF/PCX/JPEG 观察器(252KB)
48,bmp.zip
操纵位图的开发包(78KB)
49,draw_in.zip
在状态条里显现图(29KB)
50,cimageb.zip
读写jpg,dib文件的类。(267KB)
51,RGNC.zip
想制做超cool图形界面吗用它吧。(18KB)
52,CISBitmap.zip
这个从Cbitmap派生的位图类使你可以通过指定一种颜色把一幅位图变透明,而它的使用差不多同Cbitamp一样简单。(2KB)
53,Cdib.zip
这个类库可以实现设备无关位图的创建,显示,读入,保存,捕捉位图(6KB)
54,geotrans.zip
行程编码,JPEG压缩编码(基本系统)(32KB)
55,smooth.zip
图象的检测,模板匹配算法代码(24KB)
56,dither.zip
图象的边沿检测与提取,轮廓跟踪算法代码(24KB)
57,colorrope.zip
腐蚀,膨胀,细化算法代码(31KB)
58,morph.zip
直方图修正和彩色变换算法代码(17KB)
59,edge.zip
实现图案化和抖动技术以及bmp2txt源代码(34KB)
60,compress.zip
图象的几何变换算法(128KB)
61,tga2gif.zip
TGA文件转换为GIF文件。(14KB)
62,tooltip.zip
可以多行显示的提示条(32KB)
63,yearmonth.zip
选择年/月的控制(39KB)
64,calen32a.zip
提供日历功能的动态库, 含有演示代码(79KB)
65,mappin.zip
你可以在你的GIS(地图信息系统)中使用这些源程序,因为它演示了在地图上的图钉效果,运行这个程序你可以在View中移动一些图标(286KB)
66,storage.zip
文件存储和流化的一些类(10KB)
67,Redraw.zip
克服控制闪烁问题(1KB)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧