Skip to content

Commit

Permalink
Add labels.jl, latex.jl
Browse files Browse the repository at this point in the history
modified:   Manifest.toml Version
modified:   Project.toml  Version
modified:   src/MechanicalSketch.jl
modified:   src/arrow.jl  Add draw_arrowhead, redefine curved arrows.
modified:   src/autodiff_unitfu.jl Add ∇, ortography
modified:   src/chart.jl Add color_matrix, propose_legend
modified:   src/curves.jl box_fill_outline -> labels
modified:   src/flow.jl   Delete  hue_from_complex_argument!, old color_matrix
new file:   src/labels.jl Move box_fill_outline and setlabel here, add label_boxed
new file:   src/latex.jl Move from place_image, enable bold latex.
modified:   src/place_image.jl Reshuffle and move out latex
modified:   src/scale.jl Remove empty line
modified:   src/streamline_convolution.jl Signature draw_streamlines,
                                          streamlines_add! -> streamlines_matrix!,
                                          streamlines_matrix,
                                          less strict convolution_matrix
modified:   test/Manifest.toml
modified:   test/test_23.jl
modified:   test/test_26.jl
modified:   test/test_26.png
modified:   test/test_27.jl
modified:   test/test_27.png
modified:   test/test_3.jl               Counterclockwise arrows.
modified:   test/test_3.png
modified:   test/test_32.jl
modified:   test/test_33.jl
modified:   test/test_33.png
modified:   test/test_34.jl
new file:   test/test_38.jl              color_matrix test
new file:   test/test_38.png
new file:   test/test_39.jl
new file:   test/test_39.png
modified:   test/test_5.jl
modified:   test/test_5.png
new file:   test/test_functions_38.jl
new file:   test/test_functions_39.jl
  • Loading branch information
hustf committed Mar 9, 2021
1 parent 8a4f10e commit adf9582
Show file tree
Hide file tree
Showing 33 changed files with 857 additions and 434 deletions.
38 changes: 19 additions & 19 deletions Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ version = "3.10.2"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "4bffea7ed1a9f0f3d1a131bbcd4b925548d75288"
git-tree-sha1 = "5e9769a17f17b587c951d57ba4319782b40c3513"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.10.9"
version = "0.10.10"

[[ColorVectorSpace]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "StatsBase"]
Expand Down Expand Up @@ -203,10 +203,10 @@ uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615"
version = "1.1.0"

[[FileIO]]
deps = ["Pkg"]
git-tree-sha1 = "fee8955b9dfa7bec67117ef48085fb2b559b9c22"
deps = ["Pkg", "Requires", "UUIDs"]
git-tree-sha1 = "8800ec70aee7292931a3d3c10a3be3445b9c6141"
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
version = "1.4.5"
version = "1.6.2"

[[FixedPointNumbers]]
deps = ["Statistics"]
Expand Down Expand Up @@ -300,9 +300,9 @@ version = "0.8.20"

[[ImageMagick]]
deps = ["FileIO", "ImageCore", "ImageMagick_jll", "InteractiveUtils", "Libdl", "Pkg", "Random"]
git-tree-sha1 = "02558f83932fde6ebd3ab007dbff6bd8740a8247"
git-tree-sha1 = "f35fb0080591e6f271b7e1cf4c8323a4a78d5150"
uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
version = "1.1.6"
version = "1.1.7"

[[ImageMagick_jll]]
deps = ["JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pkg", "Zlib_jll", "libpng_jll"]
Expand Down Expand Up @@ -380,15 +380,15 @@ uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.0+3"

[[LaTeXStrings]]
git-tree-sha1 = "c7aebfecb1a60d59c0fe023a68ec947a208b1e6b"
git-tree-sha1 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.0"
version = "1.2.1"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "3a0084cec7bf157edcb45a67fac0647f88fe5eaf"
git-tree-sha1 = "537df0b32bc0a99620872cc6d06278e454da4533"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.14.7"
version = "0.14.10"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
Expand Down Expand Up @@ -472,9 +472,9 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[Luxor]]
deps = ["Base64", "Cairo", "Colors", "Dates", "FileIO", "ImageMagick", "Juno", "QuartzImageIO", "Random", "Rsvg"]
git-tree-sha1 = "c018cde3ab7b0867d9f9bd49d290cf15dc9fb926"
git-tree-sha1 = "8796dfbdde81ec4a811a2d972a6d5f8a7c4113d0"
uuid = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc"
version = "2.9.0"
version = "2.10.0"

[[METIS_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
Expand Down Expand Up @@ -578,9 +578,9 @@ version = "1.1.1"

[[OffsetArrays]]
deps = ["Adapt"]
git-tree-sha1 = "f64fbf703e7f5af5d82ea7b7385b443bb7765ce9"
git-tree-sha1 = "b3dfef5f2be7d7eb0e782ba9146a5271ee426e90"
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
version = "1.6.1"
version = "1.6.2"

[[OpenBLAS32_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
Expand Down Expand Up @@ -619,9 +619,9 @@ version = "1.42.4+10"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "50c9a9ed8c714945e01cd53a21007ed3865ed714"
git-tree-sha1 = "223a825cccef2228f3fdbf2ecc7ca93363059073"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "1.0.15"
version = "1.0.16"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
Expand Down Expand Up @@ -667,9 +667,9 @@ version = "1.0.0"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "cfbac6c1ed70c002ec6361e7fd334f02820d6419"
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.2"
version = "1.1.3"

[[Roots]]
deps = ["Printf"]
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MechanicalSketch"
uuid = "183f2c95-4b91-4df3-9bd2-197e8f9edb13"
authors = ["hustf <[email protected]> and contributors"]
version = "0.4"
version = "0.4.1"

[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
Expand Down
4 changes: 3 additions & 1 deletion src/MechanicalSketch.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module MechanicalSketch
import Luxor
import Luxor: Drawing,Turtle, Pencolor, Penwidth, Forward, Turn, HueShift, Point, SVGimage,
import Luxor: Drawing,Turtle, Pencolor, Penwidth, Forward, Turn, HueShift, SVGimage,
paper_sizes,
Tiler, Partition,
rescale,
Expand Down Expand Up @@ -283,6 +283,7 @@ include("rope.jl")
include("power.jl")
include("table.jl")
include("curves.jl")
include("labels.jl")
include("flow.jl")
include("runge_kutta.jl")
include("autodiff_unitfu.jl")
Expand All @@ -292,5 +293,6 @@ include("matrix_drawing.jl")
include("colorlegends.jl")
include("colorlegends_vector.jl")
include("place_image.jl")
include("latex.jl")
include("chart.jl")
end # module
171 changes: 129 additions & 42 deletions src/arrow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ function arrow(p::Point, Fx::F, Fy::F;
linewidth = PT,
backgroundcolor = colorant"white",
labellength::Bool = false) where {F <: Force}
# TODO linewidth - drop or implement
# TODO backgroundcolor - drop or implement
ΔFx = Point(Fx * cos(α), Fx *sin(α))
ΔFy = Point(-Fy * sin(α), Fy *cos(α))
ΔF = ΔFx + ΔFy
Expand All @@ -74,7 +72,7 @@ function arrow(p::Point, Fx::F, Fy::F;
arrow_nofill(p, p + ΔFx, arrowheadlength = arrowheadlength, arrowheadangle = pi/12, linewidth = PT / 2)
shaftlength = hypot(ΔFy)
arrowheadlength = shaftlength > 3 * EM ? EM : shaftlength / 3
arrow_nofill(p, p + ΔFy, arrowheadlength = arrowheadlength, arrowheadangle = pi/12, linewidth = PT / 2)
arrow_nofill(p, p + ΔFy, arrowheadlength = arrowheadlength, arrowheadangle = π / 12, linewidth = PT / 2)
grestore()
end

Expand Down Expand Up @@ -177,36 +175,7 @@ function arrow(p::Point, vx::V, vy::V;
return nothing
end

"Add a label at the end point, rounded absolute length with unit."
function setlabel(endpoint, vx, vy, α)
Δvx = (vx * cos(α), vx *sin(α))
Δvy = (-vy * sin(α), vy *cos(α))
Δv = Δvx + Δvy
l = hypot(Δv)
rounded = round(unit(l), l, digits = 1)
direction = atan(Δv[2], Δv[1]) |> °
labdir = direction + 90°
labpos = if -90° <= labdir < -70°
:S
elseif labdir < -20°
:SE
elseif labdir < 20°
:E
elseif labdir < 70°
:NE
elseif labdir < 110°
:N
elseif labdir < 160°
:NW
elseif labdir < 200°
:W
elseif labdir < 250°
:SW
else
:S
end
label(string(rounded) , labpos, endpoint, offset = div(EM, 4))
end

function curved_point_arrow_with_vanes(p, Δv, endpoint, linewidth)
arrowheadangle = pi/24

Expand Down Expand Up @@ -286,8 +255,8 @@ Same as Luxor.arrow, except for leaving the arrow head unfilled
"""
function arrow_nofill(startpoint::Point, endpoint::Point;
linewidth=1.0,
arrowheadlength=10,
arrowheadangle=pi/8,
arrowheadlength= EM / 4.4,
arrowheadangle = π / 8,
decoration = 0.5,
decorate = () -> ())
gsave()
Expand All @@ -297,7 +266,9 @@ function arrow_nofill(startpoint::Point, endpoint::Point;
isapprox(startpoint, endpoint) && throw(error("can't draw arrow between two identical points"))
shaftlength = distance(startpoint, endpoint)
shaftangle = atan(startpoint.y - endpoint.y, startpoint.x - endpoint.x)

arrowheadtopsideangle = shaftangle + arrowheadangle

# shorten the length so that lines
# stop before we get to the arrow
# thus wide shafts won't stick out through the head of the arrow.
Expand All @@ -312,23 +283,139 @@ function arrow_nofill(startpoint::Point, endpoint::Point;
newpath()
line(Point(fromx, fromy), Point(tox, toy), :stroke)

# prepare to add decorations at point along shaft
for decpos in decoration
decpoint = between(startpoint, endpoint, decpos)
slp = slope(startpoint, endpoint)
@layer begin
translate(decpoint)
rotate(slp)
decorate()
end
end
# draw the arrowhead
draw_arrowhead(endpoint, shaftangle;
arrowheadangle,
arrowheadlength, filled = false)
grestore()
end
"""
draw_arrowhead(endpoint, shaftangle;
arrowheadangle = π / 8,
arrowheadlength = EM / 4.4; filled = false)
"""
function draw_arrowhead(endpoint, shaftangle;
arrowheadangle = π / 8,
arrowheadlength = EM / 4.4, filled = false)
arrowheadtopsideangle = shaftangle + arrowheadangle
# draw the arrowhead
topx = endpoint.x + cos(arrowheadtopsideangle) * arrowheadlength
topy = endpoint.y + sin(arrowheadtopsideangle) * arrowheadlength
arrowheadbottomsideangle = shaftangle - arrowheadangle
botx = endpoint.x + cos(arrowheadbottomsideangle) * arrowheadlength
boty = endpoint.y + sin(arrowheadbottomsideangle) * arrowheadlength
poly([Point(topx, topy), endpoint, Point(botx, boty)], :stroke)
poly([Point(topx, topy), endpoint, Point(botx, boty)], filled ? :fill : :stroke)
end


"""
arrow(centerpos::Point, radius, α_sta::Angle, α_end::Angle;
linewidth=1.0,
arrowheadlength = EM / 4.4,
arrowheadangle = π / 8,
decoration = 0.5,
decorate = () -> (),
clockwise = false)
Draw a curved arrow, an arc centered at `centerpos` starting at `α_sta` and
ending at `α_end`.
The arrowhead at the end is optional. Angles are measured counter-clockwise
from the positive x-axis.
Arrows don't use the current linewidth setting (`setline()`); you can specify
the linewidth.
The `decorate` keyword argument accepts a function that can execute code at
locations on the arrow's shaft. The inherited graphic environment is centered at
points on the curve between 0 and 1 given by scalar or vector `decoration`, and
the x-axis is aligned with the direction of the curve at that point.
"""
function arrow(centerpos::Point, radius, α_sta::Angle, α_end::Angle;
linewidth=1.0,
arrowheadlength = EM / 4.4,
arrowheadangle = π / 8,
decoration = 0.5,
decorate = () -> (),
clockwise = false,
filled = false)
@assert radius >= zero(radius) " radius < 0 not supported. Flip keyword argument clockwise?"
gsave()
setlinejoin("butt")
setline(linewidth)
# Radius in points, unitless
r = scale_to_pt(oneunit(radius)) * radius / unit(radius)
while α_sta > α_end
α_end += unit(α_end)(360°)
end
# Full arc ccw angle span. Negative values for clockwise pointing arrows
Δα = clockwise ? α_sta - α_end : α_end - α_sta

# End arrow arc ccw angle span. Negative values for clockwise pointing arrows.
Δα_head = unit(α_end)(arrowheadlength / r) * (clockwise ? -1 : 1)
α_head = α_end - Δα_head

# Is there room for one arrow head?
if sign(Δα_head) != sign(Δα) && abs(Δα_head) < abs(Δα)
@warn "Arrow head too large, try negative keyword argument arrowheadlength"
return
end

# In case we are drawing a sharp arrow head point and a wide shaft, we want to end the arc somewhere inside of the head.
# Sign convention: Positive values for cutting off ccw arcs.
Δα_cutoff = unit(α_end)((linewidth / 2) / tan(arrowheadangle) / r) * sign(Δα)
# Draw the arc to
α_cutoff = unit(α_end)(α_end - Δα_cutoff)

# Local origo at centre
translate(centerpos)
# Start, end, head crossing points and end of drawn arc in local pt coordinates, where +y is down
p0 = Point(rcos(α_sta), -rsin(α_sta))
p1 = Point(rcos(α_end), -rsin(α_end))
p1h = Point(rcos(α_end - Δα_head), -rsin(α_end - Δα_head))
p1c = Point(rcos(α_end - Δα_cutoff), -rsin(α_end - Δα_cutoff))

# Unitless, clockwise radian angles from origo
β_sta = rad(-α_sta) / 1rad
β_head = rad(-α_head) / 1rad
β_cutoff = rad(-α_cutoff) / 1rad
β_end = rad(-α_end) / 1rad

# Draw the cut-off shaft arc
newpath()
move(p0.x, p0.y)
if clockwise
arc(0, 0, r, β_sta, β_cutoff, :stroke)
else
carc(0, 0, r, β_sta, β_cutoff, :stroke)
end
closepath()
# prepare to add decorations at points along shaft

# prepare to add decorations at point along shaft
for decpos in decoration
decpoint = between(startpoint, endpoint, decpos)
slp = slope(startpoint, endpoint)
decorationangle = rescale(decpos, 0, 1, β_sta, β_end)
decorationpoint = Point(r * cos(decorationangle), r * sin(decorationangle))
perp = perpendicular(decorationpoint)
@layer begin
translate(decpoint)
rotate(slp)
translate(decorationpoint)
rotate(slope(decorationpoint, perp))
decorate()
end
end

# Head
draw_arrowhead(p1, β_cutoff + (clockwise ? -π / 2 : π / 2 );
arrowheadangle, arrowheadlength, filled)
grestore()
end
return
end
Loading

0 comments on commit adf9582

Please sign in to comment.