Subdivide Bezier Curves

dan_wipf

I want to achieve that I can subdivide a Bezier Curve with a given distance. Now it works if the Bezier is a straight line, but if I change a Controll-Point(B&C) so the Bezier get's curved, the gap between the calculated Points are no more like the given Distance!

I've look through the web, but didn't crash in to a similar Problem.

float t = Distance between subdividedParts / bezier length;

//A,B,C,D = ControllPoints of Bezier

GetPoint(A,B,C,D,t);

//GetPoint equation:
public static Vector3 GetPoint (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) {
         t = Mathf.Clamp01(t);
         float OneMinusT = 1f - t;
         return
             OneMinusT * OneMinusT * OneMinusT * p0 +
             3f * OneMinusT * OneMinusT * t * p1 +
             3f * OneMinusT * t * t * p2 +
             t * t * t * p3;
     }

straight bezier curved bezier bezier explenation

dan_wipf

I've managed now to get quite accurate way to split the Bezier and get the Positions => but it's performance consumption is increasing as more accurate it get's. So this could be improved in this code:

 //if accuracy is 0.001 = good performance | if 0.000001 laggy performance
    public Vector3[] GetPoints (float gap,float accuracy){
     SimpsonVec sv = SV_Setup(0);
     Vector3 last_spawn = Bezier.GetPoint(sv.A,sv.B,sv.C,sv.D,0);

     List<Vector3> allPoints = new List<Vector3>();
     allPoints.Add(last_spawn);

     for(float t = accuracy;t <= 1.0f; t +=accuracy){
         Vector3 trial = Bezier.GetPoint(sv.A,sv.B,sv.C,sv.D,t);
         if(Vector3.Distance(trial,last_spawn) >= gap){
             last_spawn = trial;
             allPoints.Add(trial);
         }
     }
     return allPoints.ToArray();
 }

for more performance I did now this:

Code for Vector3[] Array Output

public Vector3[] GetAllPoints(float gap,float acc){

    SimpsonVector = SV_SETUP_ALL();
    BezierPoints bp = new BezierPoints();
    bp.bp_vector3 = new List<Vector3>();
    bp.bp_lastSpawn = new List<Vector3>();

    for(int i = 0; i<points.Length / 3;i++){

        Vector3 ls = new Vector3();
        if(i == 0){
            ls = Bezier.GetPoint(SimpsonVector[0].A,SimpsonVector[0].B,SimpsonVector[0].C,SimpsonVector[0].D,0);
        }if (i > 0){
            ls = bp.bp_lastSpawn[i-1];
        }
        BezierPoints bp_temp = GetSegmentPoints(gap,acc,i,ls);
        bp.bp_lastSpawn.Add(bp_temp.bp_lastSpawn[0]);
        bp.bp_vector3.AddRange(bp_temp.bp_vector3);
        SimpsonVector_TEMP = SimpsonVector;
    }


    return bp.bp_vector3.ToArray();
}

BezierPoints GetSegmentPoints (float gap,float acc,int index, Vector3 ls)
{
    SimpsonVec sv = SimpsonVector[index];
    Vector3 last_spawn = ls;

    BezierPoints bp = new BezierPoints();
    bp.bp_vector3 = new List<Vector3>();
    bp.bp_lastSpawn = new List<Vector3>();

    float step = 0.1f;
    float t = step;
    float lastT = new float();

    while (t >= 0 && t <= 1f)
    {
        while (t < 1f && Vector3.Distance(Bezier.GetPoint(sv.A,sv.B,sv.C,sv.D,t), last_spawn) < gap){
            t += step;}
        step /= acc;
        while (t > lastT && Vector3.Distance(Bezier.GetPoint(sv.A,sv.B,sv.C,sv.D,t), last_spawn) > gap){
            t -= step;}
        step /= acc;
        if (t > 1f || t < lastT){
            break;}
        if(step < 0.000001f){
            last_spawn = Bezier.GetPoint(sv.A,sv.B,sv.C,sv.D,t);
            bp.bp_vector3.Add(last_spawn + transform.position);
            lastT = t;
            step = 0.1f;
        }
    }
    bp.bp_lastSpawn.Add(last_spawn);
    return bp;
}

Structs:

public struct SimpsonVec{
    [SerializeField] public Vector3 A;
    [SerializeField] public Vector3 B;
    [SerializeField] public Vector3 C;
    [SerializeField] public Vector3 D;
}

public struct  BezierPoints
{
    [SerializeField] public List<Vector3> bp_vector3;
    [SerializeField] public List<Vector3> bp_lastSpawn; 
}

Helper Methods:

public SimpsonVec SV_Setup(int index){
     SimpsonVec sv;
     sv.A = points[index];
     sv.B = points[index+1];
     sv.C = points[index+2];
     sv.D = points[index+3];
     return sv;

 }
 public SimpsonVec[] SV_SETUP_ALL(){
     SimpsonVec[] sv = new SimpsonVec[points.Length / 3];
     for(int i = 0; i<points.Length / 3;i++){
         sv[i] = SV_Setup(i*3);
     }
     return sv;
 }
 public Vector3 GetPoint (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) {
     t = Mathf.Clamp01(t);
     float OneMinusT = 1f - t;
     return
         OneMinusT * OneMinusT * OneMinusT * p0 +
         3f * OneMinusT * OneMinusT * t * p1 +
         3f * OneMinusT * t * t * p2 +
         t * t * t * p3;
 }

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to draw each section of the blue Bezier curves with different color?

Detecting self crossing in closed Bezier curves

Circle approximations using Bezier curves

Which are the control points to create (approximate) a circle using 8 cubic bezier curves

Drawing Bezier curves in MonoGame (XNA) produces scratchy lines

Thick Bezier curves in SVG without artifacts

How to keep smooth lines when drawing out animated bezier curves in html5 canvas

How to detect collision between object made of bezier curves and a circle?

Cubic bezier curves - get Y for given X - special case where X of control points is increasing

Is there an easy way to connect the tangents of two overlapping Bezier curves?

Fill area between Bezier curves in Bokeh

How to Draw Shapes using Bezier Curves in a Flutter CustomPainter

How to create bezier curves for an arc with different start and end tangent slopes

Ways to animate bezier curves with AS3?

How to expand shape created from a lot of bezier curves (JavaScript and canvas)

Changing button shape made with bezier curves after pressure

WPF path description for a sine curve using bezier curves

Biciycle wheel path and bezier curves

How to get path of Bezier curves with coordinates of decimal value

How to prevent loops in cubic Bezier curves

Drawing random paths with quadratic bezier curves

how to use bezier curves in cytoscape.js

Converting between Bezier Curves of different degree(order)

Understanding how to draw SVG bezier curves by example

How to connect multiple bezier curves?

Bezier curves in Unity

SVG: reverse cubic and quadratic bezier curves

Using bezier curves to draw a rectangle with rounded corners in PyMuPDF

How to determine t value of original cubic bezier curve after subdivide such curve twice with each t = 0.5?