登录
首页 >  Golang >  Go问答

使用浮点数绘制图表

来源:stackoverflow

时间:2024-02-23 21:48:25 245浏览 收藏

一分耕耘,一分收获!既然都打开这篇《使用浮点数绘制图表》,就坚持看下去,学下去吧!本文主要会给大家讲到等等知识点,如果大家对本文有好的建议或者看到有不足之处,非常欢迎大家积极提出!在后续文章我会继续更新Golang相关的内容,希望对大家都有所帮助!

问题内容

目前,我正在尝试将现有的 c# 项目转换为 golang。 该项目采用一个包含一堆坐标的 xml 文件并将它们绘制在图像上。

在 c# 中,在图像上绘制矩形的代码如下:

public void drawrectangle(graphics graphics, rectangleshape rectangle)
{
    using (var drawingpen = new pen(color.black))
    {
        graphics.drawrectangle(
            drawingpen,
            rectangle.startx,
            rectangle.starty,
            rectangle.width,
            rectangle.height);
    }
}

矩形由以下类定义:

internal sealed class rectangleshape
{
    internal rectangleshape(float startx, float starty, float width, float height)
    {
        this.startx = startx;
        this.starty = starty;
        this.width = width;
        this.height = height;
    }

    internal float startx { get; }

    internal float starty { get; }

    internal float width { get; }

    internal float height { get; }
}

这意味着 c# 能够使用定义为 float 的坐标在图像上绘制矩形。

现在,我尝试将代码转换为 golang,其中我使用以下代码绘制一个矩形:

// drawrect draws a rectangle with the given dimensions on the given image.
func drawrect(img *image.rgba, rect rectangle) {
    endx := rect.x + rect.width
    endy := rect.y + rect.height

    drawhline(img, rect.x, rect.y, endx)
    drawhline(img, rect.y, endy, endx)
    drawvline(img, rect.y, rect.x, endy)
    drawvline(img, rect.y, endx, endy)
}

// private: drawhline draws a horizontal line with the given coordinates on the given image.
func drawhline(img *image.rgba, startx, y, endx float32) {
    col := color.rgba{0x00, 0x00, 0x00, 0xff}

    for ; startx <= endx; startx++ {
        img.set(startx, y, col)
    }
}

// private: drawvline draws a vertical line with the given coordinates on the given image.
func drawvline(img *image.rgba, starty, x, endy float32) {
    col := color.rgba{0x00, 0x00, 0x00, 0xff}

    for ; starty <= endy; starty++ {
        img.set(x, starty, col)
    }
}

矩形由以下结构定义:

// rectangle represents a rectangular shape.
type rectangle struct {
    x      float32
    y      float32
    width  float32
    height float32
}

go 中的示例不起作用,因为图像上的 set 函数具有以下结构:

func (p *RGBA) Set(x, y int, c color.Color) {

go 有什么方法可以使用 float 参数在图像上绘制矩形吗?


解决方案


image.Image 类型是一个接口,它定义图像的像素具有整数坐标,可通过 image.at() 方法访问:

at(x, y int) color.color

您使用的具体实现 image.RGBA 允许再次通过 RGBA.Set() 方法使用整数坐标来更改像素:

func (p *rgba) set(x, y int, c color.color)

最简单的解决方案是将浮点坐标转换为整数坐标。简单地将浮点转换为整数就是截断,因此您应该使用舍入。一个简单的舍入是在转换之前添加 0.5。详情请参见Golang Round to Nearest 0.05

最好是在“开始”坐标上执行此操作,以便循环可以使用整数值,例如:

func drawhline(img *image.rgba, startx, y, endx float32) {
    col := color.rgba{0x00, 0x00, 0x00, 0xff}

    x1, x2 := int(startx + 0.5), int(endx + 0.5)
    y1 := int(y + 0.5)
    for x := x1; x <= x2; x++ {
        img.set(x, y1, col)
    }
}

请注意,但是这种将浮点坐标转换为整数的“最简单”解决方案可能不是“最佳”。例如,如果您需要在 x = 0.1 坐标处绘制一条水平线,则上述解决方案将在 x = 0 处绘制一条线。另一种解决方案可能是在 x = 0 处画一条“更强”的线,并在 x = 1 处画一条“较弱”的线,这样从远处看,该线实际上位于 x = 0.1 处。如果线条不是水平和垂直的,这种混叠技术肯定会给出更好的结果,但需要更多的计算(因此速度更慢)。

如果您在绘图时确实需要浮动精度,您可以使用第 3 方库,例如 github.com/fogleman/gg,它允许您传递 float64 坐标,并且它使用抗锯齿来实现良好的结果。

例如,使用 github.com/fogleman/ggimage.rgba 图像上绘制一个矩形,如下所示:

var img *image.RGBA = // create your RGBA image

ctx := gg.NewContextForRGBA(img)

// Set drawing color:
ctx.SetColor(color.RGBA{0x00, 0x00, 0x00, 0xff})
// Or simply: ctx.SetRGB(0, 0, 0)

// Draw rectangle: x, y, w, h are all float64 parameters
ctx.DrawRectangle(x, y, w, h)

另请参阅相关:Draw a rectangle in Golang?

到这里,我们也就讲完了《使用浮点数绘制图表》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>