Get Intersection of a Line and a Circle?

Basically I am trying to make objects which are outside my minimap appear on the edge of the map’s circle. (The map overlay is masked with a circle image). The object that I’m trying to manipulate (move to the edge of the circle) is only seen by the map camera, and represents an object in the scene… So I want to move that object to the edge of the circle.

I have figured out how to get a Vector3 that represents the normalized direction to the center of the map (where the main character is). What I can’t figure out is how to get the position of the intersection between a raycast from the object and the edge of a circle centered on the main character. I’m guessing there’s a way to do this without even using a ray or collider? That would be good since a collider that is almost as big as the room that contains my character would cause lots of other problems for me.

I don’t know trigonometry or calculus or whatever is required to understand how to solve that problem. I wish I had taken more math classes!

Can anyone help me?

TLDR; How do I find the position where a line (direction) from an object intersects a radius surrounding my character?

public static int BetweenLineAndCircle(
Vector2 circleCenter, float circleRadius,
Vector2 point1, Vector2 point2,
out Vector2 intersection1, out Vector2 intersection2)
{
float t;

    var dx = point2.x - point1.x;
    var dy = point2.y - point1.y;

    var a = dx * dx + dy * dy;
    var b = 2 * (dx * (point1.x - circleCenter.x) + dy * (point1.y - circleCenter.y));
    var c = (point1.x - circleCenter.x) * (point1.x - circleCenter.x) + (point1.y - circleCenter.y) * (point1.y - circleCenter.y) - circleRadius * circleRadius;

    var determinate = b * b - 4 * a * c;
    if ((a <= 0.0000001) || (determinate < -0.0000001))
    {
        // No real solutions.
        intersection1 = Vector2.zero;
        intersection2 = Vector2.zero;
        return 0;
    }
    if (determinate < 0.0000001 && determinate > -0.0000001)
    {
        // One solution.
        t = -b / (2 * a);
        intersection1 = new Vector2(point1.x + t * dx, point1.y + t * dy);
        intersection2 = Vector2.zero;
        return 1;
    }
    
    // Two solutions.
    t = (float)((-b + Math.Sqrt(determinate)) / (2 * a));
    intersection1 = new Vector2(point1.x + t * dx, point1.y + t * dy);
    t = (float)((-b - Math.Sqrt(determinate)) / (2 * a));
    intersection2 = new Vector2(point1.x + t * dx, point1.y + t * dy);

    return 2;
}

As for the math you want, its actually just Trig:

The X component is Cos(theta) * circle radius.
The Y Component is Sin(theta) * circle radius.

Theta is just your characters Y rotation, converted to radians (Angle * (180 / Pi))

So here’s what I have based on what we’ve talked about:

public GameObject character;
public GameObject target;
public float mapRadius = 3;
Vector3 heading;
float distance;
Vector3 direction;
float relX;
float relZ;
float theta;


void Start () {
	
}

void Update () {
	
	heading = target.transform.position - character.transform.position;
	distance = heading.magnitude;
	
	if(distance > mapRadius) {
		
		direction = heading / distance;
		theta = direction.y;
		relX = Mathf.Pow(Mathf.Cos(theta) * mapRadius, 2);
		relZ = Mathf.Pow(Mathf.Sin(theta) * mapRadius, 2);
		
		Debug.Log(relX + relZ);// always prints "0"
		
		float newX = character.transform.position.x + relX;
		float newZ = character.transform.position.x + relZ;
		
		gameObject.transform.position = new Vector3(newX, 0, newZ);
		
	}
}

The Debug.Log line always prints “0” but I thought it should print “1” or my mapRadius value?

Even though the relX and relZ are always 0, the object I intend to move (which has the above script attached to it) does in fact move… but it moves diagonally based on the character’s x position. It does not constrain to a circle.

I’m confused. See anything that I’m doing wrong?

Thanks!

Hi there,
The KGFMapSystem already solves this problem by showing an arrow or any other marker for objects outside the minimap area.

It is highly customizeable and comes with a lot of other features you may need. Check it out:

webdemo: http://www.kolmich.at/kolmich/demo/kgf/KGFMinimap/KGFMinimap.html

documentation: http://www.kolmich.at/documentation

assetstore: http://u3d.as/content/kolmich-creations/kgfmap-system/3bf