Hi, I’m trying to move my GameObject C at a position where the distance A-C and B-C are both a given distance while C must stay at his own height.
Description of the image:
C is the object I want to move
A & B are objects and I want C to be moved at a given distance from them
A & B spheres have both the radius of the given distance
The red circle is where both spheres are overlaping (at the given distance)
D & E are 2 positions where the distance to A & B are egal to the given distance while being are C height
The way I think it must be done:
Look if A & B spheres can overlap with the given radius
Find this red circle which is all intersection between the 2 spheres where the distance are the same
Find the 2 coordinates on the red circle where the height is egal to the C height
Move C to the D position
I don’t know if it’s the easier method or if I miss a build-in fonctionnality, I’m open to any other ideas.
I’m struggling with the math to find these D & E positions any suggestion ?
Can you just do the math to find the solution, or is that what you need help with? I don't think you are missing any tool.
Ok so I finally found a solution! I used a lot of vectors and Pythagoras.
Here is the simplified process:
Find the midpoint AB
Get the equidistant & horizontal vector from this midpoint AB
Move this vector to the desired height
Use Pythagoras to find the final position along this vector
public Transform pointA, pointB, pointC;
public float distanceFromPoints;
private float fixedHeight;
//Temporary positions
Vector3 midPointAB, equidistantPointAtFixedHeight;
//Resulting vectos
Vector3 directionAB, upAB, rightAB;
//Finals positions
Vector3 intersectionA, intersectionB;
public void MoveObject()
{
// Set example references
fixedHeight = 1.0f;
distanceFromPoints = 0.7f;
//Find AB midpoint
midPointAB = (pointA.position + pointB.position) / 2.0f;
//Find all AB Vectors
//Find AB direction (Green Gizmo)
directionAB = (pointB.position - pointA.position).normalized;
//Find AB right direction which horizontal & is perpendicular to directionAB, all the positions on this vector are equidistant to A & B (Red Gizmo)
rightAB = Vector3.Cross(directionAB, Vector3.up).normalized;
//Find AB up direction which is perpendicular to both previous vectors (Blue Gizmo)
upAB = Vector3.Cross(directionAB, -rightAB).normalized;
//Find the distance to go from midPointAB to a position where Y=fixedHeight
float upScaleFactor = (fixedHeight - midPointAB.y) / upAB.y;
//Find the point along upAB where Y=fixedHeight
equidistantPointAtFixedHeight = midPointAB + upAB * upScaleFactor;
//Use Pythagore find the distanceFromPoints on rightAB (white Gizmo)
float vertical = Vector3.Distance(pointA.position, equidistantPointAtFixedHeight); //Choose pointA or B do not matter since equidistantPointAtFixedHeight is equidistant with them
float hypothenuse = distanceFromPoints;
float distanceOnRightAB = (float)(Mathf.Sqrt(Mathf.Abs((hypothenuse * hypothenuse) - (vertical * vertical))));
//Move the vector rightAB to equidistantPointAtFixedHeight and add the distanceOnRightAB of find the 2 equidistant points
intersectionA = equidistantPointAtFixedHeight + rightAB * distanceOnRightAB;
intersectionB = equidistantPointAtFixedHeight - rightAB * distanceOnRightAB;
//Move Point C to the closer intersection
if (Vector3.Distance(pointC.transform.position, intersectionA) < Vector3.Distance(pointC.transform.position, intersectionB))
pointC.transform.position = intersectionA;
else
pointC.transform.position = intersectionB;
//Print if correct result is impossible
if (Mathf.Abs(Vector3.Distance(pointA.transform.position, pointC.transform.position) - distanceFromPoints) > 0.01f
|| Mathf.Abs(Vector3.Distance(pointB.transform.position, pointC.transform.position) - distanceFromPoints) > 0.01f)
Debug.Log("Points A & B are too far from each others");
// Print distances to prove it works
Debug.Log("Distance to A: " + Vector3.Distance(pointA.transform.position, pointC.transform.position) +
" / Distance to B: " + Vector3.Distance(pointB.transform.position, pointC.transform.position) +
" / Height: " + pointC.position.y +
" / Angle (Pythagore need 90): " + Vector3.Angle((equidistantPointAtFixedHeight - pointA.position).normalized, (equidistantPointAtFixedHeight - intersectionA).normalized));
}
[ExecuteInEditMode]
private void OnDrawGizmos()
{
// Draw directionAB vector
Gizmos.color = Color.green;
Gizmos.DrawLine(pointA.position, pointB.position);
// Draw upAB vector
Gizmos.color = Color.blue;
Gizmos.DrawLine(midPointAB, midPointAB + upAB * 2);
// Draw rightAB vector
Gizmos.color = Color.red;
Gizmos.DrawLine(midPointAB, midPointAB + rightAB * 2);
Gizmos.DrawLine(equidistantPointAtFixedHeight, equidistantPointAtFixedHeight + rightAB * 2);
//Draw Pythagore
Gizmos.color = Color.white;
Gizmos.DrawLine(pointA.position, equidistantPointAtFixedHeight);
Gizmos.DrawLine(pointA.position, intersectionA);
Gizmos.DrawLine(equidistantPointAtFixedHeight, intersectionA);
// Draw pointOnCVectorFromA and pointOnCVectorFromB
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(intersectionA, 0.05f);
Gizmos.DrawSphere(intersectionB, 0.05f);
}
There is a derivation for the circle defined by two intersecting spheres here:
The result is on steps 6 and 7. Since you have a fixed height, you would plug in the z value to get an equation for y^2, which will have two solutions.
Note that this derivation is done with one of the spheres at 0,0,0 and the other sphere offset only in the x direction. If the other sphere is at an arbitrary location, then you would have to modify step 2 and try to solve the resulting equations.
Some math variables:
r - radius
0 - dot with xyz = 0
A- = (Ax - Bx, 0, Az - Bz)
Aa:
A - name of object
a - name of axis
AB: distance between object A & object B
r of 2d circle on Cy (Cr) = Ar² / (Ay - Dy)²
Dz (if they’or on the same z, x if the same x, if not it, multiply it by abs of 0A- / 0B- or 0B- / 0A- if first is bigger than 1) = (Az > Bz? Az + Ar : Bz + Br) + (ACr > BCr? BCr - ACr : ACr - BCr)
ACr² = (Dz - Az)² + (Dx - Ax)²
ACr² = (Dz - Az)² + Dx² - 2Ax * Dx + Ax²
-Dx² = (Dz - Az)² - 2Ax * Dx + Ax² - ACr²
Dx² = (Dz - Az)² + 2Ax * Dx - Ax² + ACr²
Can you just do the math to find the solution, or is that what you need help with? I don't think you are missing any tool.
– PangaminiI don't know the math to find the intersection between 2 spheres, especially at a given height
– Nicolqs