求助:怎样画出多边形各个顶点角的角平分线? 求助!怎样在屏幕坐标系中,画出给定多边形各个顶点角的角平分线? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 假设你的多边形都是凸多边形 private void DrawMidLine(Point startPoint, Point endPoint1,Point endPoint2) { double angle1 = GetLineAngle(startPoint, endPoint1); double angle2 = GetLineAngle(startPoint, endPoint2); if (angle1 == angle2) return; double linesAngle = Math.Abs(angle2 - angle1); double newAngle = 0; if (linesAngle <= Math.PI) newAngle = angle1 < angle2 ? angle1 + linesAngle / 2 : angle2 + linesAngle / 2; else { linesAngle = Math.PI * 2 - linesAngle; newAngle = angle1 > angle2 ? angle1 + linesAngle / 2 : angle2 + linesAngle / 2; } DrawAtAngle(newAngle); } private double GetLineAngle(Point start, Point end) { double diffX = end.X - start.X; double diffY = end.Y - start.Y; double tan=0,angle=0; if (diffY!=0) { tan = Math.Abs(diffX / diffY); angle = Math.Atan(tan); } else tan = Math.PI / 2; if (diffX >= 0) { if (diffY > 0) angle = Math.PI - angle; } else { if (diffY > 0) angle = Math.PI + angle; else angle = Math.PI * 2 - angle; } return angle; } private void DrawAtAngle(double angle) { while (angle > Math.PI * 2) angle = angle - Math.PI * 2; double calAngle = angle; if ((angle > Math.PI / 2) && (angle <= Math.PI)) { calAngle = Math.PI - angle; } else if ((angle > Math.PI) && (angle <= Math.PI * 1.5)) { calAngle = angle - Math.PI; } else if ((angle > Math.PI * 1.5) && (angle <= Math.PI * 2)) { calAngle = Math.PI * 2 - angle; } int y = 50; int x = (int)(Math.Tan(calAngle) * y); Point newPoint = new Point(-1, -1); ; if (angle <= Math.PI / 2) { newPoint.X = startPoint.X + x; newPoint.Y = startPoint.Y - y; } else if ((angle > Math.PI / 2) && (angle <= Math.PI)) { newPoint.X = startPoint.X + x; newPoint.Y = startPoint.Y + y; } else if ((angle > Math.PI) && (angle <= Math.PI * 1.5)) { newPoint.X = startPoint.X - x; newPoint.Y = startPoint.Y + y; } else if ((angle > Math.PI * 1.5) && (angle <= Math.PI * 2)) { newPoint.X = startPoint.X - x; newPoint.Y = startPoint.Y - y; } Graphics g = this.CreateGraphics(); Pen blackPen = new Pen(Color.Black, 1); g.DrawLine(blackPen, startPoint, newPoint); }思路,分别计算出两条线和坐标系Y轴正方向的夹角,相减得到两条线之间的夹角,算出平分线和Y轴正方向的夹角,找到这条线上的一个点,就可以从顶点处到这个点间划线。 感谢noahfang的解答,多边形为凸多边形,各个定点存储在数组中,您的函数DrawMidLine(Point startPoint, Point endPoint1,Point endPoint2)怎么调用,我试了一下怎么没有什么变化,是不是我调用函数不对? 还有您为什么要从Y轴的夹角着手,这样有什么优点么。拜托不吝赐教!急等 以Y轴正方向为基准没有什么特别的理由,用X轴也一样。主函数就是DrawMidLine,我不知道你每个点是用什么格式存储的,我用的是Point类。另外我也不清楚你是要在什么地方画图,我直接画在窗体上的,如果你要画到其他控件,修改一下DrawAtAngle方法,调用那个控件的CreateGraphics方法获得Graphics类。 谢谢回复!我也是用POINT类来存储数据的,直接在窗体上绘图。不好意思数学功底差,我还没有看懂您分类的依据,您能帮我解释一下您的代码吗? GetLineAngle(Point start, Point end)方法是计算start和end决定的直线和Y轴正方向之间的夹角,以start为原点,end和start X坐标的差就是end到Y轴的垂直距离,用diffX表示,end和start Y坐标的差就是end到X轴的垂直距离,用diffY表示,diffX/diffY就是此线和Y轴夹角的tan值,用反tan函数得到角度a。但是我这里用的是diffX/diffY绝对值计算的,因此得到的是和Y轴之间的锐角。画个图应该直观些,可惜加不了附件。总之,end在第1象限,这个角就是我们要求的角,在第2象限,这个角是此线和Y轴负方向的夹角,因此要用PI(180度)-a才是我们要的角。同样,在第3象限,是PI+a,在第4象限是2PI-a。这样算出两条线的角度a1,a2,假设a1<a2,a2-a1就是他们的夹角b,但是这里要注意,因为处理的是凸多边形,夹角必须小于PI,而有时候这样算出来会大于PI,比如一条线在第1象限而另一条在第3象限,这种情况实际我们需要的是b的对顶角,即2PI-b。如果a2-a1<PI,平分线的角度就是a1+b/2,如果a2-a1>PI,平分线的角度就是a2+b/2.DrawAtAngle(double angle)方法画出和Y轴正方向夹角是angle的线,其实就是找出这条线上的一个点,假设这个点和start点的Y坐标差是50,用根据已知角度的TAN值可以算出X坐标差,从而得到这个点的坐标,就能画出平分线了。我有一个疏忽,DrawAtAngle方法中我用到了一个startPoint,这个我是定义在窗体级的,这个实际就是角的顶点,把DrawAtAngle方法定义改为DrawAtAngle(point startPoint,double angle),在DrawMidLine方法中把调用的这句改为DrawAtAngle(startPoint,newAngle)看看是否能工作。 感谢noahfang的悉心解释。基本原理已经明白了,参考解释,我觉得calangle已经为锐角了,所以x与y应该是大于零的数字,按照calangle定义及象限分法以下代码中计算newpoint的坐标时应该改为if (angle <= Math.PI / 2) { newPoint.X = startPoint.X + x; newPoint.Y = startPoint.Y + y; } else if ((angle > Math.PI / 2) && (angle <= Math.PI)) { newPoint.X = startPoint.X + x; newPoint.Y = startPoint.Y - y; } else if ((angle > Math.PI) && (angle <= Math.PI * 1.5)) { newPoint.X = startPoint.X - x; newPoint.Y = startPoint.Y - y; } else if ((angle > Math.PI * 1.5) && (angle <= Math.PI * 2)) { newPoint.X = startPoint.X - x; newPoint.Y = startPoint.Y + y; } 不知道合适否?请高手帮我看看,解释原因! 坐标系是否是这么定义的吗?^X||||___________________>Y(0,0)to:烟头上的探戈具体怎么实现。估计这样比现在讨论的这个方法还要计算麻烦吧? 最后算出的坐标是窗体坐标系里的,以窗体左上角为原点,越往下Y坐标越大。而我们计算出的角度是以顶点为原点的,不要搞混了。因此,如果newpoint在以顶点为原点的坐标系中位于第1象限,也就是在顶点上方,那么在窗体坐标系里的Y坐标要小于顶点。其他象限类推。 TO:noahfang我刚刚接触这一块还不是很懂,想请教您:如何给一个多边形中画半径R以d递增的圆,使得圆与多边形至少两个边相切,且始终保证圆范围落在多边形内。如何的得到圆的圆心坐标和半径?还请大虾多多指导,最好给个示例!万分感谢!!! Access数据库 :要查找处于两个字符串之间的值,怎么写? 代理服务器,怎么通信。 二进制转化成String类型 OraHelper.ExecuteNonQuery()执行的Update问题 第一次涉足线程.遇到问题不懂就问. C#中怎么才能禁用掉Ctrl+Alt+Delete键打开的窗体的"任务管理器"按钮 tabcontrol在选中的时候会有虚线框,请问如何把它给去掉啊? sqlserver2005数据库怎么转到sql2000能用呢 判断XML是否有某个节点 水晶报表分发的问题 何为保护级别限制 请问,c# 中有没有类似于InternetOpen之类的函数,我要通过http验证。
private void DrawMidLine(Point startPoint, Point endPoint1,Point endPoint2)
{
double angle1 = GetLineAngle(startPoint, endPoint1);
double angle2 = GetLineAngle(startPoint, endPoint2); if (angle1 == angle2) return; double linesAngle = Math.Abs(angle2 - angle1); double newAngle = 0;
if (linesAngle <= Math.PI)
newAngle = angle1 < angle2 ? angle1 + linesAngle / 2 : angle2 + linesAngle / 2;
else
{
linesAngle = Math.PI * 2 - linesAngle;
newAngle = angle1 > angle2 ? angle1 + linesAngle / 2 : angle2 + linesAngle / 2;
} DrawAtAngle(newAngle);
} private double GetLineAngle(Point start, Point end)
{
double diffX = end.X - start.X;
double diffY = end.Y - start.Y; double tan=0,angle=0;
if (diffY!=0)
{
tan = Math.Abs(diffX / diffY);
angle = Math.Atan(tan);
}
else
tan = Math.PI / 2;
if (diffX >= 0)
{
if (diffY > 0)
angle = Math.PI - angle;
}
else
{
if (diffY > 0)
angle = Math.PI + angle;
else
angle = Math.PI * 2 - angle;
}
return angle;
} private void DrawAtAngle(double angle)
{
while (angle > Math.PI * 2)
angle = angle - Math.PI * 2;
double calAngle = angle; if ((angle > Math.PI / 2) && (angle <= Math.PI))
{
calAngle = Math.PI - angle;
}
else if ((angle > Math.PI) && (angle <= Math.PI * 1.5))
{
calAngle = angle - Math.PI;
}
else if ((angle > Math.PI * 1.5) && (angle <= Math.PI * 2))
{
calAngle = Math.PI * 2 - angle;
} int y = 50;
int x = (int)(Math.Tan(calAngle) * y);
Point newPoint = new Point(-1, -1); ; if (angle <= Math.PI / 2)
{
newPoint.X = startPoint.X + x;
newPoint.Y = startPoint.Y - y;
}
else if ((angle > Math.PI / 2) && (angle <= Math.PI))
{
newPoint.X = startPoint.X + x;
newPoint.Y = startPoint.Y + y;
}
else if ((angle > Math.PI) && (angle <= Math.PI * 1.5))
{
newPoint.X = startPoint.X - x;
newPoint.Y = startPoint.Y + y;
}
else if ((angle > Math.PI * 1.5) && (angle <= Math.PI * 2))
{
newPoint.X = startPoint.X - x;
newPoint.Y = startPoint.Y - y;
} Graphics g = this.CreateGraphics();
Pen blackPen = new Pen(Color.Black, 1); g.DrawLine(blackPen, startPoint, newPoint);
}思路,分别计算出两条线和坐标系Y轴正方向的夹角,相减得到两条线之间的夹角,算出平分线和Y轴正方向的夹角,找到这条线上的一个点,就可以从顶点处到这个点间划线。
还有您为什么要从Y轴的夹角着手,这样有什么优点么。拜托不吝赐教!急等
主函数就是DrawMidLine,我不知道你每个点是用什么格式存储的,我用的是Point类。另外我也不清楚你是要在什么地方画图,我直接画在窗体上的,如果你要画到其他控件,修改一下DrawAtAngle方法,调用那个控件的CreateGraphics方法获得Graphics类。
我也是用POINT类来存储数据的,直接在窗体上绘图。
不好意思数学功底差,我还没有看懂您分类的依据,您能帮我解释一下您的代码吗?
if (angle <= Math.PI / 2)
{
newPoint.X = startPoint.X + x;
newPoint.Y = startPoint.Y + y;
}
else if ((angle > Math.PI / 2) && (angle <= Math.PI))
{
newPoint.X = startPoint.X + x;
newPoint.Y = startPoint.Y - y;
}
else if ((angle > Math.PI) && (angle <= Math.PI * 1.5))
{
newPoint.X = startPoint.X - x;
newPoint.Y = startPoint.Y - y;
}
else if ((angle > Math.PI * 1.5) && (angle <= Math.PI * 2))
{
newPoint.X = startPoint.X - x;
newPoint.Y = startPoint.Y + y;
}
不知道合适否?请高手帮我看看,解释原因!
^X
|
|
|
|___________________>Y
(0,0)
to:烟头上的探戈
具体怎么实现。估计这样比现在讨论的这个方法还要计算麻烦吧?
我刚刚接触这一块还不是很懂,想请教您:如何给一个多边形中画半径R以d递增的圆,使得圆与多边形至少两个边相切,且始终保证圆范围落在多边形内。
如何的得到圆的圆心坐标和半径?还请大虾多多指导,最好给个示例!万分感谢!!!