|
232 | 232 | format: "float"
|
233 | 233 | ),
|
234 | 234 | mode: auto, base: auto) = (
|
235 |
| - min: min, max: max, ticks: ticks, label: label, inset: (0, 0), show-break: false, mode: mode, base: base |
| 235 | + min: min, max: max, ticks: ticks, label: label, inset: (0, 0), show-break: false, mode: mode, base: base, |
| 236 | + kind: "cartesian", |
236 | 237 | )
|
237 | 238 |
|
238 | 239 | // Format a tick value
|
|
509 | 510 | return axis
|
510 | 511 | }
|
511 | 512 |
|
| 513 | +// Transform a single value along a cartesian axis |
| 514 | +#let transform-cartesian(axis, v) = { |
| 515 | + let a = axis.origin |
| 516 | + let b = axis.target |
| 517 | + |
| 518 | + let length = vector.dist(a, b) - axis.inset.sum() |
| 519 | + let offset = axis.inset.at(0) |
| 520 | + |
| 521 | + let transform-func(n) = if axis.mode == "log" { |
| 522 | + calc.log(calc.max(n, util.float-epsilon), base: axis.base) |
| 523 | + } else { |
| 524 | + n |
| 525 | + } |
| 526 | + |
| 527 | + let factor = length / (transform-func(axis.max) - transform-func(axis.min)) |
| 528 | + return vector.scale( |
| 529 | + vector.norm(vector.sub(b, a)), |
| 530 | + (transform-func(v) - transform-func(axis.min)) * factor + offset) |
| 531 | +} |
| 532 | + |
512 | 533 | // Transform a single vector along a x, y and z axis
|
513 | 534 | //
|
514 |
| -// - size (vector): Coordinate system size |
515 |
| -// - x-axis (axis): X axis |
516 |
| -// - y-axis (axis): Y axis |
517 |
| -// - z-axis (axis): Z axis |
| 535 | +// - axes (list): List of axes |
518 | 536 | // - vec (vector): Input vector to transform
|
519 | 537 | // -> vector
|
520 |
| -#let transform-vec(size, x-axis, y-axis, z-axis, vec) = { |
521 |
| - let axes = (x-axis, y-axis) |
522 |
| - |
523 |
| - let (x, y,) = for (dim, axis) in axes.enumerate() { |
524 |
| - let s = size.at(dim) - axis.inset.sum() |
525 |
| - let o = axis.inset.at(0) |
| 538 | +#let transform-vec(axes, vec) = { |
| 539 | + let res = (0, 0, 0) |
| 540 | + for (dim, axis) in axes.enumerate() { |
| 541 | + let v = vec.at(dim, default: 0) |
526 | 542 |
|
527 |
| - let transform-func(n) = if axis.mode == "log" { |
528 |
| - calc.log(calc.max(n, util.float-epsilon), base: axis.base) |
| 543 | + if axis.kind == "cartesian" { |
| 544 | + res = vector.add(res, transform-cartesian(axis, v)) |
529 | 545 | } else {
|
530 |
| - n |
| 546 | + panic("Unknown axit type " + repr(axis.kind)) |
531 | 547 | }
|
532 |
| - |
533 |
| - let range = transform-func(axis.max) - transform-func(axis.min) |
534 |
| - |
535 |
| - let f = s / range |
536 |
| - ((transform-func(vec.at(dim)) - transform-func(axis.min)) * f + o,) |
537 | 548 | }
|
538 |
| - |
539 |
| - return (x, y, 0) |
| 549 | + return res |
540 | 550 | }
|
541 | 551 |
|
542 | 552 | // Draw inside viewport coordinates of two axes
|
543 | 553 | //
|
544 |
| -// - size (vector): Axis canvas size (relative to origin) |
545 |
| -// - x (axis): Horizontal axis |
546 |
| -// - y (axis): Vertical axis |
547 |
| -// - z (axis): Z axis |
| 554 | +// - axes (list): List of axes |
548 | 555 | // - name (string,none): Group name
|
549 |
| -#let axis-viewport(size, x, y, z, body, name: none) = { |
| 556 | +#let axis-viewport(axes, body, name: none) = { |
550 | 557 | draw.group(name: name, (ctx => {
|
551 | 558 | let transform = ctx.transform
|
552 | 559 |
|
|
559 | 566 | if "segments" in d {
|
560 | 567 | d.segments = d.segments.map(((kind, ..pts)) => {
|
561 | 568 | (kind, ..pts.map(pt => {
|
562 |
| - transform-vec(size, x, y, none, pt) |
| 569 | + transform-vec(axes, pt) |
563 | 570 | }))
|
564 | 571 | })
|
565 | 572 | }
|
566 | 573 | if "pos" in d {
|
567 |
| - d.pos = transform-vec(size, x, y, none, d.pos) |
| 574 | + d.pos = transform-vec(axes, d.pos) |
568 | 575 | }
|
569 | 576 | return d
|
570 | 577 | })
|
|
0 commit comments