Giter Club home page Giter Club logo

bezierjs's People

Contributors

0xf0f0f0 avatar adrienbataille avatar aidant avatar betula avatar carvadero avatar idupree avatar jacobp100 avatar joostdecock avatar justvanrossum avatar kant avatar kvolkovich-sc avatar littlehaker avatar louisremi avatar ntamas avatar pomax avatar pranavtotla avatar rikkertkoppes avatar sgtwilko avatar stavenko avatar vincentdo avatar williamledoux avatar xusiyuan841028 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  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  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

bezierjs's Issues

Circle intersection

Hi Mike,
What is a good strategy for detecting intersection of a Bezier curve and a circle? Would you recommend using 4 curves, each approximating a quarter circle?

Checking if two curves are colinear

Possible implementation for cubic case.
Can probably be improved (possibly unstable for as curveP0T approaches 1)

likeCurve(curve) {
    return curve.constructor == BezierCurve
        && this.p0.like(curve.p0)
        && this.p1.like(curve.p1)
        && this.p2.like(curve.p2)
        && this.p3.like(curve.p3)
}

/**
 * Checks if this curve is colinear to the passed curve, i.e.
 * for every t:number there exists a s:number with this.at(t) = curve.at(s)
 * @param {BezierCurve} curve
 * @returns {boolean}
 */
isColinearTo(curve) {
    // first, find out where/if curve.p0 and curve.p3 are on this
    // then split this at curve.p0 --> curve.p3 to compare points p1 and p2
    var curveP0T, curveP3T
    // assign in if condition to exploit short-circuit
    if (isNaN(curveP0T = this.pointLambda(curve.p0)) || isNaN(curveP3T = this.pointLambda(curve.p3))) {
        return false
    }
    var thisSplit
    if (NLA.equals(1, curveP0T)) {
        // this.split(curveP0T).right is degenerate in this case, so we need to handle it separately 

        // this.split(curveP3T): 0 --> curveP3T --> 1
        // .right: curveP3T --> 1
        // .reversed(): 1 --> curveP3T
        thisSplit = this.split(curveP3T).right.reversed()
    } else {
        // curveP3T describes the point on this
        // adjust it so it describes the same point on this.split(curveP0T).right
        // this:                       0           p0t        p3t      1
        //                             |            |          |       |
        // this.split(curveP0T).right:              0        p3tad     1
        var curveP3Tadjusted = (curveP3T - curveP0T) / (1 - curveP0T)
        thisSplit = this.split(curveP0T).right.split(curveP3Tadjusted).left
    }

    return curve.likeCurve(thisSplit)
}

/**
 * @returns {BezierCurve}
 */
reversed() {
    return new BezierCurve(this.p3, this.p2, this.p1, this.p0)
}

It seems the folder test/manual is missing in this repo

This folder is referenced in package.json:

"scripts": {
    "test": "npm run build && node test",
    "test:manual": "http-server test/manual",
    "build": "..."
}

But it isn't present in the repo. Have you renamed it to "autodraw", or simply forgotten?

Bezier curve through points.

A function constructs quadratic/cubic/poly bezier curve through points given would be useful.
Nicer if we can specify tangent direction of start and end points.

offset messes up on tighter curves

A picture is worth a thousand words:

What I'm actually trying to do is create a uniform inset for a larger closed shape, consisting of a number of bezier curves. Obviously there will be issues if the shape has any intersections on its path, but I don't care about that case too much. Can you recommend any information that would allow me to calculate a continuous non-self-intersecting offset path derived from a continuous set of bezier curves defining a closed shape?

intercepts function doesn't work with perfectly-horizontal intercepting lines

var test_bezier = [0, 1.74, .21, 1.67, .28, 1.32, .28, .86];
var test_line = { p1: { x: -.56, y: .95}, p2: { x: .56, y: .95 } };
var test_curve = new Bezier(test_bezier);
var intersections = test_curve.intersects(test_line);
if(intersections.length === 0) throw new Error('Expected at least one intersection');

The test curve and line above definitely intersect. I've checked and rechecked multiple times, including drawing the points (at various scales) onto a canvas. bezier.js fails to return any intersection points.

I've actually got a surfboard shape comprised of a set of bezier curves, and I'm using bezier.js to calculate around 150 slice points along the length of the board, but the intersections returned are very intermittent. I typically assume my code is at fault before assuming a library is at fault, but that test case above seems pretty clear.

new Bezier() use of `arguments` is broken, and unrelatedly, slows down Chrome

(thank you for your great library and giving me a chance to improve it! sorry for the dire-sounding headline on a very minor issue)

Passing multiple arguments doesn't work (as compared to an array of arguments, which does) because line 500-507 iterates coords rather than args. I can fix this with a few lines of changes, or remove it with something like

-    var args = (coords && coords.forEach ? coords : arguments);
+    var args = coords;

Any preference which? I'm happy to send a pull request.

I noticed this because Chrome's profiler noted that it doesn't know how to optimize array-like uses of arguments (see https://code.google.com/p/v8/issues/detail?id=3037 ), which keeps it from optimizing the entire function. Fixing this changed it from the slowest thing in my profile to something more reasonable. The workaround is apparently to iterate through arguments like var args = []; for(var i = 0; i !== arguments.length; i++) { args.push(arguments[i]); } (as suggested in bevry/taskgroup#12 (comment) ). Less importantly, I'd probably check for multiple arguments by checking arguments.length rather than coords && coords.forEach.

Type returned by split()

Hi @Pomax ,

I'm trying to understand the type of object returned by the split method of the Bezier class.
It seems that it can return either:

  • a Bezier,
  • a "subsplit" object with a left Bezier and a right Bezier.

I'm guessing that the subsplit might only be for internal use by split itself?

Offset is drawing a line on both sides of a cubic curve?

Given this code:

var pts = [ 120, 79.63967819396663, 173.33333333333331, 118.72659522329167, 226.66666666666669, 109.84371034788978, 272, 85.57546366477419 ],
    curve = new Bezier(pts),
    ocurve = curve.offset(20);

draw_curve(curve, "line");
ocurve.forEach(function(c) {
  draw_curve(c, "offsetpath");
});

I get a properly offset line below curve, but also a bit of the curve offset by the same amount but above curve. Here is a demo.

Is this a bug, or am I misunderstanding how this is an expected behavior?

Suggestion: simplify and generalize utils.angle

In our app we've written a small utility that calculates the angle between two lines

export function lla(l1p1, l1p2, l2p1, l2p2) {
  let angle1 = Math.atan2(l1p1.y - l1p2.y, l1p1.x - l1p2.x);
  let angle2 = Math.atan2(l2p1.y - l2p2.y, l2p1.x - l2p2.x);
  return angle1 - angle2;
}

This function is rather simple and can also be used to calculate an angle formed by three points: const angle = lla(A,B,B,C);. I suggest replacing your implementation of angle by this implementation. I'm ready to open a PR and change code that uses this method if you think this could be useful.

Thank you in advance.

bezier.toSVG() returns malformed SVG path string.

ex.)

function example(){
    var bezier = new Bezier( [ {x:1031,y:325},{x:1031,y:500},{x:1271,y:530},{x:1271,y:375} ] );
    return bezier.toSVG();
}

Output:
"M 1031 325 C 1031 5001271 5301271 375"

Expected Output:
"M1031 325C1031 500 1271 530 1271 375"

bezierjs/bezier.js:487: ERROR - Parse error. Internet Explorer has a non-standard intepretation of trailing commas. Arrays will have the wrong length and objects will not parse at all.

Hi Pomax,

Great work!

I want to use a minified version of your bezierjs and found following little issue.

It's here: https://github.com/Pomax/bezierjs/blob/gh-pages/bezier.js#L487

yi@localhost -> java -jar  ../../scripts/compiler.jar --js bezierjs/bezier.js --js_output_file /dev/null --compilation_level SIMPLE_OPTIMIZATIONS
bezierjs/bezier.js:487: ERROR - Parse error. Internet Explorer has a non-standard intepretation of trailing commas. Arrays will have the wrong length and objects will not parse at all.
  };
   ^

1 error(s), 0 warning(s)

improve the iterative intersection detection

The iteration should continue until it hits error resolution, after which any value is acceptable, and so rather than clusters we can use a final linear intersection check to find singles, instead.

__normal3 param error

__normal3: function() { // see http://stackoverflow.com/questions/25453159 var r1 = this.derivative(t), r2 = this.derivative(t+0.01)

param 't' is not defined

extend length() to accept a limit of integration

Change the .length() function so that it can be called as .length(t), setting the limits of integration to [0,t] rather than the current [0,1].

length: function(t, undef) {
  t = t===undef? 1 : t;
  ...
}

This should also make work around a "get t for distance d" function easier.

new Bezier(a, b, a, c, d, e, f, g).outline(h) fails

  1. Construct a bezier using four points where the x values of the first and second points are identical
  2. Call .outline with any number on the constructed bezier
  3. Instead of the usual array of curves being returned, an error is thrown
TypeError: p1.split is not a function

Testable example

new Bezier(102,33, 102,33, 101,129, 132,173).outline(5)

bezier.js:1 Uncaught TypeError: t.split is not a function(…)(anonymous function) @ bezier.js:1p.reduce @ bezier.js:1p.outline @ bezier.js:1(anonymous function) @ VM675:2InjectedScript._evaluateOn @ VM90:878InjectedScript._evaluateAndWrap @ VM90:811InjectedScript.evaluate @ VM90:667

Inverse of .compute?

Is there a way, given a point on the curve, to get the t value for that point? For non-degenerate quadratic curves it should be unique.

[suggestion] Add .editorconfig and .eslint files

I'm in the process of writing a functional version of the lib, and I believe it would be great to have an .editorconfig and .eslint files to keep code consistent.
I can send a PR that adds those files and fix linting errors in the repo. Do you have an existing config you'd want to point me to, or an preferred config?

getPoint(length) or getT(length)

Get the point based on the length of the curve or return t based on the length of the curve from t =0

This would allow splitting the curve evenly based on length in x sections of the same line length (not t like in getLUT) and also place items on a curve based on distance from t0

change points

Hello in video games need change the endpoint in some cases, how to ? enhancement

Typescript support

Having spent futile 4 hours trying to use this library in a typescript code base (ES6 module imports), I wonder if anyone has managed, and show how.

Seems like @danmarshall did some work on this, but none seem to work.

There's this typescript fork/port, which I couldn't install at all - it just throws errors when you run npm install; it is also at 2.1.0 at the moment.

Then, there's the typings definitions, and an npm package for @types/bezier-js, but the devil will take me I only get compilation/run-time errors with these.

Anyone?

Get the base bezier class

Hi,

Thanks a lot for your excellent work, I want to know that can I get the base bezier class in C++ format? I remembered that I can get that code some days ago, but now I can not find that code. Can you share me a copy?

Thanks a lot.

Best,
Eric

reduce (or extrema or split?) breaks as soon as control point and start are the same

First of all thanks for that library, saved me a lot of time :-).
Apparently the reduce function fails as soon as a control point and the start/ end are the same. I did some further investigations and found out that this is connected to the extrema function yielding 0 two times and therefore "confusing" the split function (which seems to be broken for input 0,0 as well).
Minimal example below:

      var curve = new Bezier(100,25 , 100,25 , 110,100 , 150,195);
      var draw = function() {
        drawSkeleton(curve);
        drawCurve(curve);
        setColor("red");
        curve.extrema().values.forEach(function(t) {
          drawCircle(curve.get(t),3);
          console.log(t);
        });

        curve.reduce().forEach( (curve) => {
          drawCurve(curve);
        } );

      }

roots function fails for order 3, d == 0

When the roots function is called with 4 points (order == 3) it is possible that the variable 'd' will assume a ZERO value causing failure when it is used as a divisor. I believe this is the cubic term being used to 'normalize' the other terms for "Cardan's method". The cubic term being zero seems to indicate that, though having 4 points, the curve is actually quadratic in nature. This would seem rather common. Finding the roots using a quadratic method, in this case, seems to easily solve the problem.

add a proto.getTforPoint(point)

If a point is on-or-near-enough the curve, return all t values that yield the specified point.

This will allow things like:

getDistanceforPoint(p):
  ts = getTforPoint(p)
  ds = (ts: (t) => split(t).length)
  yield ds

simplifying bezier curves?

I don't know if this is the right place to ask, or whether you've already addressed this problem here or elsewhere.
Anyway, it'd be nice if you could explore ways of optimizing bezier paths to reduce the number of curve segments while keeping the overall shape.
Any insight?
Thanks,

Cosimo

register in Bower

we all love npm, but having bower install bezierjs would be as good.

Diferences with the SVG getPointAtLength method

I'm trying to write a simple library to get SVG paths properties.
I'm using bezierjs for the Bezier curves, and it works ok with lengths, but with the position at certain point I find differences from the getPointAtLength method.
bezier
In this image you can see the points that should be the same, marked in different colors. The functions called are like:

 pathEl = d3.select("body").append("svg")
 .attr("width", 960)
 .attr("height", 300);
  path = pathEl
 .append("path")
 .attr("fill", "none")
 .attr("stroke", "black")
 .attr("d","M200,300 Q400,50 600,300");


 var curve = new Bezier(200,300,400,50,600,300);

 console.info("Bezier-js", curve.get(0.2));
 var browserLength = path.node().getTotalLength();
 console.info("SVG", path.node().getPointAtLength(0.2 * browserLength));

But the results are different:

Bezier-js { x: 280.00000000000006, y: 220.00000000000003 }
SVG { x: 267.53448486328125, y: 229.83480834960938 }

Am I doing something wrong? In bezierjs the length is given from 0 to 1, and in the SVG function, from 0 to the length of the curve, but the positions should be the same...
More curves with the same problem can be found here.

Uncaught TypeError: t.split is not a function

var curve = new Bezier(330,592,330,557,315,522,315,485);
curve.offset(20);  // it causes TypeError

I found it was generated while calling t.split within .reduce function of curve.

outline() fails miserably when reduce() returns empy list because it cannot form a reduction

Shouldn't reduce() in the "cannot reduce" case return the original unreduced curve? Y so destructive?

we can never form a reduction  bezier.js:1152:13
TypeError: fcurves[0] is undefined[Learn More]  bezier.js:1273:7
	Bezier.prototype.outline file:///home/chuck/curve_test_js/bezier.js:1273:7
	Bezier.prototype.outlineshapes file:///home/chuck/curve_test_js/bezier.js:1286:17
	<anonymous> file:///home/chuck/curve_test_js/outlines.html:375:40
	r.Callbacks/i file:///home/chuck/curve_test_js/jquery-3.1.1.min.js:2:27978
	r.Callbacks/j.fireWith file:///home/chuck/curve_test_js/jquery-3.1.1.min.js:2:28749
	A file:///home/chuck/curve_test_js/jquery-3.1.1.min.js:4:14201
	.send/c/< file:///home/chuck/curve_test_js/jquery-3.1.1.min.js:4:16491

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.