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