【问题标题】:F# clarification on creating labels for a pie chart关于为饼图创建标签的 F# 说明
【发布时间】:2014-12-05 13:58:49
【问题描述】:

我目前正在阅读 Tomas Petricek 和 Jon Skeet 的 Real-World Functional Programming: With Examples in F# and C#。我对一个特定示例感到有些困惑,在该示例中,我们生成了一个显示带有一些人口统计数据和标签的饼图的应用程序。

现在是绘制标签的部分,或者更确切地说是设置标签的坐标,我对此感到困惑。我希望作者不介意我在这里附上摘录,但是如果不显示代码就很难得到澄清。

let centerX, centerY = 300.0, 200.0
let labelDistance = 150.0

let drawLabel (gr: Graphics) title startAngle angle = 
    let lblAngle = float(startAngle + angle / 2)
    let ra = Math.PI * 2.0 * lblAngle / 360.0
    let x = centerX + labelDistance * cos(ra)
    let y = centerY + labelDistance * sin(ra)
    let size = gr.MeasureString(title, fnt)
    let rc = new PointF(float32(x) - size.Width / 2.0f,
                        float32(y) - size.Height / 2.0f)
    gr.DrawString(title, fnt, Brushes.Black, new RectangleF(rc, size))

似乎labelDistancecenterX, centerY 定义了距绘图表面中心的一些标准“偏移量”,我猜三角函数定义了标签的角度,因为如果我省略了这些,那么所有标签都是在右下角放置在彼此之上。但我不太明白 这是如何工作的。这里到底发生了什么?

【问题讨论】:

    标签: winforms f# trigonometry pie-chart


    【解决方案1】:

    通过添加 cmets 来尝试一下,不一定按此顺序进行:

    // startAngle is the angle in degrees of this segment, angle is the angle of
    // the segment itself.
    let drawLabel (gr: Graphics) title startAngle angle = 
        // So this is the angle of the centre of this segment.
        let lblAngle = float(startAngle + angle / 2)
        // And ra is the same angle, now in radians.
        let ra = Math.PI * 2.0 * lblAngle / 360.0
        // So these work out the position of the label in the usual
        // way, using cosine(angle-in-radians) and then scaling for the X
        // and using sine for the Y. Both relative to the centre of the
        // circle.
        let x = centerX + labelDistance * cos(ra)
        let y = centerY + labelDistance * sin(ra)
        // How long, in pixels, is the text?
        let size = gr.MeasureString(title, fnt)
        // Create an instance of the right data structure adjusting
        // so the calculated point is the centre of the rectangle
        // in which the text will be drawn.
        let rc = new PointF(float32(x) - size.Width / 2.0f,
                            float32(y) - size.Height / 2.0f)
        // And, thus, we can now draw the text.
        gr.DrawString(title, fnt, Brushes.Black, new RectangleF(rc, size))
    

    【讨论】:

      猜你喜欢
      • 2020-01-07
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 2018-01-21
      相关资源
      最近更新 更多