zoom to - camera to object

I’m trying to make a script or find a script that allows me to adjust the camera position or focal length (FOV) so an object is covering “most” of the frame.

I see two variations of this:

  1. You have a target object (cube for example) and a target focal length (say 50mm lens).
    Script will find a camera position or distance from object where the entire object is fit into the camera frame.
    this would maybe measure the object and based on the field of view (number of degrees for 50mm), tell me how far from the object I need to be. assume there is a track to constraint so the camera is always aimed directly at the the object…

  2. the other variation. assume there is a track to constraint so the camera is always aimed directly at the the object… you give the script a position and it figures out how many mm your lens needs to be to auto zoom so the target object is covering most of the camera frame.

Has anybody ever heard of such a script or does anybody have any formulas or pointers to start with ?

This might be useful:

It glitches some times, not sure why.

this is what I have so far… still tweaking it but it basically figures out he distance of the object and uses the arc tangent to figure out the relative angle in relation to camera angle… the zoom out places the camera at the dof object (usualyl an empty with that camera has trackto constraint to) and zooms out until the object fills the camera view

class Cam_Pan_Helper:

	def __init__(self):
		self.oX = 0
		self.oY = 0
		self.oZ = 0
	def init_cam_data(self):
		self.cam = bpy.context.scene.camera

		self.cam.select = True
		bpy.context.scene.objects.active = self.cam

		self.oX = self.cam.location.x
		self.oY = self.cam.location.y
		self.oZ = self.cam.location.z
		self.lens = self.cam.data.lens

		if self.dof_object!=None:
			print("found DOF")
			self.oTX = self.dof_object.location.x
			self.oTY = self.dof_object.location.y
			self.oTZ = self.dof_object.location.z

	def find_dof(self,object):
		for constraint in object.constraints:
			if constraint.type == 'TRACK_TO':
				return constraint.target
		return None

	def get_object_largest_dimension(self,obj,usescale=False):
		max_obj_dimension = 0
		if usescale==True:

			if obj.scale.x>max_obj_dimension:
			if obj.scale.y>max_obj_dimension:
			if obj.scale.z>max_obj_dimension:

			if obj.dimensions.x>max_obj_dimension:
			if obj.dimensions.y>max_obj_dimension:
			if obj.dimensions.z>max_obj_dimension:
		return max_obj_dimension
	def get_distance_between_objects(self,o1,o2):
		camObj = self.cam
		x1 = o1.location.x
		y1 = o1.location.y
		z1 = o1.location.z
		x2 = o2.location.x
		y2 = o2.location.y
		z2 = o2.location.z

		xd = x2-x1
		yd = y2-y1
		zd = z2-z1
		dist = math.sqrt(xd*xd + yd*yd + zd*zd)

		return dist
	def get_relative_angle(self,max_object_dimension,distance):
		return relative_angle

	def zoom_out(self,obj,stepX,stepY,stepZ,zoom_limit=200):
		camObj = self.cam
		camObj.location.x = obj.location.x+stepX
		camObj.location.y = obj.location.y+stepY
		camObj.location.z = obj.location.z+stepZ
		cam_angle = camObj.data.angle
		print("Camera Angle: " + str(math.degrees(cam_angle)))
		continue_zoom = True
		while continue_zoom:

			relative_angle = self.get_object_relative_angle(obj)
			print("relative_angle:" + str(math.degrees(relative_angle)) + " cam_angle: " + str(math.degrees(cam_angle)))
			if cam_angle>(relative_angle*1.6):
				# at this point we have gone too far so set it to last good position
			# prevent something crazy from happening		
			if abs(camObj.location.x)>zoom_limit:
			if abs(camObj.location.y)>zoom_limit:
			if abs(camObj.location.z)>zoom_limit:
		print("finished loop")
		relative_angle = self.get_object_relative_angle(obj)
		print("relative_angle:" + str(math.degrees(relative_angle)) + " cam_angle: " + str(math.degrees(cam_angle)))

	def get_object_relative_angle(self,obj):		

		camObj = self.cam
		distance = self.get_distance_between_objects(obj,camObj)
		print("distance from Camera to target: " + str(distance))
		max_object_dimension = self.get_object_largest_dimension(obj,True)
		print("Max Object Dimension:" + str(max_object_dimension))
		print("Object Relative Angle:" + str(math.degrees(relative_angle)))
		return relative_angle