# tangent of spline point

• On 02/05/2013 at 18:52, xxxxxxxx wrote:

I'm having a hard time understanding exactly what you want too.

Here's an example of creating a spline. And setting all of the tangents to a specific Y value.
If you only want one/or certain tangents to be set instead of all of them. Then use a conditional statement with an array index value inside of the loop. Instead of using "i" for setting all of them:

``````//This is an example of creating a spline and setting it's points and tangent handles

SplineObject *sp = SplineObject::Alloc(3, SPLINETYPE_BEZIER); //Create a bezier spline with 3 points
if(!sp) return NULL;
doc->InsertObject(sp, NULL, NULL, 0);  //Add it to the OM

Vector *gp = sp->GetPointW();          //Assign the array of spline points to a variable
gp[0] = Vector(10,0,-100);             //Place the first spline point here
gp[1] = Vector(0,0,0);                 //Place the second spline point here
gp[2] = Vector(-10,0,100);             //Place the third spline point here

Tangent *tangents = sp->GetTangentW(); //Assign the array of tangents to a variable

//Loop through all of the tangents
for (LONG i = 0; i < sp->GetTangentCount(); i++)
{
tangents[i].vl.y = 200;           //Set each spline point's left tangent to this position
tangents[i].vr.y = -200;          //Set each spline point's right tangent to this position
}

sp->Message(MSG_UPDATE);              //Update the spline's changes
``````

-ScottA

• On 05/05/2013 at 10:55, xxxxxxxx wrote:

thank you. i didnt try GetTangentW, because in the sdk it says that it returns the first element. now i get the tangents. however, i had the hope to use the tangents to create a correctly offset position for the points. but, in liniear splines there are no tangents. how can i calculate the direction for the offset so that positive values go into one direction, and negative values go to the opposite direction? (see image)

i did it like this:

Vector winkel = VectorToHPB(p2-p1);
Matrix richtung = HPBToMatrix(winkel, ROTATIONORDER_DEFAULT);

however, that resulted in point offsets to unwanted directions, like if you changed the green and red for only some of the points in the image. thats why i thought using the tangents could help..

maybe there is another solution?

cheers,
Ello

• On 05/05/2013 at 11:57, xxxxxxxx wrote:

If I wanted to move the points of a spline.
This is the way I'd do it:

``````#include "lib_splinehelp.h"

BaseDocument *doc = GetActiveDocument();
BaseObject *spline = doc->SearchObject("Spline");
PointObject *sp = ToPoint(spline);

AutoAlloc<SplineHelp> sh;
if(!sh) return FALSE;
sh->InitSpline(sp);
if(!sh->Exists()) return FALSE;

Vector *spPnts = sp->GetPointW();           //Get all the points in the spline

Real offsetX = 100.0;
Real offsetY = 100.0;                       //Some offset values that can be bound to GUI gizmos
Real offsetZ = 100.0;

LONG pntCnt = sh->GetPointCount();
for(LONG i=0; i<pntCnt; i++)
{
spPnts[i].x += offsetX;
spPnts[i].y += offsetY;                 //Move all the points in the spline by this offset amount
spPnts[i].z += offsetZ;
}

sp->Message(MSG_UPDATE);                    //Update the changes made to the spline
``````

-ScottA

• On 06/05/2013 at 00:15, xxxxxxxx wrote:

yes, i know how to move points, but how do i get the direction when there is no tangent and when  i need to take care that the points need to move all relatively to the right or left side of the spline.. thats the main problem i have here

• On 06/05/2013 at 03:07, xxxxxxxx wrote:

You can get the bisecting vector of a point by calculating the arithmetic middle of the adjacent points.

• On 06/05/2013 at 04:26, xxxxxxxx wrote:

i guess you mean something like

``````tRot = Vector((getAngle(points[i-1],points[i]).x+getAngle(points[i+1],points[i]).x)/2,0,0);

Matrix richtung = HPBToMatrix(tRot, ROTATIONORDER_DEFAULT);
tPos += Vector(0,0,_ipOffset)*richtung;
``````

this still makes some objects move to the one direction end others to the opposite direction...

• On 06/05/2013 at 14:13, xxxxxxxx wrote:

double post, sorry.

• On 06/05/2013 at 14:15, xxxxxxxx wrote:

Not exactly. But I expressed myself not 100% correct. You can get a point that lies on the bisecting
line this way:

``````p1 = points[i]
p2 = (points[i - 1] + points[i + 1]) * (1 / 2.0)   // I think division is not supported by the vector class
bv = (p2 - p1).GetNormalized()
``````

Then again you can cross it with one of the adjacent lines and cross it
again and you have the tangent:

``````n = bv.Cross(points[i] - points[i - 1])
tangent = bv.Cross(n)
``````

Best,
Niklas

• On 06/05/2013 at 21:32, xxxxxxxx wrote:

thank you niklas. i'll try if this helps me solve my problem and report back...

• On 07/05/2013 at 01:44, xxxxxxxx wrote:

hm, this still produces the wrong direction for some points. i have no idea how to get this working...

• On 07/05/2013 at 03:18, xxxxxxxx wrote:

Hi ello,

here, some example code quickly plucked together.

``````import c4d

class Tag(c4d.plugins.TagData) :

SIZE_SPHERE = c4d.Vector(10)
COLOR_SPHERE = c4d.Vector(1, 0.66, 0.02)

LENGTH_TANGENT = 20
COLOR_TANGENT = c4d.Vector(0.1, 0.95, 0.5)

def Draw(self, tag, op, bd, bh) :

if not isinstance(op, c4d.SplineObject) :
return True

bd.SetMatrix_Matrix(op, op.GetMg())
segments = [op.GetSegment(i) for i in xrange(op.GetSegmentCount())]
if not segments:
segments = [{'cnt': op.GetPointCount(), 'closed': op.IsClosed()}]

pi = 0
for segment in segments:
cnt = segment['cnt']
closed = segment['closed']

start = pi
end = pi + cnt
i_start = start
i_end = end
if not closed:
i_start += 1
i_end -= 1

bd.DrawSphere(op.GetPoint(pi), self.SIZE_SPHERE, self.COLOR_SPHERE, 0)
bd.DrawSphere(op.GetPoint(pi + cnt - 1), self.SIZE_SPHERE, self.COLOR_SPHERE, 0)

bd.SetPen(self.COLOR_TANGENT)
if start < end:
for i in xrange(i_start, i_end, 1) :
left = i - 1
right = i + 1

if left < start:
left = end - 1
if right >= end:
right = start

print left, i, right

pleft = op.GetPoint(left)
pright = op.GetPoint(right)
point = op.GetPoint(i)

mid = (pleft + pright) * 0.5
bv = point - mid
n = bv.Cross(point - pleft)
tangent = n.Cross(bv).GetNormalized() * self.LENGTH_TANGENT

pmin = point - tangent
pmax = point + tangent
bd.DrawLine(pmin, pmax, 0)

pi += cnt

print "-------------------"

return True

if __name__ == "__main__":
c4d.plugins.RegisterTagPlugin(100003, "Spline Tangents", c4d.TAG_VISIBLE, Tag, "Tsplinetangents", None)
``````

Best,
-Niklas

• On 07/05/2013 at 03:20, xxxxxxxx wrote:

Originally posted by xxxxxxxx

this still makes some objects move to the one direction end others to the opposite direction...

Uhm, I just see: The result in the image is correct. What else did you expect?
The only thing left would be to rotate them about 90° to get the actual tangent (see my example code).

• On 07/05/2013 at 04:05, xxxxxxxx wrote:

thank you very much, but when i rotate the direction the problem still remains. it just doesnt move left/right but back and forward.. still some point to the opposite..