Skip to content

Commit

Permalink
Merge pull request #2375 from hannobraun/circle
Browse files Browse the repository at this point in the history
Build circle-cycle out of multiple arcs
  • Loading branch information
hannobraun authored Jun 7, 2024
2 parents de041b3 + 57814ac commit 9033890
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 34 deletions.
42 changes: 37 additions & 5 deletions crates/fj-core/src/operations/build/cycle.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use fj_math::{Point, Scalar};
use fj_math::{Point, Scalar, Vector};
use itertools::Itertools;

use crate::{
operations::{build::BuildHalfEdge, update::UpdateCycle},
operations::{build::BuildHalfEdge, insert::Insert, update::UpdateCycle},
storage::Handle,
topology::{Cycle, HalfEdge, Surface},
Core,
Expand All @@ -19,15 +19,47 @@ pub trait BuildCycle {
Cycle::new([])
}

/// Build a circle
/// # Build a circle
///
/// This circle is built out of 4 distinct arcs.
///
/// ## Implementation Note
///
/// The cycle can't be built out of a single half-edge. That would be
/// invalid although there's not validation check to document and enforce
/// that yet. Please refer to the following issue for more information:
/// <https://github.com/hannobraun/fornjot/issues/2374>
///
/// The cycle is built out of 4 arcs specifically, because that's easier to
/// implement than three, and building it out of two creates geometry that
/// the cycle winding code can't handle right now. The following issue has
/// more information on the cycle winding problems:
/// <https://github.com/hannobraun/fornjot/issues/2130>
fn circle(
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
surface: Handle<Surface>,
core: &mut Core,
) -> Cycle {
let circle = HalfEdge::circle(center, radius, surface, core);
Cycle::empty().add_half_edges([circle], core)
let center = center.into();
let radius = radius.into();

let radius_right = Vector::from([radius, Scalar::ZERO]);
let radius_up = Vector::from([Scalar::ZERO, radius]);

let a = center + radius_right;
let b = center + radius_up;
let c = center - radius_right;
let d = center - radius_up;

let angle = Scalar::TAU / 4.;

let ab = HalfEdge::arc(a, b, angle, surface.clone(), core).insert(core);
let bc = HalfEdge::arc(b, c, angle, surface.clone(), core).insert(core);
let cd = HalfEdge::arc(c, d, angle, surface.clone(), core).insert(core);
let da = HalfEdge::arc(d, a, angle, surface.clone(), core).insert(core);

Cycle::empty().add_half_edges([ab, bc, cd, da], core)
}

/// Build a polygon
Expand Down
29 changes: 0 additions & 29 deletions crates/fj-core/src/operations/build/half_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,35 +81,6 @@ pub trait BuildHalfEdge {
half_edge
}

/// Create a circle
fn circle(
center: impl Into<Point<2>>,
radius: impl Into<Scalar>,
surface: Handle<Surface>,
core: &mut Core,
) -> Handle<HalfEdge> {
let path = SurfacePath::circle_from_center_and_radius(center, radius);
let boundary =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));

let half_edge = HalfEdge::unjoined(core).insert(core);

core.layers.geometry.define_curve(
half_edge.curve().clone(),
surface,
LocalCurveGeom { path },
);
core.layers.geometry.define_half_edge(
half_edge.clone(),
HalfEdgeGeom {
path,
boundary: boundary.into(),
},
);

half_edge
}

/// Create a line segment
fn line_segment(
points_surface: [impl Into<Point<2>>; 2],
Expand Down

0 comments on commit 9033890

Please sign in to comment.