Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    tangent of spline point

    SDK Help
    0
    17
    1.9k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 02/05/2013 at 11:28, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   r14 
      Platform:      
      Language(s) :     C++  ;

      ---------
      hi, can someone tell me how i can get the tangent at point(x) of a spline, where x is a number in GetPointCount? or how i get the spline position that point x has, so i can use GetSplineTangent?

      anyone?

      cheers,
      ello

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 02/05/2013 at 12:38, xxxxxxxx wrote:

        Read the about SplineObject class in the SDK it has methods to deal with tangents. 
        Or get your spline objects tags, it will return a hidden PointTag like all PointObjects 
        do and a TangentTag. To understand point and tangent tags read about VariableTag 
        in the SDK.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 02/05/2013 at 14:07, xxxxxxxx wrote:

          but how do i access the spline tangent at a real point, not at the position (0...1)along the spline. thats my problem.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 02/05/2013 at 15:05, xxxxxxxx wrote:

            Your first posting implied that you want to get the tangents for the control points of your spline, 
            as you spoke of PointObject.GetPointCount(). Both PointTags and TangentTags hold the data of
            control points/ vertices . In the SplineObject there are the GetTangent methods to access the 
            indexed tangents.

            I am not sure what you do understand as a 'real' point, as you seem to refer to a vector with it,
            while the term real in that context is actually bound to 0.0-1.0 offset - real offset as a reference 
            to the space in real world units (200cm instead of 0.5).
            If you just want to sample an arbitrary point between two vertices aka control points, I am not 
            sure why cannot use the general real offset methods provided by cinema 4d. There is also the
            SplineHelper class providing some convenience methods to handle spline objects. You can also
            get the underlying LineObject of a spline to access the sampled sub points rather than dealing
            with mathematical perfect representation of the spline.

            Happy rendering,
            Ferdinand

            edit: fixed some bs i wrote 😉

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                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

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  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

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    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

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      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.

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        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...

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

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

                          double post, sorry.

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            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

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              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...

                              1 Reply Last reply Reply Quote 0
                              • H
                                Helper
                                last edited by

                                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...

                                1 Reply Last reply Reply Quote 0
                                • H
                                  Helper
                                  last edited by

                                  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

                                  http://www.file-upload.net/download-7562607/spline-tangents.zip.html

                                  1 Reply Last reply Reply Quote 0
                                  • H
                                    Helper
                                    last edited by

                                    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).

                                    1 Reply Last reply Reply Quote 0
                                    • H
                                      Helper
                                      last edited by

                                      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..

                                      1 Reply Last reply Reply Quote 0
                                      • First post
                                        Last post