{
  "openapi": "3.1.1",
  "info": {
    "title": "Lens & Mirror Ray Tracer (ABCD + Real Rays) API",
    "version": "1.0.0",
    "summary": "Focal length, principal planes, image and spherical aberration of a lens or mirror system.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://prooflineraytracer.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Focal length, principal planes, image and spherical aberration of a lens or mirror system.",
        "description": "Describe a sequential optical system line by line — thin lenses, thick lenses, spherical or flat refracting surfaces with glass indices, spherical mirrors and gaps — and get the effective focal length, back and front focal distances, principal planes, the image position and magnification for an object distance, and the paraxial marginal and chief ray heights at every surface from ABCD ray-transfer matrices. Real rays are traced exactly through the spherical surfaces with Snell’s law to show the longitudinal and transverse spherical aberration, with an SVG ray diagram, an aberration plot and a chromatic focal-shift estimate from the glass Abbe number. Part of the Proofline math notebook.\n\nMethodology:\n- Paraxial optics with 2 × 2 ray-transfer (ABCD) matrices acting on the height y and the reduced angle n·u: a gap d in index n is [[1, d/n], [0, 1]], a refracting surface [[1, 0], [−(n′ − n)/R, 1]], a thin lens [[1, 0], [−1/f, 1]] and a mirror a refraction with n′ = −n (power −2n/R). The system matrix gives the power φ = −C, the effective focal length 1/φ, the back focal distance A·n′/φ, the front focal distance D·n/φ and the principal planes.\n- For a finite object the matrix is extended by the object distance; the image lies where the height of an axial ray returns to zero, and the lateral magnification is 1/D of the extended matrix.\n- Exact rays start at the axial object point (or parallel to the axis), are intersected with each spherical surface and refracted with the vector form of Snell’s law (or reflected); their axis crossings relative to the paraxial focus give the longitudinal spherical aberration, their heights in the paraxial image plane the transverse aberration. Thin lenses are treated as ideal paraxial lenses.\n- Chromatic estimate: nF − nC = (nd − 1)/νd from the glass Abbe number, split around nd; the paraxial calculation is repeated for the F and C lines.\n- Verified against the lensmaker’s equation with thickness, the ball-lens formula f = nD/4(n − 1), the two-lens formula 1/f = 1/f₁ + 1/f₂ − d/(f₁f₂), the exact single-surface and spherical-mirror intercepts, and the textbook result that a plano-convex lens with its curved side towards collimated light has about four times less spherical aberration than the other way round.\n\nA meridional, monochromatic 2-D model for checking and teaching: no skew rays, coma or astigmatism maps, vignetting by lens edges, tolerances or diffraction. Glass data are the d-line values of a few catalogue glasses; real designs need the full dispersion formula of the melt.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "proofline_ray_tracer",
        "x-owner-app": "proofline",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProoflineRayTracerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Plano-convex N-BK7 lens, curved side towards the light",
                  "value": {
                    "elements": "thick R1=51.68 R2=inf t=5 n=N-BK7",
                    "apertureRadius": 10,
                    "rays": 5
                  }
                },
                "example2": {
                  "summary": "Same lens turned round: flat side towards the light",
                  "value": {
                    "elements": "thick R1=inf R2=-51.68 t=5 n=N-BK7",
                    "apertureRadius": 10,
                    "rays": 5
                  }
                },
                "example3": {
                  "summary": "Biconvex thick lens imaging an object 150 mm away",
                  "value": {
                    "elements": "thick R1=50 R2=-50 t=10 n=1.5",
                    "objectDistance": "150",
                    "objectHeight": 10,
                    "apertureRadius": 5
                  }
                },
                "example4": {
                  "summary": "Two thin lenses 50 mm apart",
                  "value": {
                    "elements": "lens f=100\ngap 50\nlens f=100",
                    "apertureRadius": 8
                  }
                },
                "example5": {
                  "summary": "Concave spherical mirror R = −200 mm",
                  "value": {
                    "elements": "mirror R=-200",
                    "apertureRadius": 20,
                    "rays": 6
                  }
                },
                "example6": {
                  "summary": "Cemented achromat N-BAK4 / N-SF5 (thin-lens design for f = 100 mm)",
                  "value": {
                    "elements": "# crown: equiconvex N-BAK4\nsurface R=48.23 n=N-BAK4\ngap 6\n# cemented flint N-SF5\nsurface R=-48.23 n=N-SF5\ngap 2.5\nsurface R=-1876 n=1",
                    "apertureRadius": 10
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProoflineRayTracerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ProoflineRayTracerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "elements": {
            "title": "Optical system (one element per line)",
            "description": "Elements in the order the light meets them, lengths in mm: “lens f=100” (thin lens), “gap 20” (distance to the next element), “surface R=50 n=1.5168” (refracting surface into index n; R=inf for flat), “thick R1=50 R2=-50 t=6 n=N-BK7” (thick lens in the current medium), “mirror R=-200” (concave mirror facing the light). R > 0 when the centre of curvature is to the right. Glasses: N-BK7, N-BAK4, N-SK16, F2, N-SF5, N-SF11, fused silica, or a number with an optional Abbe number v=…; # starts a comment.",
            "type": "string",
            "maxLength": 4000
          },
          "objectDistance": {
            "title": "Object distance",
            "description": "Distance in mm from the object to the first element, or inf for an object at infinity (parallel light). Negative values mean a virtual object behind the first element.",
            "type": "string",
            "maxLength": 40,
            "default": "inf"
          },
          "objectHeight": {
            "title": "Object height",
            "description": "Finite objects: height of the object point the chief ray starts from.",
            "type": "number",
            "default": 10,
            "x-unit": "mm"
          },
          "fieldAngle": {
            "title": "Field angle",
            "description": "Objects at infinity: angle of the chief ray to the axis.",
            "type": "number",
            "minimum": -60,
            "maximum": 60,
            "default": 5,
            "x-unit": "°"
          },
          "apertureRadius": {
            "title": "Aperture radius",
            "description": "Semi-diameter of the beam at the first element (the aperture stop). The real rays fill it evenly.",
            "type": "number",
            "minimum": 0,
            "default": 10,
            "x-unit": "mm"
          },
          "rays": {
            "title": "Real rays",
            "description": "Number of exact rays between the axis and the aperture edge.",
            "type": "integer",
            "minimum": 1,
            "maximum": 12,
            "default": 5
          }
        },
        "required": [
          "elements"
        ]
      },
      "ProoflineRayTracerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "elementCount",
              "surfaces",
              "matrix",
              "efl",
              "power",
              "afocal",
              "frontFocalLength",
              "backFocalLength",
              "bfd",
              "ffd",
              "frontPrincipalPlane",
              "backPrincipalPlane",
              "fNumber",
              "object",
              "image",
              "apertureRadius",
              "endPlane",
              "realRays",
              "chromatic"
            ],
            "properties": {
              "elementCount": {
                "type": "integer"
              },
              "surfaces": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "surface",
                    "element",
                    "type",
                    "z",
                    "radius",
                    "focalLength",
                    "indexAfter",
                    "marginalHeight",
                    "chiefHeight"
                  ],
                  "properties": {
                    "surface": {
                      "type": "integer"
                    },
                    "element": {
                      "type": "integer"
                    },
                    "type": {
                      "type": "string"
                    },
                    "z": {
                      "type": "number"
                    },
                    "radius": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "focalLength": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "indexAfter": {
                      "type": "number"
                    },
                    "marginalHeight": {
                      "type": "number"
                    },
                    "chiefHeight": {
                      "type": "number"
                    }
                  }
                }
              },
              "matrix": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "A",
                  "B",
                  "C",
                  "D"
                ],
                "properties": {
                  "A": {
                    "type": "number"
                  },
                  "B": {
                    "type": "number"
                  },
                  "C": {
                    "type": "number"
                  },
                  "D": {
                    "type": "number"
                  }
                },
                "description": "Ray-transfer matrix from the first element to the end of the list, for (height, n·angle)."
              },
              "efl": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Effective focal length 1/φ in mm (null: afocal)."
              },
              "power": {
                "type": "number",
                "description": "Optical power φ in 1/mm."
              },
              "afocal": {
                "type": "boolean"
              },
              "frontFocalLength": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "backFocalLength": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "bfd": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Back focal distance from the end of the list along the light, mm."
              },
              "ffd": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Front focal distance: front focal point to the first element, mm."
              },
              "frontPrincipalPlane": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "H relative to the first element (+ = after it), mm."
              },
              "backPrincipalPlane": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "H′ relative to the end of the list along the light (− = before it), mm."
              },
              "fNumber": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "object": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "atInfinity",
                  "distance",
                  "height",
                  "fieldAngle"
                ],
                "properties": {
                  "atInfinity": {
                    "type": "boolean"
                  },
                  "distance": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "height": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "fieldAngle": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              },
              "image": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "distance",
                  "magnification",
                  "real",
                  "height"
                ],
                "properties": {
                  "distance": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "magnification": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "real": {
                    "type": "boolean"
                  },
                  "height": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              },
              "apertureRadius": {
                "type": "number"
              },
              "endPlane": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "z",
                  "direction",
                  "index"
                ],
                "properties": {
                  "z": {
                    "type": "number"
                  },
                  "direction": {
                    "type": "integer"
                  },
                  "index": {
                    "type": "number"
                  }
                }
              },
              "realRays": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "fraction",
                    "height",
                    "intercept",
                    "longitudinalAberration",
                    "transverseAberration",
                    "failed"
                  ],
                  "properties": {
                    "fraction": {
                      "type": "number"
                    },
                    "height": {
                      "type": "number"
                    },
                    "intercept": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "longitudinalAberration": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "transverseAberration": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "failed": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "chromatic": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "bfdF",
                  "bfdC",
                  "longitudinal",
                  "eflF",
                  "eflC"
                ],
                "properties": {
                  "bfdF": {
                    "type": "number"
                  },
                  "bfdC": {
                    "type": "number"
                  },
                  "longitudinal": {
                    "type": "number"
                  },
                  "eflF": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "eflC": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}