{"spec_id":"smith-chart-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# smith-chart-basic: Smith Chart for RF/Impedance\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 90/100 | Created: 2026-09-02\n\nusing CairoMakie\nusing Colors\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 BRAND    = colorant\"#009E73\"  # Imprint palette position 1 — always first series\nconst GRID     = RGBAf(INK.r, INK.g, INK.b, 0.35)\n\n# Data — antenna feed impedance across a parallel-RLC resonance (S11 sweep, 1-6 GHz)\nconst z0          = 50.0       # reference impedance, ohms\nconst resistance  = 75.0       # radiation resistance, ohms\nconst inductance  = 2.0e-9     # feed inductance, H\nconst capacitance = 1.034e-12  # feed capacitance, F — tuned for resonance near 3.5 GHz\n\nconst n_points      = 40\nconst frequency_hz  = collect(range(1.0e9, 6.0e9, length = n_points))\nconst frequency_ghz = frequency_hz ./ 1.0e9\nconst omega         = 2π .* frequency_hz\n\nconst admittance = (1 / resistance) .+ (im .* omega .* capacitance) .+\n                   (1 ./ (im .* omega .* inductance))\nconst impedance = 1 ./ admittance\nconst z_real    = real.(impedance)\nconst z_imag    = imag.(impedance)\n\nconst z_norm   = (z_real .+ im .* z_imag) ./ z0\nconst gamma    = (z_norm .- 1) ./ (z_norm .+ 1)\nconst gamma_re = real.(gamma)\nconst gamma_im = imag.(gamma)\n\n# Smith chart grid geometry\nconst n_circle  = 300\nconst theta     = range(0.0, 2π, length = n_circle)\nconst r_values  = [0.2, 0.5, 1.0, 2.0, 5.0]  # constant-resistance circles\nconst x_values  = [0.2, 0.5, 1.0, 2.0, 5.0]  # constant-reactance arcs (±)\nconst n_arc     = 2000\n\n# Title — fontsize scales down for titles longer than the 67-char baseline\ntitle_str  = \"Antenna S11 Sweep · smith-chart-basic · julia · makie · anyplot.ai\"\nn_title    = length(title_str)\ntitle_size = round(Int, 20 * (n_title > 67 ? 67.0 / n_title : 1.0))\n\n# Figure — square canvas (2400×2400 via px_per_unit=2): a Smith chart is a\n# circular diagram with no preferred horizontal axis\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_size,\n    titlecolor         = INK,\n    backgroundcolor    = PAGE_BG,\n    aspect             = DataAspect(),\n    xgridvisible       = false,\n    ygridvisible       = false,\n    xticksvisible      = false,\n    yticksvisible      = false,\n    xticklabelsvisible = false,\n    yticklabelsvisible = false,\n    leftspinevisible   = false,\n    rightspinevisible  = false,\n    topspinevisible    = false,\n    bottomspinevisible = false,\n)\n\nxlims!(ax, -1.3, 1.3)\nylims!(ax, -1.3, 1.3)\n\n# Chart boundary — |Γ| = 1, total reflection\nlines!(ax, cos.(theta), sin.(theta); color = INK_SOFT, linewidth = 2.2)\n\n# Zero-reactance diameter — the matched condition Z = Z0 sits at the origin\nlines!(ax, [-1.0, 1.0], [0.0, 0.0]; color = GRID, linewidth = 1.4)\n\n# Constant-resistance circles r = 0.2, 0.5, 1, 2, 5 — always fully inside the unit disk\nfor r in r_values\n    cx     = r / (1 + r)\n    radius = 1 / (1 + r)\n    lines!(ax, cx .+ radius .* cos.(theta), radius .* sin.(theta);\n        color = GRID, linewidth = 1.4)\nend\n\n# Constant-reactance arcs x = ±0.2, ±0.5, ±1, ±2, ±5 — trimmed to the unit disk.\n# Every such circle passes through Γ = 1; the disk-interior stretch is found by\n# walking outward from that anchor point in both angular directions.\nfor x in vcat(x_values, -x_values)\n    rc     = 1.0 / x\n    radius = abs(rc)\n    anchor = rc > 0 ? -π / 2 : π / 2\n    psi    = range(-π, π, length = n_arc)\n    phi    = anchor .+ psi\n    px     = 1.0 .+ radius .* cos.(phi)\n    py     = rc .+ radius .* sin.(phi)\n    inside = (px .^ 2 .+ py .^ 2) .<= 1.0 + 1.0e-6\n\n    mid = n_arc ÷ 2 + 1\n    lo, hi = mid, mid\n    while lo > 1 && inside[lo - 1]\n        lo -= 1\n    end\n    while hi < n_arc && inside[hi + 1]\n        hi += 1\n    end\n\n    lines!(ax, px[lo:hi], py[lo:hi]; color = GRID, linewidth = 1.4)\nend\n\n# Matched-condition point — Z = Z0, Γ = 0\nscatter!(ax, [0.0], [0.0]; color = INK_SOFT, markersize = 6, strokewidth = 0)\n\n# Impedance locus — antenna feed impedance trajectory across the frequency sweep\nlines!(ax, gamma_re, gamma_im; color = BRAND, linewidth = 2.75)\nscatter!(ax, gamma_re, gamma_im;\n    color = BRAND, markersize = 9, strokewidth = 1.0, strokecolor = PAGE_BG)\n\n# Frequency labels at key points along the locus\nlabel_idx = [1, round(Int, n_points / 2), n_points]\nfor i in label_idx\n    gx, gy       = gamma_re[i], gamma_im[i]\n    r_i          = hypot(gx, gy)\n    dir_x, dir_y = r_i > 1.0e-6 ? (gx / r_i, gy / r_i) : (1.0, 0.0)\n    lx, ly       = gx + 0.10 * dir_x, gy + 0.10 * dir_y\n\n    scatter!(ax, [gx], [gy];\n        color = BRAND, markersize = 16, strokewidth = 1.5, strokecolor = PAGE_BG)\n    text!(ax, lx, ly; text = \"$(round(frequency_ghz[i], digits = 1)) GHz\",\n        color = INK, fontsize = 15, align = (:center, :center))\nend\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}