mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Add regular polygons to visualize (#1215)
This commit is contained in:
parent
bcab770524
commit
5c1db0c4b8
@ -1,3 +1,5 @@
|
|||||||
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// A closed polygon.
|
/// A closed polygon.
|
||||||
@ -19,6 +21,10 @@ use crate::prelude::*;
|
|||||||
/// Display: Polygon
|
/// Display: Polygon
|
||||||
/// Category: visualize
|
/// Category: visualize
|
||||||
#[element(Layout)]
|
#[element(Layout)]
|
||||||
|
#[scope(
|
||||||
|
scope.define("regular", polygon_regular_func());
|
||||||
|
scope
|
||||||
|
)]
|
||||||
pub struct PolygonElem {
|
pub struct PolygonElem {
|
||||||
/// How to fill the polygon. See the
|
/// How to fill the polygon. See the
|
||||||
/// [rectangle's documentation]($func/rect.fill) for more details.
|
/// [rectangle's documentation]($func/rect.fill) for more details.
|
||||||
@ -91,3 +97,71 @@ impl Layout for PolygonElem {
|
|||||||
Ok(Fragment::frame(frame))
|
Ok(Fragment::frame(frame))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A regular polygon, defined by its size and number of vertices.
|
||||||
|
///
|
||||||
|
/// ## Example { #example }
|
||||||
|
/// ```example
|
||||||
|
/// #polygon.regular(
|
||||||
|
/// fill: blue.lighten(80%),
|
||||||
|
/// stroke: blue,
|
||||||
|
/// size: 30pt,
|
||||||
|
/// vertices: 3,
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Display: Regular Polygon
|
||||||
|
/// Category: visualize
|
||||||
|
#[func]
|
||||||
|
pub fn polygon_regular(
|
||||||
|
/// How to fill the polygon. See the general
|
||||||
|
/// [polygon's documentation]($func/polygon.fill) for more details.
|
||||||
|
#[named]
|
||||||
|
fill: Option<Option<Paint>>,
|
||||||
|
|
||||||
|
/// How to stroke the polygon. See the general
|
||||||
|
/// [polygon's documentation]($func/polygon.stroke) for more details.
|
||||||
|
#[named]
|
||||||
|
stroke: Option<Smart<Option<PartialStroke>>>,
|
||||||
|
|
||||||
|
/// The diameter of the circumcircle of the regular polygon (https://en.wikipedia.org/wiki/Circumcircle).
|
||||||
|
#[named]
|
||||||
|
#[default(Em::one().into())]
|
||||||
|
size: Length,
|
||||||
|
|
||||||
|
/// The number of vertices in the polygon.
|
||||||
|
#[named]
|
||||||
|
#[default(3)]
|
||||||
|
vertices: u64,
|
||||||
|
) -> Content {
|
||||||
|
let radius = size / 2.0;
|
||||||
|
let angle = |i: f64| {
|
||||||
|
2.0 * PI * i / (vertices as f64) + PI * (1.0 / 2.0 - 1.0 / vertices as f64)
|
||||||
|
};
|
||||||
|
let (horizontal_offset, vertical_offset) = (0..=vertices)
|
||||||
|
.map(|v| {
|
||||||
|
(
|
||||||
|
(radius * angle(v as f64).cos()) + radius,
|
||||||
|
(radius * angle(v as f64).sin()) + radius,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.fold((radius, radius), |(min_x, min_y), (v_x, v_y)| {
|
||||||
|
(if min_x < v_x { min_x } else { v_x }, if min_y < v_y { min_y } else { v_y })
|
||||||
|
});
|
||||||
|
let vertices = (0..=vertices)
|
||||||
|
.map(|v| {
|
||||||
|
let x = (radius * angle(v as f64).cos()) + radius - horizontal_offset;
|
||||||
|
let y = (radius * angle(v as f64).sin()) + radius - vertical_offset;
|
||||||
|
Axes::new(x, y).map(Rel::from)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut elem = PolygonElem::new(vertices);
|
||||||
|
if let Some(fill) = fill {
|
||||||
|
elem.push_fill(fill);
|
||||||
|
}
|
||||||
|
if let Some(stroke) = stroke {
|
||||||
|
elem.push_stroke(stroke);
|
||||||
|
}
|
||||||
|
elem.pack()
|
||||||
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.8 KiB |
@ -8,6 +8,7 @@
|
|||||||
#polygon()
|
#polygon()
|
||||||
#polygon((0em, 0pt))
|
#polygon((0em, 0pt))
|
||||||
#polygon((0pt, 0pt), (10pt, 0pt))
|
#polygon((0pt, 0pt), (10pt, 0pt))
|
||||||
|
#polygon.regular(size: 0pt, vertices: 9)
|
||||||
|
|
||||||
#polygon((5pt, 0pt), (0pt, 10pt), (10pt, 10pt))
|
#polygon((5pt, 0pt), (0pt, 10pt), (10pt, 10pt))
|
||||||
#polygon(
|
#polygon(
|
||||||
@ -27,6 +28,9 @@
|
|||||||
// Self-intersections
|
// Self-intersections
|
||||||
#polygon((0pt, 10pt), (30pt, 20pt), (0pt, 30pt), (20pt, 0pt), (20pt, 35pt))
|
#polygon((0pt, 10pt), (30pt, 20pt), (0pt, 30pt), (20pt, 0pt), (20pt, 35pt))
|
||||||
|
|
||||||
|
// Regular polygon; should have equal side lengths
|
||||||
|
#for k in range(3, 9) {polygon.regular(size: 30pt, vertices: k,)}
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 10-17 point array must contain exactly two entries
|
// Error: 10-17 point array must contain exactly two entries
|
||||||
#polygon((50pt,))
|
#polygon((50pt,))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user