/**
* Copyright (c) 2009-2011, chunquedong(YangJiandong)
*
* This file is part of ChunMap project
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
*
* History:
* 2010-05-05 Jed Young Creation
*/
package chunmap.model.algorithm;
import java.util.Arrays;
import chunmap.model.coord.CPoint;
import chunmap.model.elem.Line;
import chunmap.model.elem.LineSegment;
import chunmap.util.CMAssert;
public class LineSegmentAlgorithm {
/// <summary>
/// return IPoint[]/IPoint/null
/// </summary>
/// <param name="me"></param>
/// <param name="other"></param>
/// <returns></returns>
public static Object intersection(LineSegment me , LineSegment other)
{
if (!me.hasIntersect(other))
{
return null;
}
// 共线
if (me.toVector().get2DCrossProduct(other.toVector()) == 0)
return joinLinePart(me, other);
// 转化为直线
Line line1 = me.toLine();
Line line2 = other.toLine();
// 边缘检测,这样精度高
if (me.onBorder(other.getEndPoint()))
{
return other.getEndPoint();
}
else if (me.onBorder(other.getStartPoint()))
{
return other.getStartPoint();
}
else if (other.onBorder(me.getEndPoint()))
{
return me.getEndPoint();
}
else if (other.onBorder(me.getStartPoint()))
{
return me.getStartPoint();
}
// 计算交点
CPoint px = line1.crossPoint(line2);
// 断言
if (px == null) { CMAssert.unreachableCode(); }
//检查是否合法
if (!me.getEnvelop().contain(px) || !other.getEnvelop().contain(px))
{
CPoint[] ps = { me.getStartPoint(), me.getEndPoint(),
other.getStartPoint(), other.getEndPoint() };
px = getNearPoint(px, ps);
}
return px;
}
private static CPoint getNearPoint(CPoint p, CPoint[] ps)
{
int k = 0;
double d = Double.MAX_VALUE;
for (int i = 0, n = ps.length; i < n; i++)
{
//LineSegment ls = new LineSegment(p, ps[i]);
double dd = p.distance2D(ps[i]);
if (dd < d)
{
d = dd;
k = i;
}
}
return ps[k];
}
//------------------------------------------------------------------------
/**
* 两条线共线时计算公共部分
*
* @param other
* @return
*/
private static Object joinLinePart(LineSegment me , LineSegment other)
{
CPoint[] points = new CPoint[4];
points[0] = me.getStartPoint();
points[1] = me.getEndPoint();
points[2] = other.getStartPoint();
points[3] = other.getEndPoint();
Arrays.sort(points);// 排序
if (points[1].equals(points[2]))
{
return points[1];
}
CPoint[] pointList = new CPoint[2];
pointList[0] = points[1];
pointList[1] = points[2];
return pointList;
}
}