C# 截取两个点之间的线段,等距分割线

  //取线段上两点之间的沿线线段
  //line 线
  //startDist:距离线第一个点的起点位置
  //stopDist:距离线第一个点的终点位置
  public static List<double[]> lineSliceAlong(List<double[]> line, double startDist, double stopDist)
  {

      double travelled = 0;
      double overshot = 0;
      int origCoordsLength = line.Count;
      List<double[]> slice = new List<double[]>();
      //计算
      for (int i = 0; i < line.Count; i++)
      {
          //如果起始距离大于,起始点位于的线段,且是最后一段儿则停止。
          if (startDist >= travelled && i == line.Count - 1) break;
          //如果 起始点位于的line分段段小于线段长度,且不是line的第一个点
          else if (travelled > startDist && slice.Count == 0)
          {
              overshot = startDist - travelled;
              if (overshot == 0)
              {
                  slice.Add(line[i]);
                  return slice;
              }

              //将点沿着向量方向移动距离
              Vector3 point1 = new Vector3((float)line[i][0], (float)line[i][1], (float)line[i][2]);
              Vector3 point2 = new Vector3((float)line[i - 1][0], (float)line[i - 1][1], (float)line[i - 1][2]);
              Vector3 direction = Vector3.Normalize(point1 - point2);
              Vector3 moveP = point1 + direction * (float)overshot;
              slice.Add(new double[] { moveP.X, moveP.Y, moveP.Z });

              slice.Add(new double[] { moveP.X, moveP.Y, moveP.Z });

          }

          if (travelled >= stopDist)
          {
              overshot = stopDist - travelled;
              if (overshot == 0)
              {
                  slice.Add(line[i]);
                  return slice;
              }
              Vector3 point1 = new Vector3((float)line[i][0], (float)line[i][1], (float)line[i][2]);
              Vector3 point2 = new Vector3((float)line[i - 1][0], (float)line[i - 1][1], (float)line[i - 1][2]);
              Vector3 direction = Vector3.Normalize(point1 - point2);
              Vector3 moveP = point1 + direction * (float)overshot;
              slice.Add(new double[] { moveP.X, moveP.Y, moveP.Z });
              return slice;
          }
          //线段起点
          if (travelled >= startDist)
          {
              slice.Add(line[i]);
          }

          if (i == line.Count - 1)
          {
              return slice;
          }
          List<double[]> tempLine = new List<double[]> { line[i], line[i + 1] };

          travelled += LineLength(tempLine);
      }
      if (travelled < startDist && line.Count == origCoordsLength)
      {
          throw new Exception("Start position is beyond line");
      }
      double[] last = line[line.Count - 1];
      var temp = new List<double[]> { last, last };
      return temp;
  }
  //等距分割线
  public static List<double[]> lineChunck(List<double[]> line, double segmentLength, bool onlySegementPoint = false)
  {

      List<double[]> result = new List<double[]>();
      double lineLength = LineLength(line);

      if (segmentLength <= 0)
      {
          throw new Exception("segmentLength must be greater than 0");
      }
      //如果线比分段短,则返回原始数据
      if (lineLength <= segmentLength) return line;
      double numberOfSegments = lineLength / segmentLength;
      //如果分段不是整数则加1
      if ((int)numberOfSegments != numberOfSegments)
      {
          numberOfSegments = Math.Floor(numberOfSegments) + 1;
      }

      for (int i = 0; i < numberOfSegments; i++)
      {
          var outLine = lineSliceAlong(line, segmentLength * i, segmentLength * (i + 1));
          if (onlySegementPoint)
          {
              result.Add(outLine.First());
              result.Add(outLine.Last());
          }
          else
          {
              for (int j = 0; j < outLine.Count; j++)
              {
                  var v = outLine[j];
                  result.Add(v);
              }
          }

      }

      return distinctPoints(result);
  }
 //点去重
 public static List<double[]> distinctPoints(List<double[]> triplets)
 {
     return triplets
         .Distinct(new TripletComparer())
         .ToList();
 }

 private class TripletComparer : IEqualityComparer<double[]>
 {
     public bool Equals(double[] x, double[] y)
     {
         if (x.Length != y.Length) return false;
         for (int i = 0; i < x.Length; i++)
         {
             if (x[i] != y[i]) return false;
         }
         return true;
     }

     public int GetHashCode(double[] obj)
     {
         unchecked // Overflow is fine, just wrap
         {
             int hash = 17;
             foreach (var val in obj)
             {
                 hash = hash * 23 + val.GetHashCode();
             }
             return hash;
         }
     }
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值