Skip to content

Commit 6b847b9

Browse files
committed
Adds a Toggle for Inner Radius in Polygon tool (#3484)
1 parent e73e524 commit 6b847b9

File tree

4 files changed

+54
-29
lines changed

4 files changed

+54
-29
lines changed

editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/number_of_points_dial.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use glam::{DAffine2, DVec2};
1414
use graph_craft::document::NodeInput;
1515
use graph_craft::document::value::TaggedValue;
1616
use std::collections::VecDeque;
17-
use std::f64::consts::TAU;
17+
use std::f64::consts::{PI, TAU};
1818

1919
#[derive(Clone, Debug, Default, PartialEq)]
2020
pub enum NumberOfPointsDialState {
@@ -68,11 +68,12 @@ impl NumberOfPointsDial {
6868
}
6969

7070
// Polygon
71-
if let Some((sides, radius)) = extract_polygon_parameters(Some(layer), document) {
71+
if let Some((sides, radius, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) {
7272
let viewport = document.metadata().transform_to_viewport(layer);
7373
let center = viewport.transform_point2(DVec2::ZERO);
7474

75-
let point_on_max_radius = polygon_vertex_position(viewport, 0, sides, radius);
75+
let effective_radius = if is_inner_radius { radius / (PI / sides as f64).cos() } else { radius };
76+
let point_on_max_radius = polygon_vertex_position(viewport, 0, sides, effective_radius);
7677

7778
if mouse_position.distance(center) < NUMBER_OF_POINTS_DIAL_SPOKE_LENGTH && point_on_max_radius.distance(center) > GIZMO_HIDE_THRESHOLD {
7879
self.layer = Some(layer);
@@ -122,7 +123,7 @@ impl NumberOfPointsDial {
122123
}
123124

124125
// Polygon
125-
if let Some((sides, radius)) = extract_polygon_parameters(Some(layer), document) {
126+
if let Some((sides, radius, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) {
126127
let viewport = document.metadata().transform_to_viewport(layer);
127128
let center = viewport.transform_point2(DVec2::ZERO);
128129

@@ -131,10 +132,11 @@ impl NumberOfPointsDial {
131132
{
132133
return;
133134
}
134-
let point_on_max_radius = polygon_vertex_position(viewport, 0, sides, radius);
135+
let effective_radius = if is_inner_radius { radius / (PI / sides as f64).cos() } else { radius };
136+
let point_on_max_radius = polygon_vertex_position(viewport, 0, sides, effective_radius);
135137

136-
if inside_polygon(viewport, sides, radius, mouse_position) && point_on_max_radius.distance(center) > GIZMO_HIDE_THRESHOLD {
137-
self.draw_spokes(center, viewport, sides, radius, overlay_context);
138+
if inside_polygon(viewport, sides, effective_radius, mouse_position) && point_on_max_radius.distance(center) > GIZMO_HIDE_THRESHOLD {
139+
self.draw_spokes(center, viewport, sides, effective_radius, overlay_context);
138140
}
139141
}
140142
}
@@ -144,10 +146,12 @@ impl NumberOfPointsDial {
144146
};
145147

146148
// Get the star's greater radius or polygon's radius, as well as the number of sides
147-
let Some((sides, radius)) = extract_star_parameters(Some(layer), document)
148-
.map(|(sides, r1, r2)| (sides, r1.max(r2)))
149-
.or_else(|| extract_polygon_parameters(Some(layer), document))
150-
else {
149+
let Some((sides, radius)) = extract_star_parameters(Some(layer), document).map(|(sides, r1, r2)| (sides, r1.max(r2))).or_else(|| {
150+
extract_polygon_parameters(Some(layer), document).map(|(sides, radius, is_inner_radius)| {
151+
let effective_radius = if is_inner_radius { radius / (PI / sides as f64).cos() } else { radius };
152+
(sides, effective_radius)
153+
})
154+
}) else {
151155
return;
152156
};
153157

editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ impl PointRadiusHandle {
8686
}
8787

8888
// Draw the point handle gizmo for the polygon shape
89-
if let Some((sides, radius)) = extract_polygon_parameters(Some(layer), document) {
89+
if let Some((sides, radius, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) {
9090
let viewport = document.metadata().transform_to_viewport(layer);
91+
let effective_radius = if is_inner_radius { radius / (PI / sides as f64).cos() } else { radius };
9192

9293
for i in 0..sides {
93-
let point = polygon_vertex_position(viewport, i as i32, sides, radius);
94+
let point = polygon_vertex_position(viewport, i as i32, sides, effective_radius);
9495
let center = viewport.transform_point2(DVec2::ZERO);
9596

9697
// If the user zooms out such that shape is very small hide the gizmo
@@ -129,8 +130,9 @@ impl PointRadiusHandle {
129130
}
130131

131132
// Polygon
132-
if let Some((sides, radius)) = extract_polygon_parameters(Some(layer), document) {
133-
let point = polygon_vertex_position(viewport, self.point as i32, sides, radius);
133+
if let Some((sides, radius, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) {
134+
let effective_radius = if is_inner_radius { radius / (PI / sides as f64).cos() } else { radius };
135+
let point = polygon_vertex_position(viewport, self.point as i32, sides, effective_radius);
134136

135137
if matches!(&self.handle_state, PointRadiusHandleState::Hover) && (mouse_position - point).length() > 5. {
136138
self.update_state(PointRadiusHandleState::Inactive);
@@ -165,11 +167,12 @@ impl PointRadiusHandle {
165167
}
166168

167169
// Draw the point handle gizmo for the Polygon shape
168-
if let Some((sides, radius)) = extract_polygon_parameters(Some(layer), document) {
170+
if let Some((sides, radius, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) {
169171
let viewport = document.metadata().transform_to_viewport(layer);
172+
let effective_radius = if is_inner_radius { radius / (PI / sides as f64).cos() } else { radius };
170173

171174
for i in 0..sides {
172-
let point = polygon_vertex_position(viewport, i as i32, sides, radius);
175+
let point = polygon_vertex_position(viewport, i as i32, sides, effective_radius);
173176
let center = viewport.transform_point2(DVec2::ZERO);
174177

175178
// If the user zooms out such that shape is very small hide the gizmo
@@ -210,8 +213,9 @@ impl PointRadiusHandle {
210213
}
211214

212215
// Polygon
213-
if let Some((sides, radius)) = extract_polygon_parameters(Some(layer), document) {
214-
let point = polygon_vertex_position(viewport, self.point as i32, sides, radius);
216+
if let Some((sides, radius, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) {
217+
let effective_radius = if is_inner_radius { radius / (PI / sides as f64).cos() } else { radius };
218+
let point = polygon_vertex_position(viewport, self.point as i32, sides, effective_radius);
215219

216220
let Some(direction) = (point - center).try_normalize() else { return };
217221

@@ -419,17 +423,23 @@ impl PointRadiusHandle {
419423
};
420424

421425
let viewport_transform = document.network_interface.document_metadata().transform_to_viewport(layer);
422-
let center = viewport_transform.transform_point2(DVec2::ZERO);
426+
423427
let radius_index = self.radius_index;
424428

425429
let original_radius = self.initial_radius;
426430

427-
let delta = viewport_transform.inverse().transform_point2(input.mouse.position) - viewport_transform.inverse().transform_point2(drag_start);
428-
let radius = drag_start - center;
431+
let drag_start = viewport_transform.inverse().transform_point2(drag_start);
432+
let delta = viewport_transform.inverse().transform_point2(input.mouse.position) - drag_start;
433+
let radius = drag_start;
429434
let projection = delta.project_onto(radius);
430435
let sign = radius.dot(delta).signum();
431436

432437
let mut net_delta = projection.length() * sign * original_radius.signum();
438+
if let Some((sides, _, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) {
439+
if is_inner_radius {
440+
net_delta *= (PI / sides as f64).cos();
441+
}
442+
}
433443
let new_radius = original_radius + net_delta;
434444

435445
self.update_state(PointRadiusHandleState::Dragging);

editor/src/messages/tool/common_functionality/shapes/shape_utility.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,14 +245,16 @@ pub fn extract_star_parameters(layer: Option<LayerNodeIdentifier>, document: &Do
245245

246246
/// Extract the node input values of Polygon.
247247
/// Returns an option of (sides, radius).
248-
pub fn extract_polygon_parameters(layer: Option<LayerNodeIdentifier>, document: &DocumentMessageHandler) -> Option<(u32, f64)> {
248+
pub fn extract_polygon_parameters(layer: Option<LayerNodeIdentifier>, document: &DocumentMessageHandler) -> Option<(u32, f64, bool)> {
249249
let node_inputs = NodeGraphLayer::new(layer?, &document.network_interface).find_node_inputs("Regular Polygon")?;
250250

251-
let (Some(&TaggedValue::U32(n)), Some(&TaggedValue::F64(radius))) = (node_inputs.get(1)?.as_value(), node_inputs.get(2)?.as_value()) else {
251+
let (Some(&TaggedValue::U32(n)), Some(&TaggedValue::F64(radius)), Some(&TaggedValue::Bool(is_inner_radius))) =
252+
(node_inputs.get(1)?.as_value(), node_inputs.get(2)?.as_value(), node_inputs.get(3)?.as_value())
253+
else {
252254
return None;
253255
};
254256

255-
Some((n, radius))
257+
Some((n, radius, is_inner_radius))
256258
}
257259

258260
/// Extract the node input values of an arc.
@@ -349,14 +351,18 @@ pub fn star_outline(layer: Option<LayerNodeIdentifier>, document: &DocumentMessa
349351
/// Outlines the geometric shape made by polygon-node
350352
pub fn polygon_outline(layer: Option<LayerNodeIdentifier>, document: &DocumentMessageHandler, overlay_context: &mut OverlayContext) {
351353
let Some(layer) = layer else { return };
352-
let Some((sides, radius)) = extract_polygon_parameters(Some(layer), document) else {
354+
let Some((sides, radius, is_inner_radius)) = extract_polygon_parameters(Some(layer), document) else {
353355
return;
354356
};
355357

356358
let viewport = document.metadata().transform_to_viewport(layer);
357359

358360
let points = sides as u64;
359-
let radius: f64 = radius * 2.;
361+
let radius: f64 = if is_inner_radius {
362+
(radius * 2.) / (std::f64::consts::PI / points as f64).cos()
363+
} else {
364+
radius * 2.
365+
};
360366

361367
let subpath: Vec<ClickTargetType> = vec![ClickTargetType::Subpath(Subpath::new_regular_polygon(DVec2::splat(-radius), points, radius))];
362368

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,15 @@ fn regular_polygon<T: AsU64>(
157157
#[unit(" px")]
158158
#[default(50)]
159159
radius: f64,
160+
#[default(false)] is_inner_radius: bool,
160161
) -> Table<Vector> {
161162
let points = sides.as_u64();
162-
let radius: f64 = radius * 2.;
163-
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_regular_polygon(DVec2::splat(-radius), points, radius)))
163+
let effective_radius = if is_inner_radius {
164+
radius * 2. / (std::f64::consts::PI / points as f64).cos()
165+
} else {
166+
radius * 2.
167+
};
168+
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_regular_polygon(DVec2::splat(-effective_radius), points, effective_radius)))
164169
}
165170

166171
/// Generates an n-pointed star shape with inner and outer points at chosen radii from the center.

0 commit comments

Comments
 (0)