• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / ark-pixel / 13727326526

07 Mar 2025 06:52PM CUT coverage: 28.089% (-19.3%) from 47.374%
13727326526

push

github

web-flow
Add first plot drawers (#8)

7 of 677 new or added lines in 11 files covered. (1.03%)

457 of 1627 relevant lines covered (28.09%)

55.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/plot/field.go
1
package plot
2

3
import (
4
        "fmt"
5
        "image/color"
6

7
        pixel "github.com/gopxl/pixel/v2"
8
        "github.com/gopxl/pixel/v2/backends/opengl"
9
        "github.com/mlange-42/ark-tools/observer"
10
        "github.com/mlange-42/ark/ecs"
11
        "gonum.org/v1/plot"
12
        "gonum.org/v1/plot/plotter"
13
        "gonum.org/v1/plot/vg"
14
        "gonum.org/v1/plot/vg/draw"
15
        "gonum.org/v1/plot/vg/vgimg"
16
)
17

18
// Field plot drawer.
19
//
20
// Plots a vector field from a GridLayers observer.
21
// For large grids, this is relatively slow.
22
// Consider using [ImageRGB] instead.
23
type Field struct {
24
        Observer observer.GridLayers // Observers providing field component grids.
25
        Labels   Labels              // Labels for plot and axes. Optional.
26
        Layers   []int               // Layer indices. Optional, defaults to (0, 1).
27

28
        data  plotField
29
        scale float64
30
}
31

32
// Initialize the drawer.
NEW
33
func (f *Field) Initialize(w *ecs.World, win *opengl.Window) {
×
NEW
34
        f.Observer.Initialize(w)
×
NEW
35

×
NEW
36
        f.data = plotField{
×
NEW
37
                GridLayers: f.Observer,
×
NEW
38
        }
×
NEW
39

×
NEW
40
        if f.Layers == nil {
×
NEW
41
                f.Layers = []int{0, 1}
×
NEW
42
        } else if len(f.Layers) != 2 {
×
NEW
43
                panic("field plot Layers must be of length 2")
×
44
        }
NEW
45
        layers := f.Observer.Layers()
×
NEW
46
        for _, l := range f.Layers {
×
NEW
47
                if layers <= l {
×
NEW
48
                        panic(fmt.Sprintf("layer index %d out of range", l))
×
49
                }
50
        }
51

NEW
52
        f.scale = calcScaleCorrection()
×
53
}
54

55
// Update the drawer.
NEW
56
func (f *Field) Update(w *ecs.World) {
×
NEW
57
        f.Observer.Update(w)
×
NEW
58
}
×
59

60
// UpdateInputs handles input events of the previous frame update.
NEW
61
func (f *Field) UpdateInputs(w *ecs.World, win *opengl.Window) {}
×
62

63
// Draw the drawer.
NEW
64
func (f *Field) Draw(w *ecs.World, win *opengl.Window) {
×
NEW
65
        width := win.Canvas().Bounds().W()
×
NEW
66
        height := win.Canvas().Bounds().H()
×
NEW
67

×
NEW
68
        f.updateData(w)
×
NEW
69

×
NEW
70
        canvas := vgimg.New(vg.Points(width*f.scale)-10, vg.Points(height*f.scale)-10)
×
NEW
71

×
NEW
72
        p := plot.New()
×
NEW
73
        setLabels(p, f.Labels)
×
NEW
74

×
NEW
75
        p.X.Tick.Marker = removeLastTicks{}
×
NEW
76

×
NEW
77
        field := plotter.NewField(&f.data)
×
NEW
78

×
NEW
79
        p.Add(field)
×
NEW
80

×
NEW
81
        win.Clear(color.White)
×
NEW
82
        p.Draw(draw.New(canvas))
×
NEW
83

×
NEW
84
        img := canvas.Image()
×
NEW
85
        picture := pixel.PictureDataFromImage(img)
×
NEW
86

×
NEW
87
        sprite := pixel.NewSprite(picture, picture.Bounds())
×
NEW
88
        sprite.Draw(win, pixel.IM.Moved(pixel.V(picture.Rect.W()/2.0+5, picture.Rect.H()/2.0+5)))
×
NEW
89
}
×
90

NEW
91
func (f *Field) updateData(w *ecs.World) {
×
NEW
92
        values := f.Observer.Values(w)
×
NEW
93
        f.data.XValues = values[f.Layers[0]]
×
NEW
94
        f.data.YValues = values[f.Layers[1]]
×
NEW
95
}
×
96

97
type plotField struct {
98
        observer.GridLayers
99
        XValues []float64
100
        YValues []float64
101
}
102

NEW
103
func (f *plotField) Vector(c, r int) plotter.XY {
×
NEW
104
        w, _ := f.GridLayers.Dims()
×
NEW
105
        return plotter.XY{
×
NEW
106
                X: f.XValues[r*w+c],
×
NEW
107
                Y: f.YValues[r*w+c],
×
NEW
108
        }
×
NEW
109
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc