#Drawing a Bezier Curve in a shader with

1 messages · Page 1 of 1 (latest)

tight skiff
#

Since days I've been trying to draw a bezier curve,
One method is to calculate like 100 points and compare each point to the current point you're checking but this is slow, which is why I've been experimenting with splitting the curve into two bounding boxes and then split that box again, this gives very interesting results, but they seem kinda unreasonable to me.

#

my curves look like this

#

this is what happens when you just display the bonding boxes

#
float EstimateBezier(CurveSegment curve, float2 Point, float stroke)
            {
                float maxRecrutions = 5;
                
                float4 span = float4(0,1,0,0);
                float2 btmL = CalculateBezierAt(curve,0);
                float2 topR = CalculateBezierAt(curve,1);
                float dir = -1;
                Bounds StartBounds;
                StartBounds.xMin = btmL.x;
                StartBounds.xMax = topR.x;
                StartBounds.yMin = btmL.y;
                StartBounds.yMax = topR.y;
                StartBounds = SortBounds(StartBounds);
                StartBounds = BoundsUnionSelected(StartBounds,curve.Bounds,curve.Ext,0,1);

               
                Bounds Left;
                Bounds Right;
                bool insideBox = true;
                float epsilon = 0.001;
                span = SplitBezier(curve, StartBounds, Left, Right, span.xy);
                for(float i =0;i<maxRecrutions;i++)
                {
                    
                    if(PointInBoundsThreshold(Left,Point,stroke))
                    {
                        span = SplitBezier(curve, Left, Left, Right, span.xy);
                      
                    }
                    else
                    if(PointInBoundsThreshold(Right,Point,stroke))
                    {
                        span = SplitBezier(curve, Right, Left, Right, span.zw);
                       

                    }
                    else
                    {
                        i = maxRecrutions;
                        insideBox = false;
                    }
                    
                   
                     
                }
                if(insideBox)return 0;
                else return 1;
        
                
                
        }

This is the main function that executes my boundingbox searing algortithm 0 means black 1 means white

#
float2 CalculateBezierAt(CurveSegment curve, float t)
            {
                float t2 = t*t;
                float t3 = t2*t;
                float u = 1.0-t;
                float u2 = u*u;
                float u3 = u2*u;

                float2 p = curve.A * u3 +
                        curve.B * (u2 * t) * 3 +
                        curve.C * (u * t2) * 3 +
                        curve.D * t3;

                return p;


            }
            
            float4 SplitBezier(CurveSegment curve,Bounds parent, out Bounds Left, out Bounds Right, float2 range/*, float threshold*/)
            {
                
                float splitT = (range.x+range.y)/2;
                float2 rangeL = float2(range.x, splitT);
                float2 rangeR = float2(splitT, range.y);
                
                float2 splitP = CalculateBezierAt(curve, splitT);
                float2 LeftP = CalculateBezierAt(curve, range.x);
                float2 RightP = CalculateBezierAt(curve, range.y);
                Left.xMin = min(LeftP.x,splitP.x);
                Left.xMax = max(LeftP.x,splitP.x);
                Left.yMin = min(LeftP.y,splitP.y);
                Left.yMax = max(LeftP.y,splitP.y);

                Right.xMin = min(splitP.x,RightP.x);
                Right.xMax = max(splitP.x,RightP.x);
                Right.yMin = min(splitP.y,RightP.y);
                Right.yMax = max(splitP.y,RightP.y);

                Left = BoundsUnionSelected(Left,curve.Bounds, curve.Ext, rangeL.x,rangeL.y);
                Right = BoundsUnionSelected(Right,curve.Bounds, curve.Ext, rangeR.x,rangeR.y);
               

                return float4(rangeL,rangeR);
     


            }

This is to calculate the position of a bezier curve at a given t