Parse

File Parse split.js

This tree is parsed live from the source file.

Classes

  • {{ item.name }}

    • {{ key }}

Not Classes

{{ getTree() }}

Comments

{{ getTreeComments() }}

Source

            /*
title: Split
files:
    functions/clamp.js
---

_Split_ a point or a line to many smaller points.

    const p = new Point({radius: 100})
    let points = p.split(4)

*/

/* splitToPointList(point, count).pen.indicators(ctx)*/
const splitToPointList = function(point, count, radius, rotation, angle=undefined) {
    let p1 = point
    let r = radius || point.radius
    p1 = p1.subtract(r)
    let _radius = radius || p1.radius
    // p1.rotation = rotation || point.rotation
    /* p1 does not recieve r.radians - use the original rads.
    rotation ==0 is falsy.*/
    let rot = rotation == undefined? point.radians: rotation
    return PointList.from(
                getPolyDistributedPoints(count, p1, _radius, rot, angle)
                // splitRadius(p1, count)
            )
}


const lerp = (x, y, a) => x * (1 - a) + y * a;


function bLerp(a,b,t){
    return (1-t)*a+t*b;
}

// AWESOME! https://acegikmo.com/bezier/
// https://acegikmo.medium.com/the-ever-so-lovely-bézier-curve-eb27514da3bf
function lerpV2(a,b,t){
    return {
        x: bLerp(a.x,b.x,t),
        y: bLerp(a.y,b.y,t)
    };
}


function get_bezier_point(p0, p1, p2, p3, t ){
    var a = lerpV2(p0,p1,t);
    var b = lerpV2(p1,p2,t);
    var c = lerpV2(p2,p3,t);
    var d = lerpV2(a,b,t);
    var e = lerpV2(b,c,t);
    return lerpV2(d,e,t);
}


function get_bezier_derivative(p0, p1, p2, p3, t) {
    var oneMinusT = 1 - t;

    var dx = 3 * oneMinusT * oneMinusT * (p1.x - p0.x) +
             6 * oneMinusT * t * (p2.x - p1.x) +
             3 * t * t * (p3.x - p2.x);

    var dy = 3 * oneMinusT * oneMinusT * (p1.y - p0.y) +
             6 * oneMinusT * t * (p2.y - p1.y) +
             3 * t * t * (p3.y - p2.y);

    return { dx, dy };
}


const lerpRadius = function(a, b, v) {
    /* Process the width from the _first_ to the _last_ of a line.*/
    // let av = ((asLast.radius - asFirst.radius) * (i/l))+asFirst.radius
    return ((b - a) * v) + a
}

const radiusManual = function(a, b, i) {}


Polypoint.head.installFunctions('Point', {
    /* A "split" function to divide the point circumference to many points.
    Return a list of points.

        let pointList = point.split(4)

    A `point.project()` is the same as `point.split(1)`
    */
    split(count, angle=undefined, outerAngle=0) {
        let point = this
        return splitToPointList(point, count, point.radius, point.radians + outerAngle, angle)
    }
});



Polypoint.head.installFunctions('BezierCurve', {
    splitInner(count, angle=0) {

        // console.log('BezierCurve split')
        let p0 = this.a
        let p3 = this.b
        let [p1, p2] = this.getControlPoints()

        let r = new PointList

        let splitVal = 1 / (count+1)

        for (var i = 1; i < count+1; i++) {
            let t = i * splitVal
            let { dx, dy } = get_bezier_derivative(p0, p1, p2, p3, t)
            p= new Point(get_bezier_point(p0, p1, p2, p3, t))
            p.radians = angle + Math.atan2(-dx, dy)
            r.push(p)
        }
        return r
    }

    , splitOnly(count, angle=undefined, ctx) {

        // console.log('BezierCurve split')
        let p0 = this.a
        let p3 = this.b
        let [p1, p2] = this.getControlPoints()

        let r = new PointList

        let splitVal = 1 / (count-1)

        if(count == 1) {
            // mid point.
            let p = new Point(get_bezier_point(p0, p1, p2, p3, .5))
            r.push(p)
            return r
        }

        for (var i = 0; i < count; i++) {
            let p = new Point(get_bezier_point(p0, p1, p2, p3, i*splitVal))
            r.push(p)
        }

        p1.pen.indicator(ctx, {color:'yellow'})
        p2.pen.indicator(ctx, {color:'yellow'})

        return r
    }

    , split(count, angle=0) {
        let p0 = this.a;
        let p3 = this.b;
        let [p1, p2] = this.getControlPoints();

        let r = new PointList();

        let splitVal = 1 / (count - 1);

        if (count == 1) {
            // Midpoint
            let t = 0.5;
            let p = new Point(get_bezier_point(p0, p1, p2, p3, t))
            let { dx, dy } = get_bezier_derivative(p0, p1, p2, p3, t)
            p.radians = Math.atan2(dx, -dy);

            r.push(p);
            return r;
        }

        for (var i = 0; i < count; i++) {
            let t = i * splitVal ;
            let p = new Point(get_bezier_point(p0, p1, p2, p3, t));
            let { dx, dy } = get_bezier_derivative(p0, p1, p2, p3, t);
            p.radians = Math.atan2(-dx, dy) + angle
            // p.radians = Math.atan2(dx, -dy) + Math.PI;

            r.push(p);
        }

        return r;
    }

    , splitHog(count, angle=undefined, ctx) {

        // console.log('BezierCurve split')
        let p0 = this.a
        let p3 = this.b
        let [p1, p2] = this.getControlPoints()

        let r = new PointList

        let splitVal = 1 / (count-1)

        if(count == 1) {
            // mid point.
            let p = new Point(get_bezier_point(p0, p1, p2, p3, .5))
            r.push(p)
            return r
        }

        let midX = (p0.x + p3.x) * .5
        let midY = (p0.y + p3.y) * .5
        let mid = new Point(midX, midY)


        let mid2X = (p1.x + p2.x) * .5
        let mid2Y = (p1.y + p2.y) * .5
        let mid2 = new Point(mid2X, mid2Y)

        mid.pen.indicator(ctx, {color:'yellow'})
        mid2.pen.indicator(ctx, {color:'yellow'})

        let mid3X = (mid.x + mid2.x) * .5
        let mid3Y = (mid.y + mid2.y) * .6
        let mid3 = new Point(mid3X, mid3Y)

        mid3.pen.indicator(ctx, {color:'yellow'})

        for (var i = 0; i < count; i++) {
            let p = new Point(get_bezier_point(p0, p1, p2, p3, i*splitVal))
            p.lookAt(mid3)
            p.rotation += 180
            r.push(p)
        }


        p1.pen.indicator(ctx, {color:'yellow'})
        p2.pen.indicator(ctx, {color:'yellow'})

        return r
    }

    , splitHinted(count) {
        /* Perform a split, using the point hints as a reference for size
        and rotation lerping through the count. */
        let r = new PointList
        let [first, last] = this.points
        let [p1, p2] = this.getControlPoints()

        let midX = (first.x + last.x) * .5
        let midY = (first.y + last.y) * .5
        let mid = new Point(midX, midY)

        let splitVal = 1 / (count-1)
        let dis = first.distanceTo(last)
        for (var i = 0; i < count; i++) {
            let p = new Point(get_bezier_point(first, p1, p2, last, i*splitVal))
            p.radius = lerpRadius(first.radius, last.radius, i/count)
            p.lookAt(mid)
            p.rotation = lerpRadius(first.rotation, last.rotation, i/count)
            r.push(p)
        }
        return r

    }
});


Polypoint.head.installFunctions('Line', {

    /* A "split" function to divide the point circumference to many points.
    Return a list of points.

        let pointList = point.split(4)

    A `point.project()` is the same as `point.split(1)`
    */
    splitInner(count, angle=undefined) {

        let a = this.a
        let b = this.b
        let r = new PointList

        if(count == 1) {
            // mid point.
            r.push(new Point(
                lerp(a.x, b.x, .5)
                , lerp(a.y, b.y, .5)
                )
            )
            return r
        }

        let splitVal = 1 / (count - 1)
        let degs = undefined
        if(angle != undefined) {
            degs = calculateAngle(a, b) - angle;
        }

        for (var i = 0; i < count; i++) {
            r.push(new Point(
                lerp(a.x, b.x, i * splitVal)
                , lerp(a.y, b.y, i * splitVal)
                , a.radius
                , degs
                )
            )
        }
        return r
    }

    , split(count, angle=undefined) {

        let a = this.a
        let b = this.b
        let r = new PointList

        let splitVal = 1 / (count+1)
        let degs = undefined
        if(angle != undefined) {
            degs = calculateAngle(a, b) - angle;
        }

        for (var i = 1; i < count+1; i++) {
            r.push(new Point(
                lerp(a.x, b.x, i * splitVal)
                , lerp(a.y, b.y, i * splitVal)
                , a.radius
                , degs
                )
            )
        }
        return r
    }
});

copy