{"spec_id":"mohr-circle","library":"makie","language":"julia","code":"# anyplot.ai\n# mohr-circle: Mohr's Circle for Stress Analysis\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 90/100 | Created: 2026-05-30\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# Theme tokens — Imprint palette, theme-adaptive chrome\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst INK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\n\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 — brand green (Imprint palette — always first series)\n    colorant\"#C475FD\",  # 2 — lavender\n    colorant\"#4467A3\",  # 3 — blue\n    colorant\"#BD8233\",  # 4 — ochre\n    colorant\"#AE3030\",  # 5 — matte red (semantic anchor for critical values)\n    colorant\"#2ABCCD\",  # 6 — cyan\n    colorant\"#954477\",  # 7 — rose\n    colorant\"#99B314\",  # 8 — lime\n]\n\n# Stress state: steel plate under combined biaxial loading and shear (MPa)\n# Pythagorean triple (3-4-5) gives clean radius = 50 MPa\nconst sigma_x = 80.0\nconst sigma_y = 20.0\nconst tau_xy  = 40.0\n\n# Mohr's circle geometry\nconst center_c    = (sigma_x + sigma_y) / 2.0\nconst radius      = sqrt(((sigma_x - sigma_y) / 2.0)^2 + tau_xy^2)\nconst sigma1      = center_c + radius\nconst sigma2      = center_c - radius\nconst tau_max     = radius\nconst two_theta_p = atan(tau_xy, sigma_x - center_c)\n\n# Circle (parametric, 360 points)\nconst n_pts    = 360\nconst angles   = LinRange(0.0, 2π, n_pts)\nconst circle_x = center_c .+ radius .* cos.(angles)\nconst circle_y = radius .* sin.(angles)\n\n# Title\nconst title_str = \"mohr-circle · julia · makie · anyplot.ai\"\nconst n_title   = length(title_str)\nconst title_sz  = round(Int, 20 * (n_title > 67 ? 67.0 / n_title : 1.0))\n\n# Figure — square canvas (2400×2400 via px_per_unit=2) for true circle aspect ratio\nfig = Figure(\n    size            = (1200, 1200),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = title_str,\n    titlesize          = title_sz,\n    titlecolor         = INK,\n    xlabel             = \"Normal Stress σ (MPa)\",\n    ylabel             = \"Shear Stress τ (MPa)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.10),\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.10),\n    xminorgridvisible  = false,\n    yminorgridvisible  = false,\n    aspect             = DataAspect(),\n)\n\n# Axis limits — equal ranges so DataAspect() fills the square canvas\nconst pad = 30.0\nxlims!(ax, sigma2 - pad, sigma1 + pad)\nylims!(ax, -(tau_max + pad), tau_max + pad)\n\n# Reference line: σ-axis (τ = 0)\nhlines!(ax, [0.0]; color = (INK_SOFT, 0.55), linewidth = 1.2)\n\n# Reference line: vertical through center C\nvlines!(ax, [center_c]; color = (INK_SOFT, 0.4), linewidth = 1.0, linestyle = :dash)\n\n# Mohr's circle — primary element, Imprint palette position 1 (green)\nlines!(ax, circle_x, circle_y; color = IMPRINT_PALETTE[1], linewidth = 2.8)\n\n# Diameter line from A to B (construction line)\nlines!(ax, [sigma_x, sigma_y], [tau_xy, -tau_xy];\n    color = (INK_MUTED, 0.55), linewidth = 1.4, linestyle = :dash)\n\n# Arc showing the principal-plane angle 2θp (measured at center C)\nconst arc_r    = radius * 0.30\nconst arc_angs = LinRange(0.0, two_theta_p, 50)\nconst arc_x    = center_c .+ arc_r .* cos.(arc_angs)\nconst arc_y    = arc_r .* sin.(arc_angs)\nlines!(ax, arc_x, arc_y; color = IMPRINT_PALETTE[4], linewidth = 2.2)\n\n# Center point C\nscatter!(ax, [center_c], [0.0]; color = INK, markersize = 9, strokewidth = 0)\n\n# Point A: (σx, τxy) — x-face of the stress element\nscatter!(ax, [sigma_x], [tau_xy];\n    color = IMPRINT_PALETTE[2], markersize = 17,\n    strokewidth = 1.5, strokecolor = PAGE_BG)\n\n# Point B: (σy, −τxy) — y-face of the stress element\nscatter!(ax, [sigma_y], [-tau_xy];\n    color = IMPRINT_PALETTE[3], markersize = 17,\n    strokewidth = 1.5, strokecolor = PAGE_BG)\n\n# Principal stress points σ1, σ2 (circle intersects σ-axis)\nscatter!(ax, [sigma1, sigma2], [0.0, 0.0];\n    color = IMPRINT_PALETTE[5], markersize = 17, marker = :diamond,\n    strokewidth = 1.5, strokecolor = PAGE_BG)\n\n# τ_max points (top and bottom of circle)\nscatter!(ax, [center_c, center_c], [tau_max, -tau_max];\n    color = IMPRINT_PALETTE[4], markersize = 17,\n    strokewidth = 1.5, strokecolor = PAGE_BG)\n\n# Annotations\nconst nudge = 3.0\nconst voff  = radius * 0.07\n\ntext!(ax, sigma1 + nudge, -voff;\n    text     = \"σ₁ = $(round(Int, sigma1)) MPa\",\n    color    = INK,\n    fontsize = 12,\n    align    = (:left, :top))\ntext!(ax, sigma2 - nudge, -voff;\n    text     = \"σ₂ = $(round(Int, sigma2)) MPa\",\n    color    = INK,\n    fontsize = 12,\n    align    = (:right, :top))\ntext!(ax, center_c + nudge, tau_max + voff;\n    text     = \"τmax = $(round(Int, tau_max)) MPa\",\n    color    = INK,\n    fontsize = 12,\n    align    = (:left, :bottom))\ntext!(ax, center_c - nudge, -(tau_max + voff);\n    text     = \"−τmax\",\n    color    = INK,\n    fontsize = 12,\n    align    = (:right, :top))\ntext!(ax, sigma_x + nudge, tau_xy;\n    text     = \"A ($(round(Int, sigma_x)), $(round(Int, tau_xy))) MPa\",\n    color    = IMPRINT_PALETTE[2],\n    fontsize = 11,\n    align    = (:left, :center))\ntext!(ax, sigma_y - nudge, -tau_xy;\n    text     = \"B ($(round(Int, sigma_y)), $(round(Int, -tau_xy))) MPa\",\n    color    = IMPRINT_PALETTE[3],\n    fontsize = 11,\n    align    = (:right, :center))\ntext!(ax, center_c, voff;\n    text     = \"C\",\n    color    = INK,\n    fontsize = 13,\n    align    = (:center, :bottom))\n\n# 2θp arc label\nconst mid_arc = two_theta_p / 2.0\ntext!(ax, center_c + arc_r * 1.45 * cos(mid_arc), arc_r * 1.45 * sin(mid_arc);\n    text     = \"2θₚ ≈ $(round(rad2deg(two_theta_p), digits=1))°\",\n    color    = IMPRINT_PALETTE[4],\n    fontsize = 11,\n    align    = (:left, :center))\n\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}