...

Source file src/gonum.org/v1/plot/plotter/polygon_example_test.go

Documentation: gonum.org/v1/plot/plotter

     1  // Copyright ©2016 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package plotter_test
     6  
     7  import (
     8  	"image/color"
     9  	"log"
    10  	"math"
    11  
    12  	"gonum.org/v1/plot"
    13  	"gonum.org/v1/plot/palette/moreland"
    14  	"gonum.org/v1/plot/plotter"
    15  	"gonum.org/v1/plot/vg"
    16  )
    17  
    18  // ExamplePolygon_holes draws a polygon with holes, showing how
    19  // the different built-in vg backends render polygons with holes.
    20  // The output of this example is at
    21  // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.png,
    22  // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.svg,
    23  // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.pdf, and
    24  // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.eps.
    25  func ExamplePolygon_holes() {
    26  	// Create an outer ring.
    27  	outer1 := plotter.XYs{{X: 0, Y: 0}, {X: 4, Y: 0}, {X: 4, Y: 4}, {X: 0, Y: 4}}
    28  
    29  	// Create an inner ring with the same
    30  	// winding order as the outer ring.
    31  	inner1 := plotter.XYs{{X: 0.5, Y: 0.5}, {X: 1.5, Y: 0.5}, {X: 1.5, Y: 1.5}, {X: 0.5, Y: 1.5}}
    32  
    33  	// Create an inner polygon with the opposite
    34  	// winding order as the outer polygon.
    35  	inner2 := plotter.XYs{{X: 3.5, Y: 2.5}, {X: 2.5, Y: 2.5}, {X: 2.5, Y: 3.5}, {X: 3.5, Y: 3.5}}
    36  
    37  	poly, err := plotter.NewPolygon(outer1, inner1, inner2)
    38  	if err != nil {
    39  		log.Panic(err)
    40  	}
    41  	poly.Color = color.NRGBA{B: 255, A: 255}
    42  
    43  	p := plot.New()
    44  	p.Title.Text = "Polygon with holes"
    45  	p.X.Label.Text = "X"
    46  	p.Y.Label.Text = "Y"
    47  	p.Add(poly)
    48  	p.Legend.Add("key", poly)
    49  	p.Legend.TextStyle.Font.Size = vg.Points(8)
    50  	p.Legend.TextStyle.Color = color.White
    51  	p.Legend.ThumbnailWidth = vg.Points(10)
    52  
    53  	// Here we save the image in different file formats
    54  	// to show how each back end handles polygon holes.
    55  
    56  	// The vgimg backend treats both internal polygons
    57  	// as holes by default.
    58  	err = p.Save(100, 100, "testdata/polygon_holes.png")
    59  	if err != nil {
    60  		log.Panic(err)
    61  	}
    62  
    63  	// The vgsvg, vgpdf, and vgeps backgrounds all treat
    64  	// the internal polygon with the opposite winding
    65  	// direction as a hole but do not consider the internal
    66  	// polygon with the same winding direction to be a hole.
    67  	err = p.Save(100, 100, "testdata/polygon_holes.svg")
    68  	if err != nil {
    69  		log.Panic(err)
    70  	}
    71  	err = p.Save(100, 100, "testdata/polygon_holes.pdf")
    72  	if err != nil {
    73  		log.Panic(err)
    74  	}
    75  	err = p.Save(100, 100, "testdata/polygon_holes.eps")
    76  	if err != nil {
    77  		log.Panic(err)
    78  	}
    79  }
    80  
    81  // ExamplePolygon_hexagons creates a heat map with hexagon shapes.
    82  // The output of this example is at
    83  // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_hexagons_golden.png.
    84  func ExamplePolygon_hexagons() {
    85  	// hex returns a hexagon centered at (x,y) with radius r.
    86  	hex := func(x, y, r float64) plotter.XYs {
    87  		g := make(plotter.XYs, 6)
    88  		for i := range g {
    89  			g[i].X = x + r*math.Cos(math.Pi/3*float64(i))
    90  			g[i].Y = y + r*math.Sin(math.Pi/3*float64(i))
    91  		}
    92  		return g
    93  	}
    94  
    95  	var err error
    96  	p := plot.New()
    97  	p.Title.Text = "Hexagons"
    98  	p.X.Label.Text = "X"
    99  	p.Y.Label.Text = "Y"
   100  
   101  	colorMap := moreland.SmoothBlueRed()
   102  	colorMap.SetMax(2)
   103  	colorMap.SetMin(-2)
   104  	colorMap.SetConvergePoint(0)
   105  
   106  	const (
   107  		r = math.Pi / 4 // r is the hexagon radius.
   108  		// x0 and y0 are the beginning coordinates for the hexagon plot.
   109  		x0 = 0.0
   110  		y0 = 0.0
   111  		// nx and ny are the number of hexagons in the x and y directions.
   112  		nx = 5
   113  		ny = 5
   114  	)
   115  	// dx and dy are the distance between hexgons.
   116  	dx := 3 * r
   117  	dy := r * math.Sqrt(3)
   118  
   119  	xstart := []float64{x0, x0 - 1.5*r}
   120  	ystart := []float64{y0, y0 - r}
   121  	for i, xmin := range xstart {
   122  		ymin := ystart[i]
   123  		x := xmin
   124  		for ix := 0; ix < nx; ix++ {
   125  			y := ymin
   126  			for iy := 0; iy < ny; iy++ {
   127  				var poly *plotter.Polygon
   128  				poly, err = plotter.NewPolygon(hex(x, y, r))
   129  				if err != nil {
   130  					log.Panic(err)
   131  				}
   132  				poly.Color, err = colorMap.At(math.Sin(x) + math.Sin(y))
   133  				if err != nil {
   134  					log.Panic(err)
   135  				}
   136  				poly.LineStyle.Width = 0
   137  				p.Add(poly)
   138  				y += dy
   139  			}
   140  			x += dx
   141  		}
   142  	}
   143  	if err = p.Save(100, 100, "testdata/polygon_hexagons.png"); err != nil {
   144  		log.Panic(err)
   145  	}
   146  }
   147  

View as plain text