几何算法源码

几何算法源码。~~~c# /// <summary>

几何计算

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/// <summary>
/// 获取直线方程 ax + by + c = 0
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
public static double[] GetLineEquation(SGPoint p1, SGPoint p2)
{
    double a = p2.y() - p1.y();
    double b = p1.x() - p2.x();
    double c = p2.x() * p1.y() - p1.x() * p2.y();
    return new double[] { a, b, c };
}

// 获取点到线的距离
public static double GetDistanceToLine(SGPoint p, SGPoint ps, SGPoint pe)
{
    if (IsSamePoint(ps, pe))
    {
        return p.distanceTo(ps);
    }
    else
    {
        var par = GetLineEquation(ps, pe);
        double distance = (par[0] * p.x() + par[1] * p.y() + par[2]) / Math.Sqrt(par[0] * par[0] + par[1] * par[1]);
        return distance;
    }
}

// 获取点到线段的距离
public static double GetDistanceToLineSegment(SGPoint p, SGPoint ps, SGPoint pe)
{
    double pqx = pe.x() - ps.x();
    double pqy = pe.y() - ps.y();
    double dx = p.x() - ps.x();
    double dy = p.y() - ps.y();
    double d = pqx * pqx + pqy * pqy;
    double t = pqx * dx + pqy * dy;
    if (d > 0)
        t /= d;
    if (t < 0)
        t = 0;
    else if (t > 1)
        t = 1;

    dx = ps.x() + t * pqx - p.x();
    dy = ps.y() + t * pqy - p.y();
    return Math.Sqrt(dx * dx + dy * dy);
}

public static double GetDistance(SGPoint p1,SGPoint p2)
{
    return Math.Sqrt(Math.Pow((p1.x()-p2.x()),2) + Math.Pow((p1.y() - p2.y()), 2) );
}

获取凸包

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
     * 生成凸包点集合,并创建多边形
     *
     * @param coordinates 坐标
     * @return {@link Polygon}
     */
public static Polygon getMinConvexPolygon(Coordinate[] coordinates) {
  Coordinate[] coordinates1 = getMinConvexPolygonCoords(coordinates);
  GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
  LinearRing linearRing = geometryFactory.createLinearRing(coordinates1);
  return buildPolygon(linearRing, null);
}

/**
     * 获取凸包点集合
     *
     * @param coords 坐标
     * @return {@link Set}<{@link Coordinate}>
     */
public static Coordinate[] getMinConvexPolygonCoords(Coordinate[] coords) {
  //如果点集点数小于3,无需判断
  if (coords.length < 3) {
    return coords;
  }
  List<Coordinate> s = Arrays.asList(coords);
  Collections.sort(s);
  LinkedList<Coordinate> u = new LinkedList<Coordinate>(),
  l = new LinkedList<Coordinate>();
  u.push(s.get(0));
  u.push(s.get(1));
  l.push(s.get(s.size() - 1));
  l.push(s.get(s.size() - 2));
  int n = 0;
  for (int i = 2; i < s.size(); i++)                            //生成凸包上半部分
  {
    for (n = u.size(); n >= 2 && cross(u.get(1), u.get(0), s.get(i)) >= 0; n--) {
      u.pop();
    }
    u.push(s.get(i));
  }
  for (int i = s.size() - 3; i >= 0; i--)                    //生成凸包下半部分
  {
    for (n = l.size(); n >= 2 && cross(l.get(1), l.get(0), s.get(i)) >= 0; n--) {
      l.pop();
    }
    l.push(s.get(i));
  }
  for (int i = 1; i < u.size() - 1; i++)                    //合成最终结果
  {
    l.push(u.get(i));
  }
  return l.toArray(new Coordinate[0]);
}

private static double cross(Coordinate a, Coordinate b, Coordinate c) {
  double x1 = b.getX() - a.getX();
  double y1 = b.getY() - a.getY();
  double x2 = c.getX() - a.getX();
  double y2 = c.getY() - a.getY();
  return x1 * y2 - x2 * y1;
}
Licensed under CC BY-NC-SA 4.0
Gear(夕照)的博客。记录开发、生活,以及一些不足为道的思考……