placing an object at an intersection point



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/06/2011 at 00:58, xxxxxxxx wrote:

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

    ---------
    Hi,

    I have two objects in the scene..
    First one is a surface like polygon object (a landscape).
    Second is some other cube or something like that...

    What I want to do is that: I want to place second object right on first object's surface.. This is like "align to spline" tag but instead of a spline, I have a plane... i.e. I have a landscape like scene and I have lots of trees and I want to position trees using top view and my script will automatically position trees' Y component to make each of them right on landscape's surface...

    I have an algorithm in mind but I have no idea how to implement it.

    if COFFEE does have a function which returns the intersection list of an object (with lots of polygon) and a line then:

    (x1, y1, z1) = second objects pivot position (I will move pivot of the object to its bottom)
    PointList = all geometrical points of first object which intersects with the universal line (X=x1, Z=z1)..
    y1 = PointList[0].Y;

    if COFFEE does NOT have a function which return intersection of an object and a line then:

    (x1, y1, z1) = second objects pivot position (I will move pivot of the object to its bottom)
    for each polygon in first object
       PointList.add(intersection of current polygon with the universal line (X=x1, Z=z1) )
    y1 = PointList[0].Y;

    if COFFEE does NOT have a function which finds intersection of a polygon and a line; I will have to write it myself but I do not think that I can do that either :(

    I may have complicated the nature of my problem,
    Thank you anyway :)



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/06/2011 at 03:21, xxxxxxxx wrote:

    AFAIK, Coffee does not have the ColliderEngine or RayCollider classes. It'll have to be C++ or Python (or XPresso, if simple Ray Collision is sufficient for your purpose).

    P.S.: If you have a Coffee question, it's not much use checking all available languages when posting ;-)



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/06/2011 at 03:43, xxxxxxxx wrote:

    Hi C4dJack,

    First of all, thanks for the quick response....

    Your answer clears things up a bit... Now, how can I make this post a C++ and/or python question??? :))) or better, can you help me assuming that this post is marked as "C++"?? :)

    thanks again,

    ps: Actually, it is better if I can find a solution on C++. Or any example which uses some object geometry is very welcome...



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/06/2011 at 06:50, xxxxxxxx wrote:

    Ray-Triangle intersection isn't that difficult and it should be possible even with COFFEE (but it will be significantly slower than C++).  Note that it is easier to use a triangulated object as quadrangles and n-gons are not guaranteed to be planar or convex.  Note that some of the variables like 'p0' and 'p1' are class members.

    // DIRayCollider.Init  
    //*---------------------------------------------------------------------------*  
    void DIRayCollider::Init(BaseObject* goal)  
    //*---------------------------------------------------------------------------*  
    {  
      PolygonObject*    pobj =    (PolygonObject* )goal;  
    #ifdef    C4D_R11  
      points =    pobj->GetPointW();  
      poly =        pobj->GetPolygonW();  
    #else  
      points =    pobj->GetPoint();  
      poly =        pobj->GetPolygon();  
    #endif  
      lastPoly =    poly + pobj->GetPolygonCount();  
      gmat =        pobj->GetMg();  
    }  
    // DIRayCollider.Intersect  
    // - Returns the nearest distance intersection  
    //*---------------------------------------------------------------------------*  
    Bool DIRayCollider::Intersect(const Vector& ray_p0, const Vector& ray_p1, Real* distance)  
    //*---------------------------------------------------------------------------*  
    {  
      p0 =            LVector(ray_p0.x, ray_p0.y, ray_p0.z);  
      p1 =            LVector(ray_p1.x, ray_p1.y, ray_p1.z);  
      *distance =        BIGPOSREAL;  
      
      UCHAR            res;  
      Bool            intersection =    FALSE;  
      Real            dist;  
      
      // Get intersections, if any, and retain nearest  
      for (CPolygon* p = poly; p != lastPoly; ++p)  
      {  
          v0 =    gmat*points[p->a];  
          v1 =    gmat*points[p->b];  
          v2 =    gmat*points[p->c];  
          res =    intersect_RayTriangle(LVector(v0.x, v0.y, v0.z), LVector(v1.x, v1.y, v1.z), LVector(v2.x, v2.y, v2.z));  
          if (res < 1)    continue;  
          if (res == 1)  
          {  
              intersection =    TRUE;  
              dist =            LDistance(p0, hitpos);  
              if (dist < *distance) *distance = dist;  
          }  
          else if    (res == 2)  
          {  
              *distance =    0.0;  
              return TRUE;  
          }  
      }  
      return intersection;  
    }  
    // DIRayCollider.Intersect  
    // anything that avoids division overflow  
    #define SMALL_NUM    0.00000001f  
    //*---------------------------------------------------------------------------*  
    CHAR DIRayCollider::intersect_RayTriangle(const LVector& lv0, const LVector& lv1, const LVector& lv2)  
    //*---------------------------------------------------------------------------*  
    {  
      // triangle vectors  
      // get triangle edge vectors and plane normal  
      LVector    u =        lv1 - lv0;  
      LVector    v =        lv2 - lv0;  
      LVector    n =        u % v;                    // cross product  
      // triangle is degenerate  
      if (n == (LVector)0)  
          return -1;                    // do not deal with this case  
      
      LVector    dir =    p1 - p0;                // ray direction vector  
      LVector    w0 =    p0 - lv0;  
      // params to calc ray-plane intersect  
      LReal    a =        -(n * w0);  
      LReal    b =        n * dir;  
      // ray is parallel to triangle plane  
      if (fabs(b) < SMALL_NUM)  
      {  
          // ray lies in triangle plane  
          if (a == 0)    return 2;  
          // ray disjoint from plane  
          else        return 0;  
      }  
      
      // get intersect point of ray with triangle plane  
      LReal    r = a / b;  
      // ray goes away from triangle  
      if (r < 0.0)    return 0;                    // => no intersect  
      // for a segment, also test if (r > 1.0) => no intersect  
      
      // intersect point of ray and plane  
      hitpos = p0 + r * dir;  
      
      // is I inside T?  
      LReal    uu = u * u;  
      LReal    uv = u * v;  
      LReal    vv = v * v;  
      LVector    w = hitpos - lv0;  
      LReal    wu = w * u;  
      LReal    wv = w * v;  
      LReal    D = 1.0 / (uv * uv - uu * vv);  
      
      // get and test parametric coords  
      a = (uv * wv - vv * wu) * D;  
      // I is outside T  
      if ((a < 0.0) || (a > 1.0))            return 0;  
      b = (uv * wu - uu * wv) * D;  
      // I is outside T  
      if ((b < 0.0) || ((a + b) > 1.0))    return 0;  
      
      // I is in T  
      return 1;  
    }
    

Log in to reply