How can I create a mathematically correct arc/circular segment?
Add Primitive Arc Operator

The theory is well covered here Calculate the radius of a circle given the chord length and height of a segment
The text editor &gt; Templates &gt; Python &gt; Operator Add Mesh template modified to add an arc.
Input the arc length, arc height and number of segments and it creates an arc.
Notes. Haven't dealt with the restriction that arc height can only ever by at most half chord length for a semi circle.
bl_info = {
    &quot;name&quot;: &quot;Circular Arc&quot;,
    &quot;author&quot;: &quot;batFINGER&quot;,
    &quot;version&quot;: (1, 0),
    &quot;blender&quot;: (2, 80, 0),
    &quot;location&quot;: &quot;View3D &gt; Add &gt; Mesh &gt; Circular Arc&quot;,
    &quot;description&quot;: &quot;Adds a mesh circumcircle given base and height&quot;,
    &quot;warning&quot;: &quot;&quot;,
    &quot;doc_url&quot;: &quot;&quot;,
    &quot;category&quot;: &quot;Add Mesh&quot;,
}


import bpy
import bmesh
from mathutils import Matrix
from math import asin
from bpy_extras.object_utils import AddObjectHelper

from bpy.props import (
    IntProperty,
    BoolProperty,
    FloatProperty,
)


class MESH_OT_primitive_arc_add(AddObjectHelper, bpy.types.Operator):
    &quot;&quot;&quot;Add a simple arc mesh&quot;&quot;&quot;
    bl_idname = &quot;mesh.primitive_arc_add&quot;
    bl_label = &quot;Add Circular Arc&quot;
    bl_options = {'REGISTER', 'UNDO'}

    length: FloatProperty(
        name=&quot;length&quot;,
        description=&quot;Chord Length&quot;,
        min=0.01,
        max=100.0,
        default=2.0,
        unit='LENGTH',
    )
    height: FloatProperty(
        name=&quot;Height&quot;,
        description=&quot;Arc Height&quot;,
        min=0.01,
        max=100.0,
        unit='LENGTH',
        default=1.0,
    )
    segments: IntProperty(
        name=&quot;Arc Segments&quot;,
        description=&quot;Number of Segments&quot;,
        min=1,
        default=8,
    )

    def draw(self, context):
        '''Generic Draw'''
        layout = self.layout
        # annnotated on this class
        for prop in self.__class__.__annotations__.keys():
            layout.prop(self, prop)
        # annotated on AddObjectHelper
        for prop in AddObjectHelper.__annotations__.keys():
            layout.prop(self, prop)


    def execute(self, context):
        h = self.height
        a = self.length / 2
        r = (a * a + h * h) / (2 * h)
        if abs(a / r) &gt; 1:
            # math domain error on arcsin
            return {'CANCELLED'}
        angle = 2 * asin(a / r)

        mesh = bpy.data.meshes.new(&quot;Arc&quot;)

        bm = bmesh.new()
        v = bm.verts.new((0, r, 0))
        bmesh.ops.rotate(
            bm, verts=[v], matrix=Matrix.Rotation(angle / 2, 3, 'Z'))
        bmesh.ops.spin(
            bm,
            geom=[v],
            axis=(0, 0, 1),
            steps=self.segments,
            angle=-angle,
        )

        for v in bm.verts:
            v.co.y -= r - h
            v.select = True
        bm.to_mesh(mesh)
        #mesh.update()

        # add the mesh as an object into the scene with this utility module
        from bpy_extras import object_utils
        object_utils.object_data_add(context, mesh, operator=self)

        return {'FINISHED'}


def menu_func(self, context):
    self.layout.operator(MESH_OT_primitive_arc_add.bl_idname, icon='MESH_CUBE')


def register():
    bpy.utils.register_class(MESH_OT_primitive_arc_add)
    bpy.types.VIEW3D_MT_mesh_add.append(menu_func)


def unregister():
    bpy.utils.unregister_class(MESH_OT_primitive_arc_add)
    bpy.types.VIEW3D_MT_mesh_add.remove(menu_func)


if __name__ == &quot;__main__&quot;:
    register()

    # test call
    bpy.ops.mesh.primitive_arc_add()