Giter Club home page Giter Club logo

bezier.dart's Introduction

bezier.dart is a simple open-source Dart library for handling 2D Bézier curve math.

The library was developed, documented, and published by Aaron Barrett and Isaac Barrett. It is based heavily on the work of Pomax, including his excellent Primer on Bézier Curves and his original JavaScript library, Bezier.js.

We're trying to design bezier.dart to be both platform independent and context independent. You can run the library anywhere you can run Dart: in a web browser, in a Flutter application, server side, and beyond.

For live examples of the library's API, see the project page at dartographer.com/bezier.

Features

  • Supports both quadratic and cubic two dimensional Bézier curves
  • Calculate the coordinates of a point at any parameter value t along a curve
  • Derivative and normal values at any t parameter value
  • Accurate length approximations (using the Legendre-Gauss quadrature algorithm)
  • Split a curve into equivalent subcurves between any t parameter values
  • Find the extrema of a curve on both the x and y axes
  • Calculate the bounding box for a curve
  • Given any curve, derive a new curve, offset from the original curve along the normals at a given distance
  • Calculate the positions of a curve's intersections with itself, with another curve, or with a line segment
  • Find points evenly spaced along the arc length of a curve
  • Heavily documented and tested
  • Straightforward, readable code

Getting Started

  1. Add the following to your project's pubspec.yaml and run pub get.
dependencies:
  bezier: any
  1. Import bezier.dart from a file in your project. In most cases you will also want to import the vector_math library.
import "package:vector_math/vector_math.dart";
import "package:bezier/bezier.dart";

Examples

  • Instantiate a Bézier curve.
import "package:vector_math/vector_math.dart";
import "package:bezier/bezier.dart";

void main() {
  // bezier.dart supports both quadratic curves...
  final quadraticCurve = QuadraticBezier([
    Vector2(-40.0, -40.0),
    Vector2(30.0, 10.0),
    Vector2(55.0, 25.0)
  ]);

  // ...and cubic curves!
  final cubicCurve = CubicBezier([
    Vector2(10.0, 10.0),
    Vector2(70.0, 95.0),
    Vector2(25.0, 20.0),
    Vector2(15.0, 80.0)
  ]);
}
  • Compute a point along a curve at t of 0.75.
import "package:vector_math/vector_math.dart";
import "package:bezier/bezier.dart";

void main() {
  final curve = QuadraticBezier([
    Vector2(10.0, 10.0),
    Vector2(70.0, 95.0),
    Vector2(15.0, 80.0)
  ]);

  final computedPoint = curve.pointAt(0.75);
}
  • Split a curve between the t parameter values of 0.2 and 0.6.
import "package:vector_math/vector_math.dart";
import "package:bezier/bezier.dart";

void main() {
  final curve = CubicBezier([
    Vector2(10.0, 10.0),
    Vector2(70.0, 95.0),
    Vector2(25.0, 20.0),
    Vector2(15.0, 80.0)
  ]);

  final subcurve = curve.subcurveBetween(0.2, 0.6);
}
  • Find the intersection t values between a curve and a line segment.
import "package:vector_math/vector_math.dart";
import "package:bezier/bezier.dart";

void main() {
  final curve = QuadraticBezier([
    Vector2(10.0, 500.0),
    Vector2(50.0, 0.0),
    Vector2(90.0, 500.0)
  ]);

  final lineStart = Vector2(0.0, 400.0);
  final lineEnd = Vector2(100.0, 410.0);

  final intersections = curve.intersectionsWithLineSegment(lineStart, lineEnd);
}
  • Derive an offset curve (composed of a series of subcurves) at distance 12.0.
import "package:vector_math/vector_math.dart";
import "package:bezier/bezier.dart";

void main() {
  final curve = CubicBezier([
    Vector2(10.0, 10.0),
    Vector2(15.0, 95.0),
    Vector2(20.0, 95.0),
    Vector2(25.0, 10.0)
  ]);

  final subcurves = curve.offsetCurve(12.0);
}

Style, Formatting, Philosophy

We've made our best effort to conform to the recommendations outlined in the Effective Dart guide. Accordingly, this library is formatted using dartfmt.

As fervent believers in the value of clean code, we are constantly seeking to improve the library and make it easier to work with. Please alert us to any issues you notice, no matter how trivial. We wholeheartedly welcome criticism and friendly debate! 🤓

Running Automated Tests

To run the test cases from the terminal, run the following command from the bezier.dart root directory.

pub run test

Most IDEs now provide interfaces for running tests, which are generally easier to work with. In most cases you can simply right click on a test file or directory in the project tree view and select the menu option to run the selected tests.

Submitting bugs, requesting features

Please file feature requests and bugs using the GitHub issues tab.

bezier.dart's People

Contributors

aab29 avatar fzyzcjy avatar ikebart avatar luigi-rosso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bezier.dart's Issues

Null Safety Support

Hi looking forward to support null safety! Since flutter has make null safety stable today!

EventSpacer question

Hi thanks for this! I can't get EvenSpacer to work... dots should follow the edge.

image

  @override
  void paint(Canvas canvas, Size size) {
    final curve = CubicBezier([
      Vector2(0, size.height),
      Vector2(size.width/8, size.height/8),
      Vector2(size.width, size.height/2),
      Vector2(size.width, size.height)
    ]);

    final points = curve.points;

    final path = Path()..moveTo(points[0].x, points[0].y)..cubicTo(curve.points[1].x, curve.points[1].y, curve.points[2].x,
        curve.points[2].y, curve.points[3].x, curve.points[3].y);

    canvas.drawPath(path, Paint()..color=Color.fromRGBO(0, 150, 255, 1));

    final es = EvenSpacer.fromBezier(curve,intervalsCount: 40);

    final count = 40;
    final eventValues = es.evenTValues(parametersCount: count);

    final paint = Paint();
    for (int i=0;i<eventValues.length;i++) {
      print(eventValues[i]);
      final pt = i;
      final x1 = pt * size.width/count;
      //double bla =(es.evenTValueAt(eventValues[i])) * size.height;
      double bla =(eventValues[i]) * size.height;
      canvas.drawCircle(Offset(x1, bla), 4, paint);
    }
  }

Awesome Library, can you convert to swift ?

Thank you for writing this awesome library , but I don't know Dart , any chance to convert this library to apple Swift ?
I want to realize such line effect :
(Draw with Adobe Flash CC Pen Tool , single line but with tapered width effect)
BezierLineByAdobeFlashCC
At first, I tried to use 2 Cubic Bezier Curves, but seems it's not so simple (I have no idea how to adjust that 4 control points, and even I don't know that if this is possible)
so now I'm trying to use single curves , and split it to segments (same length) ,and draw those segments with different width from big to small (maybe bad performance ? since the line(s) will be animated , any suggest ? )

Issue with line intersection

Given this piece of code:

import "package:vector_math/vector_math.dart";
import "package:bezier/bezier.dart";


void main() {

  // try to get intersection of zero axis with bezier -> no luck, intersections are empty
  CubicBezier bezier1 = CubicBezier([Vector2(-214.5, 80.0), Vector2(52.0, 80.0), Vector2(52.0, 530.0), Vector2(214.5, 530.0)]);

  Vector2 start1 = Vector2(0.0, 0.0);
  Vector2 end1 = Vector2(0.0, 1080.0);

  List<double> intersections1 = bezier1.intersectionsWithLineSegment(start1, end1);
  print("bezier1 intersections= $intersections1");

  // now try to translate this situation by 429px to right -> it's OK
  CubicBezier bezier2 = CubicBezier([Vector2(429.0 - 214.5, 80), Vector2(429.0 - 52.0, 80), Vector2(429.0 + 52.0, 530), Vector2(429.0 + 214.5, 530)]);

  Vector2 start2 = Vector2(429, 0);
  Vector2 end2 = Vector2(429, 1080);

  List<double> intersections2 = bezier2.intersectionsWithLineSegment(start2, end2);
  print("bezier2 intersections= $intersections2");

}

it's output is:

bezier1 intersections= []
bezier2 intersections= [0.4999999999999998]

But both intersections should be the same.

This is how it look like in canvas 429x1080px
image
(it is cropped by canvas)

SDK version 2.1.0
Bezier library version:1.1.1

intersectionsWithCurve not working with greater values

Hi! Thanks for the great package. It works very well and helps a lot. However, I recognized intersectionsWithCurve method was not working in greater values. Here are the details:

Scenario 1 (Works):

  • I am using some smaller numbers
final line =
        CubicBezier([Vector2(100, 100), Vector2(200, 100), Vector2(200, 100), Vector2(400, 100)]);
final curve =
        CubicBezier([Vector2(200, 50), Vector2(350, 150), Vector2(350, 150), Vector2(200, 200)]);

 final intersection = line.intersectionsWithCurve(curve);
 debugPrint('${intersection.length}');

>>> 1

Scenario 2 (Not work):

  • Bigger numbers
final line =
        CubicBezier([Vector2(100, 100), Vector2(400, 100), Vector2(400, 100), Vector2(3000, 100)]);

final curve = CubicBezier(
        [Vector2(2000, 50), Vector2(2350, 150), Vector2(2350, 150), Vector2(2000, 200)]);

 final intersection = line.intersectionsWithCurve(curve);
 debugPrint('${intersection.length}');

>>> 0

I also tried to increase curveIntersectionThreshold and decrease minTValueDifference but it did not help me. Would you happen to know any fixes/workarounds? I am not well-informed about bezier curves and might be wrong about some concepts. Thanks in advance!

Error in example

whoops ignore this i had bezier_chart: ^1.0.15 in my pubspec

lib/main.dart:519:11: Error: No named parameter with the name
'displayPreviousDataPointWhenNoValue'

Discrepancy between this library and CustomPainter cubicTo

I'm using this library to create a path that consists of multiple curves, the issue is that when I draw the path using CustomPainter cubicTo

var cubic = GameObject.shared.cubicBeziers;
    final Path path = Path();
    for (var i = 0; i < cubic.length; i++) {
      drawCurve(cubic[i], path);
    }
    path.close();
    canvas.drawPath(path, _paint);
    
    void drawCurve(CubicBezier curve, Path path) {
  
    vectorMath.Vector2 point0 = curve.startPoint;
    vectorMath.Vector2 point1 = curve.points[1];
    vectorMath.Vector2 point2 = curve.points[2];
    vectorMath.Vector2 point3 = curve.endPoint;
    path.moveTo(point0.x, point0.y);

    path.cubicTo(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y);

  }

And when I follow the path via percentages, they have a difference, especially on the y axis
The issue can be seen here:

ezgif-5-be09c688f3

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.