I am writing a function where I have two 3d points with coordinates {x, y, z} both with a line segment of a given length. I am trying to find a common endpoint between the two line segments closest to a given vector with coordinates {x, y, z}. I have interpreted them as spheres found the intersecting circle with center {h, k, l} with and its radius. I have then got the normal plane. I am stuck figuring out how to get from the circle and the normal plane with the given vector to finding the closest point on that circle. I have tried following Sphere-Sphere intersection and Circle-Sphere intersection

Current Code:

    float distance = sqrt((pow((point_1.x - point_0.x), 2) + pow((point_1.y - point_0.y), 2) + pow((point_1.z - point_0.z), 2)));

    float x = .5 + (pow(length_0, 2) - pow(length_1, 2))/(2*pow(distance, 2));

    point3d interSectionCenter;
    interSectionCenter.x = point_0.x + x * (point_1.x - point_0.x);
    interSectionCenter.y = point_0.y + x * (point_1.y - point_0.y);
    interSectionCenter.z = point_0.z + x * (point_1.z - point_0.z);

    float intersectionRadius = sqrt(pow(length_0, 2) - pow(x, 2) * pow(distance, 2));

    vector3d normalPlane;
    normalPlane.x = (point_1.x - point_0.x)/distance;
    normalPlane.y = (point_1.y - point_0.y)/distance;
    normalPlane.z = (point_1.z - point_0.z)/distance;  
    vector3d projection;
    float hint_dot_normal = (hint_direction.x * normalPlane.x) + (hint_direction.y * normalPlane.y) + (hint_direction.z * normalPlane.z);
    float normal_dot_normal = pow(normalPlane.x, 2) + pow(normalPlane.y, 2) + pow(normalPlane.z, 2);
    projection.x = (hint_dot_normal/normal_dot_normal) * normalPlane.x;
    projection.y = (hint_dot_normal/normal_dot_normal) * normalPlane.y;
    projection.z = (hint_dot_normal/normal_dot_normal) * normalPlane.z;

    vector3d tangent;
    crossProduct(normalPlane, vector3d{0, 1, 0}, tangent);
    float tangent_magnitude = sqrt((pow(tangent.x, 2) + pow(tangent.y, 2) + pow(tangent.z, 2)));
    tangent.x = tangent.x / tangent_magnitude;
    tangent.y = tangent.y / tangent_magnitude;
    tangent.z = tangent.z / tangent_magnitude;

    // Get the bitangent
    vector3d bitangent;
    crossProduct(tangent, normalPlane, bitangent);

    //Now get the point of intersection
    float dot_tangent_hint = (tangent.x * hint_direction.x) + (tangent.y * hint_direction.y) + (tangent.z * hint_direction.z);
    float dot_bitangent_hint = (bitangent.x * hint_direction.x) + (bitangent.y * hint_direction.y) + (bitangent.z * hint_direction.z);
    vector3d to_normalize;
    to_normalize.x = dot_tangent_hint * tangent.x + dot_bitangent_hint * bitangent.x;
    to_normalize.y = dot_tangent_hint * tangent.y + dot_tangent_hint *  bitangent.y;
    to_normalize.z = dot_tangent_hint * tangent.z + dot_tangent_hint * bitangent.z;
    float to_normalize_magnitude = sqrt(pow(to_normalize.x, 2) + pow(to_normalize.y, 2) + pow(to_normalize.z, 2));
    common_point.x = intersectionRadius * (to_normalize.x / to_normalize_magnitude);
    common_point.y = intersectionRadius * (to_normalize.y / to_normalize_magnitude);
    common_point.z = intersectionRadius * (to_normalize.z / to_normalize_magnitude);

I had code for the tangent and bitangent but it wasn't getting me very far. Essentially just took the cross product of the normal plane with a perpendicular plane then used that and the normal plane for the bitangent.

  • \$\begingroup\$ Where did you run into trouble following that answer? That will help us focus on helping with the specific parts you need help with, rather than repeating parts that already worked for you. \$\endgroup\$
    – DMGregory
    Jun 19 at 2:24
  • \$\begingroup\$ I essentially have it worked out up until the end I have a tangent and bitangent. I just am unsure of how to use all that information to find the spot on my circle closest to the point on the circle. \$\endgroup\$ Jun 19 at 3:16
  • \$\begingroup\$ Ahhh, that's a much simpler problem. Can you show us the code you have so far? That way we can show you how to write the final step in a way that works with what you have already. \$\endgroup\$
    – DMGregory
    Jun 19 at 12:00
  • \$\begingroup\$ @DMGregory added the code to the original post to make it easier :) \$\endgroup\$ Jun 19 at 17:34

If I understand your issue correctly (which I had trouble with) you should be able to find the point on the intersection circle closest to your target vector using the following:

vector3d targetVec = ...; // this is the vector which determines what point we choose on the intersection circle (I think you call this the hint vector)
vector3d closestPoint = ri * normalize(dot(ti_vec, targetVec)*ti_vec + dot(bi_vec, targetVec)*bi_vec);

Where ri is the radius of the intersection circle and ti_vec and bi_vec are the tangent vectors.

  • \$\begingroup\$ Just to make sure I am doing this right I am normalizing the resulting vector of dot(ti_vec, targetVec)*ti_vec + dot(bi_vec, targetVec)*bi_vec. Essentially getting that resulting vector, its magnitude, normalizing it then multiplying that by the radius for each x, y, z coordinate \$\endgroup\$ Jun 19 at 20:56
  • \$\begingroup\$ What do you mean by for each x,y,z coordinate? As I said the way you describe the situation confuses me a bit. As I understand it you have a random vector and you want to find the point closest to it on the intersection circle. The logic in my answer is that you project your hint vector on the circle plane and normalize that projection and then increase the magnitude by the circle radius in order to get a point on that circle. \$\endgroup\$
    – PentaKon
    Jun 19 at 21:30
  • \$\begingroup\$ Each vector3d has an X, Y, and Z component to it. So when you have vector3d closestPoint wouldn't I have to do that for the X, Y and Z component? \$\endgroup\$ Jun 19 at 21:35
  • \$\begingroup\$ Ah, I see what you mean. I thought you were using a math library that handles vector calculations for you (i.e. allowing you to do myVector * myScalar = scaledUpVector). Yes, what you mentioned is correct. \$\endgroup\$
    – PentaKon
    Jun 19 at 21:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.