Skip to content

Commit

Permalink
Add ticks to angular axis
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesrswift committed Jul 31, 2024
1 parent 42a4959 commit ee26caf
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 23 deletions.
89 changes: 72 additions & 17 deletions src/axes/presets/scientific-polar.typ
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

// Default Scientific Style
#let default-style-scientific-polar = util.merge-dictionary(default-style-scientific, (
left: (tick: (label: (anchor: "east"))),
bottom: (tick: (label: (anchor: "north"))),
right: (tick: (label: (anchor: "west"))),
top: (tick: (label: (anchor: "south"))),
distal: (tick: (label: (anchor: "north-east", offset: 0.25))),
angular: (tick: (label: (anchor: "center", offset: 0.35))),
stroke: (cap: "square"),
padding: 0,
))
Expand Down Expand Up @@ -39,10 +37,10 @@
for (distance, label, is-major) in ticks {
let theta = distance * calc.pi * 2
draw.line(
(radius / 2, radius / 2),
(radius, radius),
(
radius * (calc.cos(theta) + 1) / 2,
radius * (calc.sin(theta) + 1) / 2
radius * (calc.cos(theta) + 1),
radius * (calc.sin(theta) + 1)
),
stroke: if is-major and (kind == 1 or kind == 3) {
style.grid.stroke
Expand All @@ -54,8 +52,8 @@
} else {
for (distance, label, is-major) in ticks {
circle(
(radius / 2, radius / 2),
radius: distance * radius / 2,
(radius, radius),
radius: distance * radius,
stroke: if is-major and (kind == 1 or kind == 3) {
style.grid.stroke
} else if not is-major and (kind >= 2) {
Expand Down Expand Up @@ -113,7 +111,62 @@
}
}

#let place-ticks-on-radius(ticks, center, radius, style) = {
#let place-ticks-on-radius(ticks, center, radius, style, flip: true) = {

// Early exit
let show-label = style.tick.label.show
if (show-label not in (auto, true)) {return}

let def(v, d) = {
return if v == none or v == auto {d} else {v}
}

for (distance, label, is-major) in ticks {

// Early exit for overlapping tick
if (distance == 1){continue}

let theta = (2 * distance) * calc.pi
let dist = radius

let offset = style.tick.offset
let length = if is-major { style.tick.length } else { style.tick.minor-length }
if flip {
offset *= -1
length *= -1
}

let a = dist + offset
let b = a + length

draw.line(
(a * calc.sin(theta) + radius, a * calc.cos(theta) + radius),
(b * calc.sin(theta) + radius, b * calc.cos(theta) + radius),
stroke: style.tick.stroke
)

if (label != none){
let offset = style.tick.label.offset
if flip {
offset *= -1
length *= -1
}
// let c = vector.sub(if length <= 0 { b } else { a },
// vector.scale(norm, offset))

let c = a - offset

let angle = def(style.tick.label.angle, 0deg)
let anchor = def(style.tick.label.anchor, "center")

draw.content(
(c * calc.sin(theta) + radius, c * calc.cos(theta) + radius),
[#label],
angle: angle,
anchor: anchor
)
}
}

}

Expand All @@ -131,18 +184,20 @@

let style = style.named()
style = styles.resolve(ctx.style, merge: style, root: "axes",
base: default-style-scientific)
base: default-style-scientific-polar)
style = _prepare-style(ctx, style)

// Compute ticks
let x-ticks = compute-ticks(angular, style)
let y-ticks = compute-ticks(distal, style)
let radius = calc.min(w,h)
let radius = calc.min(w,h) / 2

style.fill = luma(95%)

// Draw frame
if style.fill != none {
on-layer(style.background-layer, {
circle( (0,0), radius: radius, fill: style.fill, stroke: none)
circle( (radius,radius), radius: radius, fill: style.fill, stroke: none)
// rect((0,0), (w,h), fill: style.fill, stroke: none)
})
}
Expand Down Expand Up @@ -173,8 +228,8 @@

group(name: "axes", {
let axes = (
("angular", (radius/2, radius/2), (radius/2, radius), (0, -1), false, x-ticks, angular),
("distal", (radius/2, radius/2), (radius, radius/2), (1, 0), true, y-ticks, distal,),
("angular", (radius, radius), (radius, radius*2), (0, -1), false, x-ticks, angular),
("distal", (radius, radius), (radius, radius*2), (-1,0), true, y-ticks, distal,),
)

for (name, start, end, outsides, flip, ticks, axis) in axes {
Expand All @@ -192,12 +247,12 @@
if (name == "angular"){
let (data-start, data-end) = _inset-axis-points(ctx, style, axis, start, end)

let path = _draw-polar-axis-line(start, radius/2, axis, is-horizontal, style)
let path = _draw-polar-axis-line(start, radius, axis, is-horizontal, style)
on-layer(style.axis-layer, {
group(name: "axis", {
if draw-unset or axis != none {
path;
place-ticks-on-radius(ticks, start, radius/2, style)
place-ticks-on-radius(ticks, start, radius, style)
}
})
})
Expand Down
2 changes: 1 addition & 1 deletion src/axes/viewport.typ
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
let radius = calc.min(..size)
let x-norm = (vec.at(0) - x-axis.min) / (x-axis.max - x-axis.min)
let y-norm = (vec.at(1) - y-axis.min) / (y-axis.max - y-axis.min)
let theta = 2 * calc.pi * x-norm - calc.pi/2
let theta = 2 * calc.pi * x-norm
let dist = (radius/2) * y-norm
let x = dist * calc.cos(theta)
let y = dist * calc.sin(theta)
Expand Down
19 changes: 14 additions & 5 deletions tests/plot/polar/test.typ
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
/* Scientific Style */
#test-case({

draw.set-style(
axes: (tick: (label: (position: "south"))),
legend: (stroke: none, achor: "west")
)
// draw.set-style(
// axes: (tick: (label: (position: "south"))),
// legend: (stroke: none, achor: "west")
// )

plot.plot(
size: (16,9),
Expand All @@ -25,6 +25,7 @@
x-minor-tick-step: calc.pi / 16,
x-grid: "both",
x-min: 0, x-max: 2 * calc.pi,
x-format: plot.formats.multiple-of,

y-min: -1, y-max: 1,
y-tick-step: 0.5,
Expand All @@ -38,8 +39,16 @@
domain: (0, 2* calc.pi),
line: "raw",
samples: 100,
// fill: true,
label: $sin(x)$
)

plot.add(
(t)=>calc.pow(calc.sin(t),2),
domain: (0, 2* calc.pi),
line: "raw",
samples: 100,
label: $sin^2 (x)$
)

})
})

0 comments on commit ee26caf

Please sign in to comment.