Skip to content

Commit 3a97982

Browse files
committed
init
1 parent bd97c15 commit 3a97982

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

editor/src/messages/portfolio/document/node_graph/node_properties.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub(crate) fn property_from_type(
124124
Some("Percentage") => number_widget(document_node, node_id, index, name, number_input.percentage().min(min(0.)).max(max(100.)), true).into(),
125125
Some("SignedPercentage") => number_widget(document_node, node_id, index, name, number_input.percentage().min(min(-100.)).max(max(100.)), true).into(),
126126
Some("Angle") => number_widget(document_node, node_id, index, name, number_input.mode_range().min(min(-180.)).max(max(180.)).unit("°"), true).into(),
127+
Some("AngularDistance") => number_widget(document_node, node_id, index, name, number_input.mode_range().min(min(0.)).max(max(360.)).unit("°"), true).into(),
127128
Some("PixelLength") => number_widget(document_node, node_id, index, name, number_input.min(min(0.)).unit(" px"), true).into(),
128129
Some("Length") => number_widget(document_node, node_id, index, name, number_input.min(min(0.)), true).into(),
129130
Some("Fraction") => number_widget(document_node, node_id, index, name, number_input.min(min(0.)).max(max(1.)), true).into(),

libraries/bezier-rs/src/subpath/core.rs

+33
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,39 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
293293
Self::new(manipulator_groups, true)
294294
}
295295

296+
/// Constructs an arc by a `radius`, `angle_start` and `angle_size`. Angles must be in radians.
297+
pub fn new_arc(radius: f64, angle_start: f64, angle_size: f64) -> Self {
298+
let center = DVec2::new(0., 0.);
299+
let segments = (angle_size.abs() / (std::f64::consts::PI / 4.)).ceil() as usize;
300+
let step = angle_size / segments as f64;
301+
let half_step = step / 2.;
302+
let factor = 4. / 3. * half_step.sin() / (1. + half_step.cos());
303+
304+
let mut manipulator_groups = Vec::with_capacity(segments);
305+
let mut prev_in_handle = None;
306+
let mut prev_end = DVec2::new(0., 0.);
307+
308+
for i in 0..segments {
309+
let start_angle = angle_start + step * i as f64;
310+
let end_angle = start_angle + step;
311+
let start_vec = DVec2::from_angle(start_angle);
312+
let end_vec = DVec2::from_angle(end_angle);
313+
314+
let start = center + radius * start_vec;
315+
let end = center + radius * end_vec;
316+
317+
let handle_start = start + start_vec.perp() * radius * factor;
318+
let handle_end = end - end_vec.perp() * radius * factor;
319+
320+
manipulator_groups.push(ManipulatorGroup::new(start, prev_in_handle, Some(handle_start)));
321+
prev_in_handle = Some(handle_end);
322+
prev_end = end;
323+
}
324+
manipulator_groups.push(ManipulatorGroup::new(prev_end, prev_in_handle, None));
325+
326+
Self::new(manipulator_groups, false)
327+
}
328+
296329
/// Constructs a regular polygon (ngon). Based on `sides` and `radius`, which is the distance from the center to any vertex.
297330
pub fn new_regular_polygon(center: DVec2, sides: u64, radius: f64) -> Self {
298331
let angle_increment = std::f64::consts::TAU / (sides as f64);

node-graph/gcore/src/registry.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub mod types {
1212
pub type Percentage = f64;
1313
/// -180° - 180°
1414
pub type Angle = f64;
15+
/// 0° - 360°
16+
pub type AngularDistance = f64;
1517
/// -100% - 100%
1618
pub type SignedPercentage = f64;
1719
/// Non negative integer, px unit

node-graph/gcore/src/vector/generator_nodes.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::Ctx;
2+
use crate::registry::types::{Angle, AngularDistance};
23
use crate::vector::{HandleId, VectorData, VectorDataTable};
34
use bezier_rs::Subpath;
45
use glam::DVec2;
@@ -38,6 +39,15 @@ fn circle(_: impl Ctx, _primary: (), #[default(50.)] radius: f64) -> VectorDataT
3839
VectorDataTable::new(VectorData::from_subpath(Subpath::new_ellipse(DVec2::splat(-radius), DVec2::splat(radius))))
3940
}
4041

42+
#[node_macro::node(category("Vector: Shape"))]
43+
fn arc(_: impl Ctx, _primary: (), #[default(50.)] radius: f64, start_angle: Angle, #[default(90.)] angle_size: AngularDistance) -> VectorDataTable {
44+
VectorDataTable::new(VectorData::from_subpath(Subpath::new_arc(
45+
radius,
46+
start_angle / 360. * std::f64::consts::TAU,
47+
angle_size / 360. * std::f64::consts::TAU,
48+
)))
49+
}
50+
4151
#[node_macro::node(category("Vector: Shape"))]
4252
fn ellipse(_: impl Ctx, _primary: (), #[default(50)] radius_x: f64, #[default(25)] radius_y: f64) -> VectorDataTable {
4353
let radius = DVec2::new(radius_x, radius_y);

0 commit comments

Comments
 (0)