Setting camera to position where it can render a seamless repetable orthographic scen

I’m using 3d to speed up production of 2d graphics of machines and structures (which have a lot of straight lines, objects and little details repeated all over the place).
The goal is to have an isometric background image that repeats seamless. I set the camera with orthographic projection and 45° of rotation.


The scene from another angle:


And manually cut the vertical borders in an image editor in the position where it repeats. Then I can do something like this:


Instead of cutting it manually every time I do a test, I would like to set the camera view position and height from Blender. Then I can render an already seamless repeated image.
Those two Empty objects in the boundaries are where the camera borders should be. However I have no clue how to accurately set up the camera in this case. How can I do this?

Create a mesh edge or curve spline between the two, which would help to select it and search for “camera fit frame to selected” operator, which in turn will put the borders exactly where the empties are. If you want to use existing empties, vertex snapping helps to position them.

If you want to keep using empties, could use them as hooks for the vertices/handles and have them deform the edge/spline as they’re moved.

This methods deal with scale but the image size don’t change.
I need to change render resolution too to fit the borders.

So I come up with an operator that change the camera scale and render dimensions to fit the boundary box of a mesh.
I can create a plane where I want the borders.


Then I find the adjacent (plane_height * cos(camera.rotation_euler.x)). Divide the render width by the aspect ratio of plane_width / projected_plane_height to find the render height.

The operator align the camera, keeps the render width I want and change height to match.

import bpy
import math
import mathutils

class FitRenderBorder(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "view3d.fit_render_border"
    bl_label = "Fit camera and resolution to selected object"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        render = context.scene.render
        camera = context.scene.camera
        frame = context.active_object
        
        # Size
        frame_projected_height = frame.dimensions.y * math.sin(camera.rotation_euler.x)
        height = render.resolution_x / (frame.dimensions.x / frame_projected_height)

        # Set location
        bpy.ops.view3d.camera_to_view_selected()
        position = mathutils.Vector((0.0, 0.0, frame_projected_height))
        inverse = camera.matrix_world.copy()
        inverse.invert()
        new_position = position * inverse
        camera.location = camera.location + new_position

        # Render settings
        camera.data.ortho_scale = frame.dimensions.x
        render.resolution_y = height

        return {'FINISHED'}


def register():
    bpy.utils.register_class(FitRenderBorder)


def unregister():
    bpy.utils.unregister_class(FitRenderBorder)


if __name__ == "__main__":
    register()