Skip to content

Commit

Permalink
misc fixes, polycross
Browse files Browse the repository at this point in the history
  • Loading branch information
cormullion committed Sep 6, 2020
1 parent f14f9da commit 0a823be
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 114 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## [v2.5.0] - forthcoming - September 2020
## [v2.5.0] - September 6 2020

### Added

Expand All @@ -10,14 +10,15 @@
### Changed

- docs use JuliaMono
- in a few functions (eg `sector`, `box`) a `:clip` action didn't work, because it was applied within a
`gsave()`/`grestore()` block. `:clip` actions should now work, as they're applied after.

### Removed

- old deprecations finally gone
- some old deprecations finally gone

### Deprecated


## [v2.4.0] - August 13 2020

### Added
Expand Down
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Luxor"
uuid = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc"
authors = ["cormullion <[email protected]>"]
version = "2.4.0"
version = "2.5.0"

[deps]
Cairo = "159f3aea-2a34-519c-b102-8c37f9878175"
Expand All @@ -23,7 +23,7 @@ test = ["Test"]
julia = "1"
Cairo = "0.7, 0.8, 1.0"
Colors = "0.9, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 1.0"
FileIO = "^1.0"
ImageMagick = "0.7, 1.0"
FileIO = "1.0, 1.1, 1.2, 1.3, 1.4"
ImageMagick = "0.7, 1.0, 1.1"
Juno = "0.7, 0.8"
QuartzImageIO = "^0.6"
QuartzImageIO = "0.6, 0.7"
10 changes: 6 additions & 4 deletions docs/src/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,12 @@ end
While drawing, you can copy the data in the form of a
matrix, using the `image_as_matrix()` function.

`image_as_matrix()` returns a array of ARGB{32} values that encode the Red, Green, and Blue, and Alpha values of each pixel.
`image_as_matrix()` returns a array of ARGB32 values that encode the Red, Green, Blue, and Alpha values of each pixel.

The following example draws a red box, then copies the drawing into a matrix called `mat1`. Then it draws a blue circle, and copies the updated drawing into `mat2`. Then, the second drawing reads the values in from the two matrices and draws some square tiles depending on the corresponding values in the two matrices ... a very primitive Boolean operation.

```@example
using Luxor, Colors # hide
using Luxor, Colors
Drawing(40, 40, :png)
origin()
Expand Down Expand Up @@ -302,21 +302,23 @@ nothing # hide

![image drawings](assets/figures/image-drawings.svg)

(You can use `collect()` to gather the re-interpreted values together.)

If you're working with Images.jl, you will probably want to transpose the array:

```
using Luxor, Images
# in Luxor
Drawing(50, 50, :image)
Drawing(50, 50, :png)
origin()
background(randomhue()...)
sethue("white")
fontsize(40)
fontface("Georgia")
text("42", halign=:center, valign=:middle)
mat = image_as_matrix()
mat = image_as_matrix();
finish()
# in Images
Expand Down
68 changes: 0 additions & 68 deletions docs/src/polygons.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,74 +119,6 @@ ngon
ngonside
```

## Stars and crosses

Use `star()` to make a star. You can draw it immediately, or use the points it can create.

```@example
using Luxor # hide
Drawing(500, 300, "assets/figures/stars.png") # hide
background("white") # hide
origin() # hide
tiles = Tiler(400, 300, 4, 6, margin=5)
for (pos, n) in tiles
randomhue()
star(pos, tiles.tilewidth/3, rand(3:8), 0.5, 0, :fill)
end
finish() # hide
nothing # hide
```

![stars](assets/figures/stars.png)

The `ratio` determines the length of the inner radius compared with the outer.

```@example
using Luxor # hide
Drawing(500, 250, "assets/figures/star-ratios.png") # hide
origin() # hide
background("white") # hide
sethue("black") # hide
setline(2) # hide
tiles = Tiler(500, 250, 1, 6, margin=10)
for (pos, n) in tiles
star(pos, tiles.tilewidth/2, 5, rescale(n, 1, 6, 1, 0), 0, :stroke)
end
finish() # hide
nothing # hide
```

![stars](assets/figures/star-ratios.png)

Use `polycross()` to draw a cross-shaped polygon.

```@example
using Luxor # hide
Drawing(600, 600, "assets/figures/polycross.png") # hide
origin() # hide
background("white") # hide
sethue("black") # hide
setline(2) # hide
tiles = Tiler(600, 600, 4, 4, margin=10)
for (pos, n) in tiles
randomhue()
polycross(pos, min(tiles.tileheight/3, tiles.tilewidth/3),
n + 2, # number of points
rescale(n, 1, length(tiles), 0.9, 0.1), # ratio
0, # orientation
:fill)
end
finish() # hide
nothing # hide
```

![polycross](assets/figures/polycross.png)

```@docs
star
polycross
```

## Polygons

Use `poly()` to draw lines connecting the points and/or just fill the area:
Expand Down
68 changes: 68 additions & 0 deletions docs/src/simplegraphics.md
Original file line number Diff line number Diff line change
Expand Up @@ -904,3 +904,71 @@ finish() # hide
nothing # hide
```
![rounded rect](assets/figures/round-rect.png)

## Stars and crosses

Use `star()` to make a star. You can draw it immediately, or use the points it can create.

```@example
using Luxor # hide
Drawing(500, 300, "assets/figures/stars.png") # hide
background("white") # hide
origin() # hide
tiles = Tiler(400, 300, 4, 6, margin=5)
for (pos, n) in tiles
randomhue()
star(pos, tiles.tilewidth/3, rand(3:8), 0.5, 0, :fill)
end
finish() # hide
nothing # hide
```

![stars](assets/figures/stars.png)

The `ratio` determines the length of the inner radius compared with the outer.

```@example
using Luxor # hide
Drawing(500, 250, "assets/figures/star-ratios.png") # hide
origin() # hide
background("white") # hide
sethue("black") # hide
setline(2) # hide
tiles = Tiler(500, 250, 1, 6, margin=10)
for (pos, n) in tiles
star(pos, tiles.tilewidth/2, 5, rescale(n, 1, 6, 1, 0), 0, :stroke)
end
finish() # hide
nothing # hide
```

![stars](assets/figures/star-ratios.png)

Use `polycross()` to draw a cross-shaped polygon.

```@example
using Luxor # hide
Drawing(600, 600, "assets/figures/polycross.png") # hide
origin() # hide
background("white") # hide
sethue("black") # hide
setline(2) # hide
tiles = Tiler(600, 600, 4, 4, margin=10)
for (pos, n) in tiles
randomhue()
polycross(pos, min(tiles.tileheight/3, tiles.tilewidth/3),
n + 2, # number of points
rescale(n, 1, length(tiles), 0.9, 0.1), # ratio
0, # orientation
:fill)
end
finish() # hide
nothing # hide
```

![polycross](assets/figures/polycross.png)

```@docs
star
polycross
```
5 changes: 4 additions & 1 deletion src/basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ end
Establish a new clipping region by intersecting the current clipping region with the
current path and then clearing the current path.
An existing clipping region is enforced through and after a `gsave()`-`grestore()` block, but a clipping region set inside
a `gsave()`-`grestore()` block is lost after `grestore()`. [?]
"""
clip() = Cairo.clip(get_current_cr())

Expand All @@ -251,7 +254,7 @@ clipreset() = Cairo.reset_clip(get_current_cr())
"""
setline(n)
Set the line width.
Set the line width, in points.
"""
setline(n) = Cairo.set_line_width(get_current_cr(), n)

Expand Down
3 changes: 2 additions & 1 deletion src/curves.jl
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ end
sector(centerpoint::Point, innerradius, outerradius, startangle, endangle, action:none)
Draw an annular sector centered at `centerpoint`.
"""
function sector(centerpoint::Point, innerradius::Real, outerradius::Real, startangle::Real,
endangle::Real, action::Symbol=:none)
Expand All @@ -249,8 +250,8 @@ function sector(centerpoint::Point, innerradius::Real, outerradius::Real, starta
line(innerradius * cos(endangle), innerradius * sin(endangle))
carc(0, 0, innerradius, endangle, startangle, :none)
closepath()
do_action(action)
grestore()
do_action(action)
end

"""
Expand Down
68 changes: 40 additions & 28 deletions src/drawings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -703,34 +703,6 @@ function image_as_matrix()
return reinterpret(ARGB32, permutedims(data, (2, 1)))
end

# function image_as_matrix()
# if length(CURRENTDRAWING) != 1
# error("no current drawing")
# end
# w = Int(current_surface().width)
# h = Int(current_surface().height)
# z = zeros(UInt32, w, h)
#
# # create a new image surface to receive the data from the current drawing
# imagesurface = CairoImageSurface(z, Cairo.FORMAT_ARGB32)
#
# # the destination - we're drawing on this
# crdest = Cairo.CairoContext(imagesurface)
#
# # set the source to be the current Luxor drawing
# Cairo.set_source_surface(crdest, Luxor.current_surface(), 0, 0)
#
# Cairo.set_operator(crdest, Cairo.OPERATOR_SOURCE)
# Cairo.paint(crdest)
#
# data = imagesurface.data
# r = unpremultiplyalpha(data)
#
# Cairo.finish(imagesurface)
# Cairo.destroy(imagesurface)
# return permutedims(r, (2, 1))
# end

"""
Create a drawing and return a matrix of the image.
Expand Down Expand Up @@ -789,6 +761,46 @@ end
drawimagematrix(m)
```
Transparency
The default value for the cells in an image matrix is
transparent black. (Luxor's default color is opaque black.)
```
julia> @imagematrix begin
end 2 2
2×2 reinterpret(ARGB32, ::Array{UInt32,2}):
ARGB32(0.0,0.0,0.0,0.0) ARGB32(0.0,0.0,0.0,0.0)
ARGB32(0.0,0.0,0.0,0.0) ARGB32(0.0,0.0,0.0,0.0)
```
Setting the background to a partially or completely
transparent value may give unexpected results:
```
julia> @imagematrix begin
background(1, 0.5, 0.0, 0.5) # semi-transparent orange
end 2 2
2×2 reinterpret(ARGB32, ::Array{UInt32,2}):
ARGB32(0.502,0.251,0.0,0.502) ARGB32(0.502,0.251,0.0,0.502)
ARGB32(0.502,0.251,0.0,0.502) ARGB32(0.502,0.251,0.0,0.502)
```
here the semi-transparent orange color has been partially
applied to the transparent background.
```
julia> @imagematrix begin
sethue(1., 0.5, 0.0)
paint()
end 2 2
2×2 reinterpret(ARGB32, ::Array{UInt32,2}):
ARGB32(1.0,0.502,0.0,1.0) ARGB32(1.0,0.502,0.0,1.0)
ARGB32(1.0,0.502,0.0,1.0) ARGB32(1.0,0.502,0.0,1.0)
```
picks up the default alpha of 1.0.
"""
macro imagematrix(body, width=256, height=256)
quote
Expand Down
13 changes: 8 additions & 5 deletions src/shapes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ function box(centerpoint::Point, width, height, cornerradius, action::Symbol=:st
line(p4end)

closepath()
do_action(action)
grestore()
do_action(action)
end

"""
Expand Down Expand Up @@ -316,29 +316,32 @@ end

"""
polycross(pt::Point, radius, npoints::Int, ratio=0.5, orientation=0.0, action=:none;
splay = 0.5,
vertices = false,
reversepath = false)
Make a cross-shaped polygon with `npoints` arms to fit inside a circle of radius `radius` centered at `pt`.
`ratio` specifies the ratio of the two sides of each arm.
`ratio` specifies the ratio of the two sides of each arm. `splay` makes the arms ... splayed.
Use `vertices=true` to return the vertices of the shape instead of drawing it.
(Adapted from Compose.xgon()))
(Adapted from Compose.jl.xgon()))
"""
function polycross(pt::Point, radius, npoints::Int, ratio=0.5, orientation=0.0, action=:none;
splay = .5,
vertices = false,
reversepath = false)
# adapted from: Compose.jl, https://github.com/GiovineItalia/Compose.jl/src/form.jl
# original author: mattriks

ratio = clamp(ratio, 0.0, 1.0)

θ₁ = range/2 + orientation + 0, stop = π/2 + orientation + 2π, length = npoints + 1)[1:end-1]

width = 2radius * ratio * sin/npoints)
# radius = width/2(ratio * sin(π/npoints))

dₒ = asin(0.5 * width/radius)
dₒ = asin(clamp(splay * width/radius, -1.0, 1.0))
dᵢ = asin(0.5 * width/(radius * ratio))

r₂ = repeat([radius * ratio, radius, radius], outer = npoints)
Expand Down

0 comments on commit 0a823be

Please sign in to comment.