毕达哥拉斯只有一侧已知/计算几何

时间:2018-09-26 15:57:04

标签: computational-geometry

问题图片

我正在处理一个编码挑战,在给定一定数量的山p和山s坐标的情况下,我必须计算日光照射山的多少米。

编码挑战说明:https://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=861

我创建了一个具有x坐标和y坐标的Node类,并将它们放在优先级队列中,其中最左侧的坐标排在最前面

double totalLength = 0;
Node peak = priorityQueue.poll();
Node col = null;
while (!priorityQueue.isEmpty()) {
    Node nextCoordinates = priorityQueue.poll();
    if (peak.yCo > nextCoordinates.yCo) {
        col = nextCoordinates;
    } else {
        // DO SOME CALCULATIONS 
        peak = nextCoordinates;
    }
}
System.out.println(totalLength);

我正在寻找首先在上图中说明的计算,然后在寻找编码挑战的可能更好的解决方案。谢谢

1 个答案:

答案 0 :(得分:0)

实际上,我认为您需要按x降序排列,即最右边的点在前。过程从右向左指向,跟踪当前的最高峰,并初始化到最右边。如果某个点低于当前峰值,则可以忽略。否则,我们使用相似的三角形计算在新的高峰的坡度上可见的太阳的数量,即可见坡度(我们想要的)与总坡度之比等于可见高度的比率(新峰高减去当前峰高) )到总高度。

这是一些伪代码:

Sort array of points, P, by x descending

sun = 0
high = 0
for i = 1 to P.length-1
  if P[i].y > P[high].y
    a = P[i].y - P[i-1].y
    b = P[i].x - P[i-1].x
    hdiff = P[i].y - P[high].y
    sun = sun + hdiff*sqrt(a*a+b*b)/a
    high = i
  end
end

翻译成Java:

static double calculateSun(int[] peaks)
{
  Point[] pts = new Point[peaks.length/2];
  for(int j=0, i=0; i<peaks.length; j++) 
    pts[j] = new Point(peaks[i++], peaks[i++]);

  // Sort by X descending
  Arrays.sort(pts, (p1, p2) -> {return p2.x - p1.x;});

  double sun = 0;    
  for(int h=0, i=1; i<pts.length; i++)
  {
    if(pts[i].y > pts[h].y)
    {
      int a = pts[i].y - pts[i-1].y;
      int b = pts[i].x - pts[i-1].x;
      int hdiff = pts[i].y - pts[h].y;
      sun += hdiff*Math.sqrt(a*a + b*b)/a;        
      h = i;
    }
  }
  return sun;
}

测试:

public static void main(String[] args)
{
  int[][] tests = {
      { 1100, 1200, 0, 500, 1400, 100, 600, 600, 2800, 0, 
        400,  1100, 1700, 600, 1500, 800, 2100, 300, 
        1800, 700, 2400, 500, },
      {
        0, 1000, 1000, 0, 
      }};

  for (int[] test : tests)
    System.out.printf("%.2f\n", calculateSun(test));
}

输出:

1446.34
1414.21

与预期输出匹配的