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;  
}