 # How to create a curve which follows the position of severals points ?

#1

Hello,

I search for the way to smooth an edge selection.
So i have an array of points…
The problem is : how to create a curve passing approximately by these points?
Lets say the curve will be simple…

#2

I’m not sure if this is what you’re looking for, but this is what you can use to build a line from some points.

``````(
-- Initialize line
new_spline = splineShape()

cAng = 23 -- Some random angle

-- Throw some point3 values (coordinates) in an array just to have something.
-- Using sin and cos to set some lines in a curve.

-- Add points in array to construct the line
for i in pointArray do addknot new_spline 1 #smooth #curve i
)

``````

#3

Just by curiosity:
I don’t know if I am alone having a crash when I edit the vertices of the spline ?
But if I add the line “updateShape new_spline” at the end then it don’t crash anymore.
Well that isn’t very important.

Thanks for your answer I realize I was not very precise in my request.
I am trying to give you a complete explanation:

I want to create a tool for modelers.
The modeler have an edge selection but the curve of these edges is a bit chaotic.
Because of that, the surface generated by the subdivision surface of this curve isn’t very clean.
I avoid that by editing it manually (I use some tools to displace the vertices or I recreate some new edges with cut function).
The goal is to obtain a very smooth curve.

So the problem is not to follow exactly the postion of the points but to be able of creating a perfect curve using a cloud of points. It is more a mathematical problem.

It is easier to show it than to say it. Then here is a plan:

#4

This looks like a NURBS CV curve.

#5

But if I add the line “updateShape new_spline” at the end then it don’t crash anymore.
Well that isn’t very important.

It is very important to add updateShape() after modifying a spline Your image indeed looks like a nurbs or bezier curve.

There is a mathematically easy version of bezier curves that are described by 4 points only. But I guess you need the full version.

http://local.wasp.uwa.edu.au/~pbourke/surfaces_curves/bezier/

Georg

#6

To be honest I had hoped to find a less complex solution for smoothing the edges.
Bezier curves are really core mathematics…

#7

Hey Arketip, how about taking the vert that is “highest up” and “lowest down” and calculating that distance. Then get the middle position of all edges, go straigth “up” from that position by the amount of the first distance and you have a position. Create a spline with three knots and set the end knots to the verts of the edges farthest away from each other and set the middle knot to the position you got above the middle. If you set the knot type to Smooth for the middle knot you will have a curve that you can align the verts of the edges to. I hope that made sense, I’m a bit tired. CML

#8

That sounds like a quadratic way of generating a curve - that a degree of n2. Way to slow for something a little more complex that 4-5 points. I’d use a bernstien polynormial of maybe a nth degree of 3, nurbs curves which are a bezier curve projection into 4d space, using conic sections is very complicated to write and I still find pretty hard to do.

So ontop of building a respective curve, be it cardinal (a curve that goes through your set aproximated points) or a bezier curve which infact what you want is a b-spline, which is several bezier curves joined together. (the math for the sections isnt too hard, and infact the algorithm for the polynormial isnt either) - your have to do some aproximation math on the points firstly:

1.to get the ‘best fit’ selection of points, maybe based on distance to each other.
2. then get an ‘average’ point made of these selections or maybe a vector to

Im just thinking out loud (love trying ideas out), so grab every say 10 points that are close to each other, build an average vector from that. Think you’ll need a modular function on a per 10 vector basis.

``````  r = 0

aprxVecs=#()
for v = 1 to vecs.count do
(
if mod((v 10)-1) == 0 then
(
r = 0
)
else
(
if distance (vecs[v] vecs[(v+1)) < 10 do
(
r = r + vecs[v]
)
append aprxVecs (r/10)
)

)

``````

umm… something like that. may need to put a distance fn in there some where.

Then you’ll need a polynomial to quantify the curve, hmm… you’ll need to do some percentage based section stuff, a bezier curve segment relies on 4 control points (tangents) its how these tangents are derived that the difference between a cardinal and a bezier curve. Nurbs are a lot different. First off id build a spline using a simple for loop and knot creation methods. If you want something a little more custom then yell!

Your aproximation is the most important part, as you may not want distance but edge detection etc.

#9

If you are trying to find a curve using any amount of points you can do it quite simply.

Say you have four points to start with, any number can be used, and you want to create a curve from those points and find a given position along the curve.

We will find the mid point in this example, this will be 0.5 along the curve.

Start with four vector points, P1,P2,P3,P4 and the percent (time) along the curve that you are trying to find, T=0.5. Time can be a value from 0 to 1.

Using this formula you can find the percent between any two points. We will use P1 and P2 as an example.
(1-T)P1+tP2

So what you do is start with the four vectors and find the time between each to calcualte three new vectors.
P1a=(1-T)P1+tP2
P2a=(1-T)P2+tP3
P3a=(1-T)P3+tP4

The you just do it all again. You find the time between each of the three new vectors. to calculate two new vectors.

P1b=(1-T)P1a+tP2a
P2b=(1-T)P2a+tP3a

Then one last time to calcualte the final vector that is 0.5 along the length of the curve.

P1c=(1-T)P1b+tP2b

P1c is 0.5 along the curve in our test. Pass any other time value into the equasion to find that point.

#10

Thats quadratic Paul, I was thinking it will be too slow because your loops are recursive right and so for 20 vectors. 1-20, 1-19, 1-18 etc Also with that curve, it won’t run through any point you give it.

#11

This is a quadratic curve but really is the basis for others. If you pass it 20 points I’m sure that it would get slow. I use this in rigs and it is faster then using Max splines. How ever I usualy set it up so that it is only using sets of four points each.

#12

hey thanks for all your answers Thanks very much !

Tonight i only had the time to do a little test based on the middle of the edges.

1. find the middle of the edges
2. & 3. a new curve appears but the points aren’t positioned correctly…
3. Then 2 options are possible:
Either i find the middle of this new edges but it is a little bit to far for several points.
Or i project the old point on this new curve (at the right)
4. The smoothed final curve.

mmmhhh that is not very good. The edges are smoothed but the shape is lost.

I will try another idea tomorrow :shrug:

#13

Hey Arketip, I couldn’t help playing around with this idea since I think it is a very good one. Would you mind if I included a similar tool in the PolyBoost tools? I think it would be appreciated by the users.

My idea is to generate smooth curves of edges/edgeloops where the curvature is based on the position of the selected verticses along the loops. I’m using splines to form the curves. I already have something that is working fairly well and can be used on multiple edgeloops at once to curve a whole surface, feels like working with patches or nurbs a bit. Some examples…the top images is the initial vertex selection along selected loops, in the bottom the tool is applied: What do you think? I don’t want to rip you off if this idea is something you are going to use commercially or something.

cheers,
CML

#14

anyone know how to store an array of vertex indices, the order they were selected? I can get an array but it sorts them the second they become an array? eg 13,17,12 becomes 12,13,17!!

#15

Hi Charles,

You can’t. I know because I asked Larry about it before. Only way would be to use a callback or timer, but if the user select multiple SOs, then it becomes uncertain. Also depending on what you want to do with it, you could also make a tool to pick them (using the tool clause).

Light

#16

Carl, thats really cool. What method are you using for the math?

#17

Thats what I thought, damn this crazy brain of mine! #18

Off course You can add it in the polyBoost tools.
For the moment i don’t have the time to write the mine, that is great ! lol

Seriouly are you interested that i become a beta tester of polyBoost ?
I could give you some ideas.

#19

Arketip - Sounds good, thanks. It should then be a feature in the next version wich is due out soon. Send me a mail at admin@polyboost.com and I’ll set you up as a betatester.

PEN - Thanks, I get a lot for free by using splines to form the curves, so the main work is to sort all loops and vertices and aligning them to the curve at the correct distances and such. Not extremely complex math but still quite a bit of work. Mostly vector math. There is an option to space the verts evenly along the loops or retain the initial relationship between vertices.

#20

Has anyone thought of using Catmull-Rom curves for this?
http://en.wikipedia.org/wiki/Catmull-Rom_spline