Skip to content

Commit

Permalink
log fix tick
Browse files Browse the repository at this point in the history
  • Loading branch information
cormullion committed Jul 18, 2021
1 parent 985b0c1 commit 3a2b75e
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 70 deletions.
2 changes: 1 addition & 1 deletion docs/src/assets/luxor-docs.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@font-face {
font-family: JuliaMono-Regular;
src:
local('JuliaMono-Regular'),
local('JuliaMono'),
url("https://cdn.jsdelivr.net/gh/cormullion/juliamono/webfonts/JuliaMono-Regular.woff2");
}

Expand Down
93 changes: 56 additions & 37 deletions docs/src/explanation/imagematrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@

# Images as matrices

While drawing, you can copy the current graphics in a drawing as a matrix of pixels, using the [`image_as_matrix`](@ref) function.
While drawing, you can copy the current graphics in a
drawing as a matrix of colored pixels, using the
[`image_as_matrix`](@ref) function. And with the
[`@imagematrix`](@ref) macro, you can create your drawing
with vector graphics in the usual way, and then return the
result as a matrix of colored pixels.

With the [`@imagematrix`](@ref) macro, you can create your drawing with vector graphics in the usual way, but the result is returned as a matrix. This example processes an ampersand in Images.jl.
The next example draws an ampersand and then processes the
pixels further in Images.jl.

```
using Luxor, Colors, Images, ImageFiltering
Expand All @@ -28,13 +34,59 @@ imfilter(img, Kernel.gaussian(10))

![image matrix](../assets/figures/ampersand-matrix.png)

[`image_as_matrix`](@ref) returns a array of ARGB32 values. Each ARGB value encodes the Red, Green, Blue, and Alpha values of a pixel into a single 32 bit integer.
[`image_as_matrix`](@ref) returns a array of ARGB32
(AlphaRedGreenBlue) values. Each ARGB value encodes the Red,
Green, Blue, and Alpha values of a pixel into a single 32
bit integer.

The next example draws a red rectangle, then copies the drawing into a matrix called `mat1`. Then it adds a blue triangle, and copies the updated drawing into `mat2`. In the second drawing, values from the two matrices are tested, and table cells are randomly colored depending on the corresponding values ... this is a primitive Boolean operation.
You can display the matrix using, for example, Images.jl.

```
using Luxor, Images
# in Luxor
Drawing(250, 250, :png)
origin()
background(randomhue()...)
sethue("red")
fontsize(200)
fontface("Georgia")
text("42", halign=:center, valign=:middle)
mat = image_as_matrix()
finish()
# in Images
img = RGB.(mat)
# img = Gray.(mat) # for greyscale
imfilter(img, Kernel.gaussian(10))
```

In Luxor:

![42 image array](../assets/figures/42.png)

In Images:

![42 image array](../assets/figures/42gaussian.png)

The next example makes two drawings. The first draws a red rectangle, then copies the
drawing in its current state into a matrix called `mat1`. Next it adds a blue
triangle, and copies the updated drawing state into `mat2`.

In the second drawing, values from these two matrices are
tested, and table cells are randomly colored depending on
the corresponding values ... this is a primitive Boolean
operation.

```@example
using Luxor, Colors, Random # hide
Random.seed!(42) # hide
# first drawing
Drawing(40, 40, :png)
origin()
background("black")
Expand Down Expand Up @@ -78,36 +130,3 @@ In the second drawing, a table with 1600 squares is colored according to the val
![image drawings](../assets/figures/image-drawings.svg)

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

You can display the matrix using, for example, Images.jl.

```
using Luxor, Images
# in Luxor
Drawing(250, 250, :png)
origin()
background(randomhue()...)
sethue("red")
fontsize(200)
fontface("Georgia")
text("42", halign=:center, valign=:middle)
mat = image_as_matrix()
finish()
# in Images
img = RGB.(mat)
# img = Gray.(mat) # for greyscale
imfilter(img, Kernel.gaussian(10))
```

In Luxor:

![42 image array](../assets/figures/42.png)

In Images:

![42 image array](../assets/figures/42gaussian.png)
29 changes: 18 additions & 11 deletions docs/src/explanation/transforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ nothing # hide

```@example
using Luxor, Colors, Random # hide
Drawing(800, 250, "../assets/figures/scale.png") # hide
Drawing(800, 300, "../assets/figures/scale.png") # hide
background("antiquewhite") # hide
Random.seed!(1) # hide
setline(1) # hide
Expand Down Expand Up @@ -172,7 +172,7 @@ julia> getmatrix()
0.0
```

[`transform(a)`](@ref) transforms the current workspace by 'multiplying' the current matrix with matrix `a`. For example, `transform([1, 0, xskew, 1, 50, 0])` skews the current matrix by `xskew` radians and moves it 50 in x and 0 in y.
[`transform(a)`](@ref) transforms the current workspace by multiplying the current matrix with matrix `a`. For example, `transform([1, 0, xskew, 1, 50, 0])` skews the current matrix by `xskew` radians and moves it 50 in x and 0 in y.

```@example
using Luxor # hide
Expand Down Expand Up @@ -218,7 +218,7 @@ If you use [`translate`](@ref) to move the origin to different places on a drawi

```@example
using Luxor, Random # hide
Drawing(600, 400, "../assets/figures/getworldposition.png") # hide
Drawing(800, 400, "../assets/figures/getworldposition.png") # hide
background("antiquewhite") # hide
Random.seed!(3) # hide
setline(1) # hide
Expand All @@ -241,14 +241,14 @@ nothing # hide

## Coordinate conventions

In Luxor, by default, the y axis points downwards, and the x axis points to the right.
In Luxor, by convention, the y axis points downwards, and the x axis points to the right.

There are basically two main conventions for computer graphics:

- mathematical illustrations, such as graphs, figures, Plots.jl, plots, etc., use the "y upwards" convention

- most computer graphics systems (HTML, SVG, Processing, Cairo, Luxor, image processing, most GUIs, etc) use "y downwards" convention

- mathematical illustrations, such as graphs, figures, Plots.jl, plots, etc., which use the "y upwards" convention

```@setup conventions
using Luxor
diagram = @drawsvg begin
Expand All @@ -261,21 +261,24 @@ diagram = @drawsvg begin
text("y", O + (20, -200))
arrow(O, O + (200, 0))
text("x", O + (200, 20))
text("maths: y upwards", O + (0, 100), halign=:center)
end
@layer begin
translate(table[2])
text("computing: y downwards", O + (0, 100), halign=:center)
rulers()
end
end 800 450
```

```@example conventions
diagram
diagram # hide
```

You could use a transformation matrix to reflect the Luxor drawing space in the x-axis.
You could use a transformation matrix to reflect the Luxor drawing space in the x axis.

```@example
using Luxor # hide
Expand All @@ -301,13 +304,17 @@ end 800 450 # hide

!!! note

If you do this, all your text will be incorrectly drawn, so you'd need to use enclose text functions with antoher matrix transformation.
If you do this and try to place text, all your text will be incorrectly drawn upside down, so you'd need to enclose any text placement with more matrix transformations.

## Advanced transformations

For more powerful transformations, consider using Julia packages which are designed specifically for the purpose.
For more powerful transformations of graphic elements,
consider using Julia packages which are designed
specifically for the purpose.

The following example sets up some transformations, which can then be composed in the correct order to transform points.
The following example sets up some transformations which
can then be composed in the correct order to transform
points.

```
rawpts = [
Expand Down
54 changes: 35 additions & 19 deletions docs/src/howto/simplegraphics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1104,35 +1104,49 @@ There's a matching [`epitrochoid`](@ref) function.

## Ticks

The [`tickline`](@ref) function lets you divide a distance between two points into ticks: short lines positioned equidistant between the two end points.
The [`tickline`](@ref) function lets you divide the space
between two points by drawing ‘ticks’, short parallel lines
positioned equidistant between the two points.

In its simplest form it can used to draw basic number lines, complete with text labels.
In its simplest form the function can used to draw basic
number lines, complete with automatic text labels.

```@example
using Luxor # hide
@drawsvg begin
background("antiquewhite")
tickline(Point(-350, -100), Point(350, -100))
tickline(Point(-350, 0), Point(350, 0),
major=3,
startnumber=0, finishnumber=100)
tickline(Point(-350, 100), Point(350, 100), major=3, minor=4)
background("antiquewhite")
# major defaults to 1
tickline(Point(-350, -100), Point(350, -100))
# three major ticks inserted
tickline(Point(-350, 0), Point(350, 0),
major=3,
startnumber=0, finishnumber=100)
# four minor ticks inserted between each major
tickline(Point(-350, 100), Point(350, 100), major=3, minor=4)
end 800 350 # hide
```

These spaced positions (linear or logarithmic) are useful even when you switch off the text display and just return points (using `vertices=true`).

The function returns the positions of the generated ticks in two arrays of points - the locations of the major and minor ticks.

The spaced positions (linear or logarithmic) are useful even when you switch off the display of text (using `vertices=true`) and just return points.

```@example
using Luxor # hide
@drawsvg begin # hide
background("antiquewhite") # hide
# no axis
tickline(Point(-350, -100), Point(350, -100), minor=9, axis=false)
# logarithmic
majticks, minticks = tickline(Point(-350, 0), Point(350, 0),
major=9,
startnumber=1,
finishnumber=10,
log=true,
vertices=false)
Expand Down Expand Up @@ -1179,22 +1193,24 @@ Sometimes you just want a sequence of spaced points.

```@example
using Luxor, Colors # hide
@drawsvg begin # hide
background("black") # hide
_, minticks = tickline(Point(-400, 0), Point(420, 0),
major=1, minor=25,
_, minticks = tickline(Point(-400, 0), Point(260, 0),
major=0, minor=40,
log=true,
axis=false,
vertices=true)
@drawsvg begin # hide
background("black")
for (n, pt) in enumerate(minticks)
k = rescale(n, 0, length(minticks), 0, 1)
sethue(LCHab(40, 100, 360k))
setline(12k)
wave = [pt + Point(50k * sin(y), (360/2π) * y) for y in -:π/12:2π]
k = rescale(n, 1, length(minticks), 0, 1)
sethue(LCHab(60, 100, 360k))
setline(1/k)
wave = [pt + Point(120k * sin(y), 600/2π * y) for y in -π:π/20:π]
poly(wave, :stroke)
end
end 800 700 # hide
end 800 600 # hide
```

## Cropmarks
Expand Down
4 changes: 2 additions & 2 deletions src/arrows.jl
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,9 @@ function tickline(startpos, finishpos;
# 1 major/minor division means 3 ticks (beginning, middle, end)

if log == true
majorticklocations = between.(O, newfinishpos, rescale.(exp10.(range(0, 1, length=(major+2))), 1, 10, 0, 1))
majorticklocations = between.(O, newfinishpos, log10.(range(1, 10, length=(major+2))))
n_minorticks = ((major + 1) * (minor + 1)) + 1
minorticklocations = between.(O, newfinishpos, rescale.(exp10.(range(0, 1, length=n_minorticks)), 1, 10, 0, 1))
minorticklocations = between.(O, newfinishpos, log10.(range(1, 10, length=n_minorticks)))
else
majorticklocations = between.(O, newfinishpos, range(0, 1, length=(major+2)))
n_minorticks = ((major + 1) * (minor + 1)) + 1
Expand Down

0 comments on commit 3a2b75e

Please sign in to comment.