# 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.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.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;
}
``````