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软件开发公司招聘产品部研发工程师的笔试题
...全文
232 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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;
.....(这是需要补充的代码)
}

111,110

社区成员

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

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

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