Skip to content

Commit e01b7c1

Browse files
committed
New version of Togo
1 parent 7da4374 commit e01b7c1

9 files changed

Lines changed: 39 additions & 37 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## [0.2.0] - 2025-10-21
4+
- update with the new Togo version
5+
36
## [0.1.0] - 2025-09-24
47
- Implemented graph-based cycle detection algorithm
58
- Added arc reconnection system for offset segments

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "offroad"
3-
version = "0.1.2"
3+
version = "0.2.0"
44
description = "2D offsetting for arc polylines/polygons."
55
rust-version = "1.88"
66
edition = "2024"
@@ -15,8 +15,8 @@ readme = "README.md"
1515

1616

1717
[dependencies]
18-
togo = "0.4.1"
19-
robust = "1.2.0"
18+
togo = "0.5"
19+
robust = "1.2"
2020

2121
[lib]
2222
crate-type = ["lib"]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ To use the Offroad library in your project, add the following to your `Cargo.tom
99

1010
```toml
1111
[dependencies]
12-
offroad = "0.1.2"
12+
offroad = "0.2"
1313
```
1414

1515
## 2D offsetting for arc polylines/polygons

examples/offset_arcline.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ fn main() {
1111
// Show final offset arclines in SVG output
1212
cfg.svg_final = true;
1313

14-
let arc0 = arc_circle_parametrization(point(40.0, 100.0), point(140.0, 200.0), 0.0);
15-
let arc1 = arc_circle_parametrization(point(140.0, 200.0), point(240.0, 100.0), 0.5);
16-
let arc2 = arc_circle_parametrization(point(240.0, 100.0), point(40.0, 100.0), 1.3);
14+
let arc0 = arc_from_bulge(point(40.0, 100.0), point(140.0, 200.0), 0.0);
15+
let arc1 = arc_from_bulge(point(140.0, 200.0), point(240.0, 100.0), 0.5);
16+
let arc2 = arc_from_bulge(point(240.0, 100.0), point(40.0, 100.0), 1.3);
1717
let arcs_orig = vec![arc0, arc1, arc2];
1818

1919
// Translate to fit in the SVG viewport

src/graph/find_cycles.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -447,16 +447,15 @@ pub fn find_non_intersecting_cycles(arcs: &[Arc]) -> Vec<Vec<Arc>> {
447447

448448
#[test]
449449
fn test_double_edges() {
450-
// Two arcs between the same points (like two semicircles of a circle)
451-
// Use arc_circle_parametrization to create proper arcs
450+
// Use arc_from_bulge to create proper arcs
452451
let p1 = point(0.0, 0.0);
453452
let p2 = point(2.0, 0.0);
454453
let bulge1 = 1.0; // Semicircle bulge
455454
let bulge2 = 1.0; // Another semicircle bulge (same direction, forms full circle)
456455

457456
let arcs = vec![
458-
arc_circle_parametrization(p1, p2, bulge1),
459-
arc_circle_parametrization(p2, p1, bulge2),
457+
arc_from_bulge(p1, p2, bulge1),
458+
arc_from_bulge(p2, p1, bulge2),
460459
];
461460

462461
let result = find_non_intersecting_cycles(&arcs);
@@ -494,7 +493,7 @@ pub fn find_non_intersecting_cycles(arcs: &[Arc]) -> Vec<Vec<Arc>> {
494493
// Combine line segments and curved arcs in a cycle
495494
let arcs = vec![
496495
arcseg(point(0.0, 0.0), point(1.0, 0.0)), // Line segment
497-
arc_circle_parametrization(point(1.0, 0.0), point(0.0, 1.0), 0.5), // Curved arc
496+
arc_from_bulge(point(1.0, 0.0), point(0.0, 1.0), 0.5), // Curved arc
498497
arcseg(point(0.0, 1.0), point(0.0, 0.0)), // Line segment
499498
];
500499

src/offset.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ pub fn arcs_to_polylines_single(arcs: &Vec<Arc>) -> Polyline {
262262
if arc.is_seg() {
263263
(arc.a, arc.b, 0.0)
264264
} else {
265-
let bulge = arc_bulge_from_points(arc.a, arc.b, arc.c, arc.r);
265+
let bulge = bulge_from_arc(arc.a, arc.b, arc.c, arc.r);
266266
(arc.a, arc.b, bulge)
267267
}
268268
} else {
@@ -277,7 +277,7 @@ pub fn arcs_to_polylines_single(arcs: &Vec<Arc>) -> Polyline {
277277
if arc.is_seg() {
278278
(arc.a, arc.b, 0.0)
279279
} else {
280-
let bulge = arc_bulge_from_points(arc.a, arc.b, arc.c, arc.r);
280+
let bulge = bulge_from_arc(arc.a, arc.b, arc.c, arc.r);
281281
(arc.a, arc.b, bulge)
282282
}
283283
} else {
@@ -286,7 +286,7 @@ pub fn arcs_to_polylines_single(arcs: &Vec<Arc>) -> Polyline {
286286
(arc.b, arc.a, 0.0)
287287
} else {
288288
// For reversed arc, we need to negate the bulge
289-
let forward_bulge = arc_bulge_from_points(arc.a, arc.b, arc.c, arc.r);
289+
let forward_bulge = bulge_from_arc(arc.a, arc.b, arc.c, arc.r);
290290
(arc.b, arc.a, -forward_bulge)
291291
}
292292
}
@@ -310,7 +310,7 @@ mod test_arcs_to_polylines {
310310
// First arc: from (0,0) to (1,0) - line segment
311311
arcseg(point(0.0, 0.0), point(1.0, 0.0)),
312312
// Second arc: from (1,0) to (0,1) - quarter circle
313-
arc_circle_parametrization(point(1.0, 0.0), point(0.0, 1.0), 1.0),
313+
arc_from_bulge(point(1.0, 0.0), point(0.0, 1.0), 1.0),
314314
// Third arc: from (0,1) to (0,0) - line segment (completing the loop)
315315
arcseg(point(0.0, 1.0), point(0.0, 0.0)),
316316
];
@@ -342,7 +342,7 @@ mod test_arcs_to_polylines {
342342
arcseg(point(0.0, 0.0), point(1.0, 0.0)),
343343
// Second arc: reversed orientation (from (0,1) to (1,0) instead of (1,0) to (0,1))
344344
// This should be detected and corrected
345-
arc_circle_parametrization(point(0.0, 1.0), point(1.0, 0.0), 1.0),
345+
arc_from_bulge(point(0.0, 1.0), point(1.0, 0.0), 1.0),
346346
];
347347

348348
// Convert to polyline
@@ -2035,12 +2035,12 @@ fn polyline_to_arcs_single(pline: &Polyline) -> Vec<Arc> {
20352035
let mut arcs = Vec::with_capacity(pline.len() + 1);
20362036
let last = pline.len() - 1;
20372037
for i in 0..last {
2038-
let arc = arc_circle_parametrization(pline[i].p, pline[i + 1].p, pline[i].b);
2038+
let arc = arc_from_bulge(pline[i].p, pline[i + 1].p, pline[i].b);
20392039
arcs.push(arc);
20402040
}
20412041
// last segment
20422042
let arc =
2043-
arc_circle_parametrization(pline.last().unwrap().p, pline[0].p, pline.last().unwrap().b);
2043+
arc_from_bulge(pline.last().unwrap().p, pline[0].p, pline.last().unwrap().b);
20442044
arcs.push(arc);
20452045
arcs
20462046
}

src/offset_connect_raw.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,8 @@ mod test_offset_connect_raw_single {
396396
#[test]
397397
fn test_arc_segments() {
398398
// Test with actual arc segments (not just lines) using valid parametrization
399-
let arc1 = arc_circle_parametrization(point(0.0, 0.0), point(2.0, 0.0), 0.3);
400-
let arc2 = arc_circle_parametrization(point(3.0, 0.0), point(5.0, 0.0), -0.3);
399+
let arc1 = arc_from_bulge(point(0.0, 0.0), point(2.0, 0.0), 0.3);
400+
let arc2 = arc_from_bulge(point(3.0, 0.0), point(5.0, 0.0), -0.3);
401401

402402
// Verify arcs are valid
403403
assert!(arc1.is_valid(1e-10));
@@ -546,8 +546,8 @@ mod test_offset_connect_raw_single {
546546
#[test]
547547
fn test_realistic_curved_segments_with_gaps() {
548548
// Test with actual arc segments using valid parametrization
549-
let arc1 = arc_circle_parametrization(point(0.0, 0.0), point(2.0, 2.0), 0.5);
550-
let arc2 = arc_circle_parametrization(point(4.0, 2.0), point(6.0, 0.0), -0.5);
549+
let arc1 = arc_from_bulge(point(0.0, 0.0), point(2.0, 2.0), 0.5);
550+
let arc2 = arc_from_bulge(point(4.0, 2.0), point(6.0, 0.0), -0.5);
551551

552552
// Verify arcs are geometrically valid
553553
assert!(arc1.is_valid(1e-10));
@@ -601,8 +601,8 @@ mod test_offset_connect_raw_single {
601601
#[test]
602602
fn test_all_g_value_combinations() {
603603
// Test various g values with curved arcs (not line segments)
604-
let arc1 = arc_circle_parametrization(point(0.0, 0.0), point(1.0, 0.0), 0.5);
605-
let arc2 = arc_circle_parametrization(point(2.0, 0.0), point(3.0, 0.0), 0.5);
604+
let arc1 = arc_from_bulge(point(0.0, 0.0), point(1.0, 0.0), 0.5);
605+
let arc2 = arc_from_bulge(point(2.0, 0.0), point(3.0, 0.0), 0.5);
606606

607607
// Verify arcs are geometrically valid
608608
assert!(arc1.is_valid(1e-10));

src/offset_polyline_raw.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub fn poly_to_raws_single(pline: &Polyline) -> Vec<OffsetRaw> {
9595
//let last = pline.len() - 1;
9696
for i in 0..pline.len() - 1 {
9797
let bulge = pline[i].b;
98-
let seg = arc_circle_parametrization(pline[i].p, pline[i + 1].p, bulge);
98+
let seg = arc_from_bulge(pline[i].p, pline[i + 1].p, bulge);
9999
let check = seg.is_valid(EPS_COLLAPSED);
100100
if !check {
101101
continue;
@@ -110,7 +110,7 @@ pub fn poly_to_raws_single(pline: &Polyline) -> Vec<OffsetRaw> {
110110
}
111111
// last segment
112112
let bulge = pline.last().unwrap().b;
113-
let seg = arc_circle_parametrization(pline.last().unwrap().p, pline[0].p, bulge);
113+
let seg = arc_from_bulge(pline.last().unwrap().p, pline[0].p, bulge);
114114
let check = seg.is_valid(EPS_COLLAPSED);
115115
if check {
116116
let orig = if bulge < ZERO { seg.a } else { seg.b };
@@ -143,7 +143,7 @@ pub fn arcs_to_raws_single(arcs: &Arcline) -> Vec<OffsetRaw> {
143143
if !check {
144144
continue;
145145
}
146-
let bulge = arc_bulge_from_points(seg.a, seg.b, seg.c, seg.r);
146+
let bulge = bulge_from_arc(seg.a, seg.b, seg.c, seg.r);
147147
let orig = if bulge < ZERO { seg.a } else { seg.b };
148148
let off = OffsetRaw {
149149
arc: seg,
@@ -156,7 +156,7 @@ pub fn arcs_to_raws_single(arcs: &Arcline) -> Vec<OffsetRaw> {
156156
let seg = arcs.last().unwrap();
157157
let check = seg.is_valid(EPS_COLLAPSED);
158158
if check {
159-
let bulge = arc_bulge_from_points(seg.a, seg.b, seg.c, seg.r);
159+
let bulge = bulge_from_arc(seg.a, seg.b, seg.c, seg.r);
160160
let orig = if bulge < ZERO { seg.a } else { seg.b };
161161
let off = OffsetRaw {
162162
arc: *seg,
@@ -199,15 +199,15 @@ mod test_offset_polyline_raw {
199199

200200
#[test]
201201
fn test_new() {
202-
let arc = arc_circle_parametrization(point(1.0, 2.0), point(3.0, 4.0), 3.3);
202+
let arc = arc_from_bulge(point(1.0, 2.0), point(3.0, 4.0), 3.3);
203203
let o0 = offsetraw(arc, point(5.0, 6.0), 3.3);
204204
let o1 = offsetraw(arc, point(5.0, 6.0), 3.3);
205205
assert_eq!(o0, o1);
206206
}
207207

208208
#[test]
209209
fn test_display_01() {
210-
let arc = arc_circle_parametrization(point(0.0, 0.0), point(2.0, 2.0), 1.0);
210+
let arc = arc_from_bulge(point(0.0, 0.0), point(2.0, 2.0), 1.0);
211211
let o0 = offsetraw(arc, point(5.0, 6.0), 3.3);
212212
assert_eq!(
213213
"[[[0.00000000000000000000, 0.00000000000000000000], [2.00000000000000000000, 2.00000000000000000000], [1.00000000000000000000, 1.00000000000000000000], 1.41421356237309514547], [5.00000000000000000000, 6.00000000000000000000], 3.3]",
@@ -217,7 +217,7 @@ mod test_offset_polyline_raw {
217217

218218
#[test]
219219
fn test_display_02() {
220-
let arc = arc_circle_parametrization(point(1.0, 2.0), point(3.0, 4.0), 3.3);
220+
let arc = arc_from_bulge(point(1.0, 2.0), point(3.0, 4.0), 3.3);
221221
let o0 = offsetraw(arc, point(5.0, 6.0), 3.3);
222222
assert_eq!(
223223
"[[[1.00000000000000000000, 2.00000000000000000000], [3.00000000000000000000, 4.00000000000000000000], [3.49848484848484808651, 1.50151515151515169144], 2.54772716009334887488], [5.00000000000000000000, 6.00000000000000000000], 3.3]",
@@ -297,8 +297,8 @@ mod test_offset_polyline_raw {
297297

298298
#[test]
299299
#[ignore = "svg output"]
300-
fn test_arc_circle_parametrization_plinearc_svg() {
301-
let arc0 = arc_circle_parametrization(
300+
fn test_arc_from_bulge_plinearc_svg() {
301+
let arc0 = arc_from_bulge(
302302
point(-52.0, 250.0),
303303
point(-23.429621235520095, 204.88318696736243),
304304
-0.6068148963145962,

0 commit comments

Comments
 (0)