【问题标题】:Drawing the slices of a 3D pie chart in the right order以正确的顺序绘制 3D 饼图的切片
【发布时间】:2009-07-05 05:27:35
【问题描述】:

我正在尝试修复一个旧应用程序:我有一个函数,它采用一对角度并绘制一个分解饼图的 3d 切片。我还有一些函数可以获取一组数字、生成角度并重复调用切片绘制函数,直到绘制出整个饼图。

对切片绘制函数的重复调用会在现有切片的顶部进行绘制,并且顺序永远不会完全正确。我的问题是如何保证最靠近查看器的部分将最后绘制,以便这些部分正确重叠?

function drawSlice(startAngle, endAngle)
  // draws a slice as shown in picture


function drawPie(list of angles to make up pie)
  for each angle in angles
    drawSlice(angle)

// example usage
drawPie([30,15,40,10,5])

切片看起来像: alt text http://img233.imageshack.us/img233/2627/slice.png

【问题讨论】:

  • 代码?如果我们不知道它应该如何工作,我们怎么知道它不起作用
  • 无法发布实际代码,因为不确定工作中的合法性 - 将尝试更好地解释它并提供等效的伪代码

标签: graphics geometry graph


【解决方案1】:

也许您必须将绘制切片分成两个相等的阶段。两者都从离观察者最远的角度开始,并以相反的方式前进。

将切片分为两个阶段后,您可以将整个切片以及位于 50% 边界上的切片的两个部分按圆周上的中点排序,朝向观察者。

如果有例如两个切片,首先是 80%,从离观察者最远的角度开始,你可以把它分成两个切片,在第一阶段绘制 50%,然后你会绘制从顶部开始的 20% 切片,然后朝另一个方向走,然后你才会画出第一片剩下的 30%。

对不起,解释的复杂,但我希望你能明白。 ;)

编辑: 为了说明小切片既重叠又重叠较大切片的情况。 但是请注意,这不是一个分解的馅饼,而且这个馅饼更容易绘制。

【讨论】:

  • 是的,我有点明白 - 很高兴你至少理解了我糟糕的初步解释!请参阅我的回答,因为我认为您已经给了我正确的想法开始......
【解决方案2】:

假设直接指向我们时的角度值为270,简单 计算切片中点到六点钟线的距离:

 Math.abs(270 - (startAngle + endAngle) / 2)

然后根据这个距离对切片进行排序,降序绘制。

【讨论】:

  • +1 谢谢,这基本上是正确的答案。它可以用任何半体面的语言工作,但在这个特定的应用程序中,除了排序高 -> 低之外的任何东西都不是真正可行的,我可能不得不使用我更冗长的解决方案
  • 查看我编辑的答案,了解简单公式不起作用的情况。
【解决方案3】:

编辑:

mbeckish 是正确的 - 这应该可以解决它。用'cartoon-race method' 建立两个列表 - 即不断添加到一个列表,直到它的总角度内容超过另一个列表,然后更改列表并继续。完成后,首先绘制“较小”的。由于这将包含最多 180 度,因此它永远无法越过危险点。如果他们是平等的,那没关系。 (不好看)

define clockwiseAngles[], antiClockwiseAngles[]
define totalClockwiseAngles, totalAntiClockwiseAngles

for each angle in angles
  if totalClockwiseAngles > totalAntiClockwiseAngles
    totalAntiClockwiseAngles += angle
    AntiClockwiseAngles.push(angle)
  else
    totalClockwiseAngles += angle
    clockwiseAngles.push(angle)

if totalClockwiseAngles > totalAntiClockwiseAngles
  // draw all anticlockwise angles
  // draw all clockwise angles
else
  // draw all clockwise angles  
  // draw all anticlockwise angles

【讨论】:

  • 您需要确保最后绘制穿过 180 度线的切片(即最靠近屏幕的切片)。在您当前的伪代码中,它可能是顺时针方向的,但切片可能非常大并且绕到逆时针方向。然后,当你逆时针画下一个棋子时,你就会遇到问题。
【解决方案4】:

假设任何调用绘制切片的函数的数据都在某种列表中,请对该列表进行排序,以便较近的项目稍后出现并最后绘制。

不过,一些代码或其他细节将大大有助于为您提供更好的答案。

【讨论】:

    【解决方案5】:

    也许您应该重构以使用现有的任何标准方法从给定的角度绘制圆柱体,然后为圆柱体的表面着色以描绘切片。

    【讨论】:

      猜你喜欢
      • 2016-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 2021-10-13
      • 1970-01-01
      相关资源
      最近更新 更多