POV-Ray : Newsgroups : povray.newusers : Camera position for spline object : Re: Camera position for spline object Server Time
26 Apr 2024 16:59:50 EDT (-0400)
  Re: Camera position for spline object  
From: Tor Olav Kristensen
Date: 28 May 2022 15:55:00
Message: <web.62927c9e6b948b668051087f89db30a9@news.povray.org>
Cousin Ricky <ric### [at] yahoocom> wrote:
> On 2022-05-26 10:17 (-4), Tor Olav Kristensen wrote:
> >
> > But I'm now wondering if the original poster used another spline type in the
> > other tool. The spline type in the POV-Ray code is "b_spline". But I've not been
> > able to find out what spline type that is supposed to be. I very much doubt that
> > it is the B-splines described here:
> >
> > https://en.wikipedia.org/wiki/B-spline
> >
> > Perhaps the b stands for Bezier (?) Maybe someone can verify this...
>
> POV-Ray's b_spline is indeed a 3rd degree B-spline.  I verified this a
> few years ago by plotting points derived by de Boor's algorithm against
> a POV-Ray b_spline.

Ok. I did the same test as you. It seems to be b-splines with a closed knot
vector. Their order is 4, i.e. 3rd degree (as you found) plus 1.


> I have a very poor understanding of what is going
> on mathematically, but I do know that b_spline is not a Bezier curve.

As Bill mentioned; B-spline curves are a superset of Bezier curves.


> I found the Wikipedia article quite confusing, especially since all of
> the illustrations have the curves intersecting the endpoints, yet de
> Boor's algorithm, which the article links to, does not produce this
> result.  I know that Bezier curves are related to B-splines, but I
> haven't figured out how.

To make B-splines intersect the endpoints, you can use open knot vectors.

Alternatively you can repeat the endpoints. To see how to do this,
have a look at the source code below and the attached image.

The file NURBS_29.inc in below can be found here:
http://news.povray.org/povray.binaries.scene-files/thread/%3Cweb.4c327e199f459e99c734aecd0%40news.povray.org%3E/


// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.7;

global_settings { assumed_gamma 1.0 }

#include "colors.inc"
#include "NURBS_29.inc"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

default {
    texture {
        pigment { color White }
        finish {
            diffuse 0
            emission color White
        }
    }
}

background { color Gray10 }

camera {
    orthographic
    location -5*z
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare Size = 7;

#declare PP =
    array[Size] {
        <-3, +2,  0>, // 0
        <-3, -1,  0>, // 1
        <-1, -2,  0>, // 2
        <-1, +2,  0>, // 3
        <+1, +2,  0>, // 4
        <+2, -2,  0>, // 5
        <+3,  0,  0>  // 6
    }
;

#declare Radius = 0.01;

union {
    ShowPoints1A3D(
        PP,  // Points1A3D
        false, // WrapU
        6*Radius  // Radius
    )
    pigment { color Gray40 }
    translate +5*z
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Uniform B-Spline of order 4 with closed knot vector

sphere_sweep {
    b_spline
    Size,
    #for (I, 0, Size - 1)
        PP[I], 8*Radius
    #end // for
    tolerance 0.1
    pigment { color Cyan }
    translate +4*z
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare Order = 4;
#declare Open = false;

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// The circumstantial way

#macro B_Spline_Function1A(OrderU, KnotsU, Values1A)

    #local SizeU = Size1A(Values1A);
    #local BlendU_Fns = BlendFunctions(SizeU, OrderU, KnotsU);

    function(_t) {
        0
        #for (I, 0, SizeU - 1)
            #local C = Values1A[I];
            #switch (C)
                #case (-1)
                    -BlendU_Fns[I](_t)
                    #break
                #case (0)
                    #break
                #case (+1)
                    +BlendU_Fns[I](_t)
                    #break
                #else
                    +BlendU_Fns[I](_t)*C
            #end // switch
        #end // for
    }

#end // macro B_Spline_Function1A


#declare KK =
    UniformKnotVector(
        Open,  // Open
        Order,  // Order
        Size  // NrOfPoints
    )
;
// Closed: { -3/4,-2/4,-1/4, 0/4, 1/4, 2/4, 3/4, 4/4, 5/4, 6/4, 7/4 }
// Open:   {  0/4, 0/4, 0/4, 0/4, 1/4, 2/4, 3/4, 4/4, 4/4, 4/4, 4/4 }

#declare PPx = ExtractComponent1A(PP, x);
#declare PPy = ExtractComponent1A(PP, y);
#declare PPz = ExtractComponent1A(PP, z);

#declare B_Spline_FnX =
    B_Spline_Function1A(
        Order,  // OrderU
        KK,  // KnotsU
        PPx  // Values1A
    )
;
#declare B_Spline_FnY =
    B_Spline_Function1A(
        Order,  // OrderU
        KK,  // KnotsU
        PPy  // Values1A
    )
;
#declare B_Spline_FnZ =
    B_Spline_Function1A(
        Order,  // OrderU
        KK,  // KnotsU
        PPz  // Values1A
    )
;

union {
    ShowFunctions1A3D(
        B_Spline_FnX,  // xFn
        B_Spline_FnY,  // yFn
        B_Spline_FnZ,  // zFn
        false,  // WrapU
        0, // MinU
        1, // MaxU
        200,  // ResU
        6*Radius  // Radius
    )
    pigment { color Blue }
    translate +3*z
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Alternative way,
// but now with 2 repeated points in both the beginning and the end.

#declare NewSize = Size + 4;

#declare QQ =
    array[NewSize] {
        PP[0], //  0
        PP[0], //  1

        PP[0], //  2
        PP[1], //  3
        PP[2], //  4
        PP[3], //  5
        PP[4], //  6
        PP[5], //  7
        PP[6], //  8

        PP[6], //  9
        PP[6]  // 10
    }
;

// Uniform B-Spline
union {
    Show_UBS_1A3D(
        QQ,  // Points1A3D
        Open,  // OpenU
        Order,  // OrderU
        false,  // WrapU
        200,  // ResU
        2*Radius  // Radius
    )
    pigment { color Red }
    translate +1*z
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Now check if also the built in B-spline sphere sweep can be
// tricked into reaching the points in the beginning and the end.

sphere_sweep {
    b_spline
    NewSize,
    #for (I, 0, NewSize - 1)
        QQ[I], 4*Radius
    #end // for
    tolerance 0.1
    pigment { color Green }
    translate +2*z
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


--
Tor Olav
http://subcube.com
https://github.com/t-o-k


Post a reply to this message


Attachments:
Download 'b_spline_sphere_sweep.png' (33 KB)

Preview of image 'b_spline_sphere_sweep.png'
b_spline_sphere_sweep.png


 

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.