TileRectangle tiles the given cell (determines the axes along which cells are repeated) onto the rectangle dst (bounds of clipping path), where cells are filled by rectangle src (bounds of object to be tiled).
(cell Matrix, dst, src Rect)
| 36 | |
| 37 | // TileRectangle tiles the given cell (determines the axes along which cells are repeated) onto the rectangle dst (bounds of clipping path), where cells are filled by rectangle src (bounds of object to be tiled). |
| 38 | func TileRectangle(cell Matrix, dst, src Rect) []Matrix { |
| 39 | // find extremes along cell axes |
| 40 | invCell := cell.Inv() |
| 41 | points := []Point{ |
| 42 | invCell.Dot(Point{dst.X0, dst.Y0}), |
| 43 | invCell.Dot(Point{dst.X1, dst.Y0}), |
| 44 | invCell.Dot(Point{dst.X1, dst.Y1}), |
| 45 | invCell.Dot(Point{dst.X0, dst.Y1}), |
| 46 | } |
| 47 | x0, x1 := points[0].X, points[0].X |
| 48 | y0, y1 := points[0].Y, points[0].Y |
| 49 | for _, point := range points[1:] { |
| 50 | x0 = math.Min(x0, point.X) |
| 51 | x1 = math.Max(x1, point.X) |
| 52 | y0 = math.Min(y0, point.Y) |
| 53 | y1 = math.Max(y1, point.Y) |
| 54 | } |
| 55 | |
| 56 | // add/subtract when overflowing/underflowing cell |
| 57 | cellBounds := src.Transform(invCell) |
| 58 | x0 -= cellBounds.X1 - 1.0 |
| 59 | y0 -= cellBounds.Y1 - 1.0 |
| 60 | x1 -= cellBounds.X0 |
| 61 | y1 -= cellBounds.Y0 |
| 62 | |
| 63 | // collect all positions |
| 64 | cells := []Matrix{} |
| 65 | for y := math.Floor(y0); y < y1; y += 1.0 { |
| 66 | for x := math.Floor(x0); x < x1; x += 1.0 { |
| 67 | p := cell.Dot(Point{x, y}) |
| 68 | if src.Translate(p.X, p.Y).Overlaps(dst) { |
| 69 | cells = append(cells, cell.Translate(x, y)) |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | return cells |
| 74 | } |
| 75 | |
| 76 | //// P1 wallpaper group |
| 77 | //var P1 = []Matrix{Identity} |