昨天看到某个公司招聘出的一道题目,题目是这样的:判断任意三个点是否构成三角形,以及某个点是否位于指定的三角形内。
关于这个问题,我给出了自己的答案,首先解决第一个问题:
关于第二个问题稍微复杂些,不过幸好我在早期研究过并解决了一个更常见的问题,那就是判断一个点是否位于某个多边形内,而且即使这个多边形是凹多边形。这个功能在EnterpriseServerBase.XMath.Geometry.Polygon类中实现。
对于问题二的解答,我封装了Triangle类,它不仅借助Polygon类解决了问题二,而且可以计算三角形的面积和各个边长。
public class Triangle
{
private ArrayList vertextList = null ;
private ArrayList lengthList = null ;
private float myArea = 0 ;

ctor
Area ,GetEdgeLength

Contains
}
Polygon类的实现比较复杂,代码也比较多,源码就不列出来了,可以点击这里下载。
关于这个问题,我给出了自己的答案,首先解决第一个问题:
/// <summary>
/// IsTriangle 判断集合中的头三个点PointF是否可以构成一个三角形
/// </summary>
public static bool IsTriangle(ArrayList ptList)
{
PointF pt0 = (PointF)ptList[0] ;
PointF pt1 = (PointF)ptList[1] ;
PointF pt2 = (PointF)ptList[2] ;
//如果有两个点相同
if(pt0.Equals(pt1) || pt0.Equals(pt2) || pt1.Equals(pt2) )
{
return false ;
}
float length_01 = (float)Math.Sqrt((pt0.X - pt1.X)*(pt0.X - pt1.X) + (pt0.Y - pt1.Y)*(pt0.Y - pt1.Y)) ;
float length_02 = (float)Math.Sqrt((pt0.X - pt2.X)*(pt0.X - pt2.X) + (pt0.Y - pt2.Y)*(pt0.Y - pt2.Y)) ;
float length_12 = (float)Math.Sqrt((pt2.X - pt1.X)*(pt2.X - pt1.X) + (pt2.Y - pt1.Y)*(pt2.Y - pt1.Y)) ;
bool result0 = (length_01+length_02 <= length_12) ;
bool result1 = (length_01+length_12 <= length_02) ;
bool result2 = (length_02+length_12 <= length_01) ;
if(result0 || result1 || result2)
{
return false ;
}
return true ;
}
该解答分为两步,首先判断是否有重点,接着以两边之和大于第三边作为构成三角形的依据。/// IsTriangle 判断集合中的头三个点PointF是否可以构成一个三角形
/// </summary>
public static bool IsTriangle(ArrayList ptList)
{
PointF pt0 = (PointF)ptList[0] ;
PointF pt1 = (PointF)ptList[1] ;
PointF pt2 = (PointF)ptList[2] ;
//如果有两个点相同
if(pt0.Equals(pt1) || pt0.Equals(pt2) || pt1.Equals(pt2) )
{
return false ;
}
float length_01 = (float)Math.Sqrt((pt0.X - pt1.X)*(pt0.X - pt1.X) + (pt0.Y - pt1.Y)*(pt0.Y - pt1.Y)) ;
float length_02 = (float)Math.Sqrt((pt0.X - pt2.X)*(pt0.X - pt2.X) + (pt0.Y - pt2.Y)*(pt0.Y - pt2.Y)) ;
float length_12 = (float)Math.Sqrt((pt2.X - pt1.X)*(pt2.X - pt1.X) + (pt2.Y - pt1.Y)*(pt2.Y - pt1.Y)) ;
bool result0 = (length_01+length_02 <= length_12) ;
bool result1 = (length_01+length_12 <= length_02) ;
bool result2 = (length_02+length_12 <= length_01) ;
if(result0 || result1 || result2)
{
return false ;
}
return true ;
}
关于第二个问题稍微复杂些,不过幸好我在早期研究过并解决了一个更常见的问题,那就是判断一个点是否位于某个多边形内,而且即使这个多边形是凹多边形。这个功能在EnterpriseServerBase.XMath.Geometry.Polygon类中实现。
对于问题二的解答,我封装了Triangle类,它不仅借助Polygon类解决了问题二,而且可以计算三角形的面积和各个边长。













Polygon类的实现比较复杂,代码也比较多,源码就不列出来了,可以点击这里下载。
Feedback
# re: 某公司的一道机考题的解答 回复
2005-10-16 12:14 by coordinator第一个题在判断完重点后判断是否三点共线就行了吧……
如果应聘的工作只是些应用层的开发....这种题目就真的是白痴了....
如果应聘的工作是关于游戏又或者gdi方面的,这题出的不错
如果应聘的工作是关于游戏又或者gdi方面的,这题出的不错
我见到的一个简单的算法是计算面积来判断,
如果为三角形,则三点构成的面积应该大于0,如果某点在三角形内,则该点与三角形的顶点构成的三角形面积之和相等。
所以这个问题的实质就是计算任意三点构成的三角形面积之和,而这就是一个公式。
由以上可见,对程序的学习主要是对算法的理解和运用,其次是对程序设计理论的掌握。
如果为三角形,则三点构成的面积应该大于0,如果某点在三角形内,则该点与三角形的顶点构成的三角形面积之和相等。
所以这个问题的实质就是计算任意三点构成的三角形面积之和,而这就是一个公式。
由以上可见,对程序的学习主要是对算法的理解和运用,其次是对程序设计理论的掌握。
第一问:
设三个点坐标为(x1,y1),(x2,y2),(x3,y3)
直接判断S=(x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)即可
若S=0则。。
实质是求两个向量的叉乘表示相应的平行四边形面积
设三个点坐标为(x1,y1),(x2,y2),(x3,y3)
直接判断S=(x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)即可
若S=0则。。
实质是求两个向量的叉乘表示相应的平行四边形面积
如果为三角形,则三点构成的面积应该大于0,如果某点在三角形内,则该点与三角形的顶点构成的三角形面积之和相等。
同意
同意
从招聘者的角度去想问题,可能考的并不是算法,而是代码风格,容错处理,面向对象,人机操作的友好性,还有就是是否考虑了所有的情况(问题的全面性)
你们回忆一下初中学的斜率,然后很快可以写出最简捷的第一道题,然后第二道题只须确定 点在对应 任意两个端点的斜线的斜率应该在其两个边之内。
如果有人对Html转换xml分析机有兴趣请加我的MSN : parasite_eve_md@msn.com
如果有人对Html转换xml分析机有兴趣请加我的MSN : parasite_eve_md@msn.com
我的解题思路是这样:
1、
A(x1,y1)
B(x2,y2)
C(x3,y3)
P(x4,y4)
2、
以A、B和C中X最小作为原点做坐标平移(这里假设A点的X最小):
A(0,0)
B(Xb,Yb), Xb=x2-x1,Yb=y2-y1
C(Xc,Yc), Xc=x3-x1,Yc=y3-y1
P(Xp,Yp), Xp=x4-x1,Yp=y4-y1
3、
AB的斜率为K(AB)=Yb/Xb,Yb<>0
AC的斜率为K(AC)=Yc/Xc,Xc<>0
4、
若K(AB) <> K(AC),则ABC可以画三角形
5、
下面3个条件同时成立的时候,点P在三角形ABC内
5.1、Xp>0
第2步坐标平移后保证了三角形在X轴的右边
5.2、Min(K(AB),K(AC))<K(AP)<Max(K(AB),K(AC))
AP的斜率为K(AP)=(Yp/Xp,Xp<>0
5.3、点P在直线BC的左边或者下面
通过BC两点构造直线BC的方程为:
ax+by+c=0,(a>0)
a=Yb-Yc,b=Xc-Xb,c=Yc×Xb-Xc×Yc(如果(Yb-Yc)<0,则a,b,c同时乘以-1:必须保证a>0)
令f(x)=ax+by+c,现在把P(Xp,Yp)代入:
f(x) = a×Xp+b×Yp+c
如果f(x)<0,则P在直线BC左侧或下侧;
f(x)>0,则P在直线BC右侧或上侧;
f(x)=0,则P在直线BC上.
1、
A(x1,y1)
B(x2,y2)
C(x3,y3)
P(x4,y4)
2、
以A、B和C中X最小作为原点做坐标平移(这里假设A点的X最小):
A(0,0)
B(Xb,Yb), Xb=x2-x1,Yb=y2-y1
C(Xc,Yc), Xc=x3-x1,Yc=y3-y1
P(Xp,Yp), Xp=x4-x1,Yp=y4-y1
3、
AB的斜率为K(AB)=Yb/Xb,Yb<>0
AC的斜率为K(AC)=Yc/Xc,Xc<>0
4、
若K(AB) <> K(AC),则ABC可以画三角形
5、
下面3个条件同时成立的时候,点P在三角形ABC内
5.1、Xp>0
第2步坐标平移后保证了三角形在X轴的右边
5.2、Min(K(AB),K(AC))<K(AP)<Max(K(AB),K(AC))
AP的斜率为K(AP)=(Yp/Xp,Xp<>0
5.3、点P在直线BC的左边或者下面
通过BC两点构造直线BC的方程为:
ax+by+c=0,(a>0)
a=Yb-Yc,b=Xc-Xb,c=Yc×Xb-Xc×Yc(如果(Yb-Yc)<0,则a,b,c同时乘以-1:必须保证a>0)
令f(x)=ax+by+c,现在把P(Xp,Yp)代入:
f(x) = a×Xp+b×Yp+c
如果f(x)<0,则P在直线BC左侧或下侧;
f(x)>0,则P在直线BC右侧或上侧;
f(x)=0,则P在直线BC上.