• Stars
    star
    112
  • Rank 312,240 (Top 7 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created about 4 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A spline for interactive 2D curve design

A spline for interactive curve design.

This crate implements a new spline designed and optimized for interactive design of 2D curves. A major motivation is fonts, but it can be used in other domains.

The work builds on previous iterations, notably the Spiro spline, and then another research spline.

Hyperbeziers

The major innovation of this spline is the "hyperbezier" curve family. Like cubic Béziers and the Spiro curve, it is a four-parameter curve family. In fact, it's closely based on Spiro and there is significant overlap of the parameter space, including Euler spirals.

There is a significant difference, however. In the Spiro curve family, curvature is bounded, so it is not capable of cusp-like behavior. Rather, when "pushed," Spiro tends to wiggly, Shmoo-like shapes. Béziers are of course capable of high curvature regions, as are elastica when placed under very high tension.

A good way to parametrize the hyperbezier is by tangent angle and "tension," which correlates strongly with curvature at the endpoint. At low tension, the hyperbezier is equivalent to the Spiro curve. A natural tension value produces the Euler spiral (curvature is a linear function of arclength). But for higher tension values, a different function takes over, which approaches a cusp at the endpoint as tension increases.

Unlike Béziers, the cusp happens only at the endpoint. Curvature maxima in the interior of a curve are ugly. With the hyperbezier, if the designer wants a sharp curvature maximum, simply place an on-curve point there.

A particular strength of the hyperbezier is smooth (G2-continuous) transitions from straight to curved sections. The hyperbezier is capable (unlike a cubic Bézier) of an S-shaped curve with zero curvature at both ends. It's also capable of a wide range of Euler spiral like behavior where one end has zero curvature and the other is a nice rounded shape (in the general case a designer would use at least two Béziers to create this effect).

The name "hyperbezier" clearly references its roots in the cubic Bézier, and the "hyper" part is a reference to the fact that the Euler spiral, an important section of its parameter space, is an instance of the Hypergeometric function.

Focus on UX

A persistent challenge with spline-based curve design is getting the UX right. Bézier curves are not easy to master, but the pen tool has become highly refined over time, and is an extremely productive interface for designers. A major motivation for this work is to retain the good parts of the Bézier UX.

In particular, the "control handle" maps to hyperbezier parameters in a natural, intuitive way. The tangent angle is obvious, and tension similarly dependent on the length of the control arm. So it's completely valid to use hyperbeziers simply as a drop-in replacement for Béziers.

The intended UX for use as an interpolating spline is simply to designate a control point as "auto." As is traditional, the spline solver solves these for G2 continuity. Where the tension is a free parameter (which generally happens when there is an "auto" point on either side of an on-curve point), it is assigned a reasonable default, in particular the Euler spiral value for small to medium deviations, and a value similar to the research spline as the deviation increases.

To further refine a curve, the designer can click on an auto point and drag it to the desired location. That gesture enforces tangents at extrema, and in general allows for fine tuning of tension, for example to make quadrants more superelliptical (a strength of Bézier editing and a relative weakness of Spiro).

Note: as of this release, the interpolating spline is still work in progress.

More Repositories

1

druid

A data-first Rust-native UI design toolkit.
Rust
9,543
star
2

xilem

An experimental Rust native UI framework
Rust
3,444
star
3

vello

A GPU compute-centric 2D renderer.
Rust
2,315
star
4

piet

An abstraction for 2D graphics.
Rust
1,251
star
5

runebender

A font editor written in Rust.
Rust
762
star
6

kurbo

A Rust library for manipulating curves
Rust
698
star
7

masonry

Rust UI design toolkit - moved.
Rust
405
star
8

skribo

A Rust library for low-level text layout.
Rust
325
star
9

glazier

Deprecated Rust Window Creation Library
Rust
209
star
10

parley

Rich text layout library
Rust
197
star
11

piet-metal

Experimental Metal-based GPU renderer for piet 2D graphics.
Rust
140
star
12

bevy_vello

An integration to render with Vello in Bevy game engine.
Rust
117
star
13

druid-widget-nursery

A place where Druid widgets come to mature before moving to the Druid repo.
Rust
87
star
14

velato

An integration to parse and render Lottie with Vello.
Rust
71
star
15

norad

Rust crate for working with Unified Font Object files
Rust
43
star
16

rbf-interp

An implementation of Radial Basis Function multidimensional interpolation
Rust
35
star
17

gpu-stroke-expansion-paper

Rust
35
star
18

2d.graphics

Repo for an ideational book on 2D graphics, plus tools to make images
26
star
19

peniko

Primitive types for styling vector graphics.
Rust
22
star
20

vello_svg

An integration to render SVG files with Vello.
Rust
15
star
21

wiki

Wiki and documentation for 2D graphics projects
9
star
22

android_trace

Support for Android NDK Tracing in Rust
Rust
6
star
23

rfcs

Suggestions for major changes to the linebender ecosystem
6
star
24

linebender.github.io

Main webpage for linebender org
SCSS
5
star
25

interpoli

Rust
3
star
26

runebender.app

Ruby
2
star
27

piet-snapshots

Data for snapshot testing of piet backends
2
star