{"spec_id":"mohr-circle","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' mohr-circle: Mohr's Circle for Stress Analysis\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 89/100 | Created: 2026-05-30\n\nlibrary(ggplot2)\nlibrary(ragg)\n\n# Theme tokens (Imprint palette — theme-adaptive chrome)\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\nINK_MUTED   <- if (THEME == \"light\") \"#6B6A63\" else \"#A8A79F\"\n\nIMPRINT_PALETTE <- c(\n  \"#009E73\",  # 1 brand green — circle + principal stress markers\n  \"#C475FD\",  # 2 lavender\n  \"#4467A3\",  # 3 blue — point A\n  \"#BD8233\",  # 4 ochre — max shear stress points\n  \"#AE3030\",  # 5 matte red — point B\n  \"#2ABCCD\",  # 6 cyan\n  \"#954477\",  # 7 rose\n  \"#99B314\"   # 8 lime\n)\n\n# Stress state (MPa) — structural member under combined axial and shear loading\nsigma_x <- 80\nsigma_y <- -20\ntau_xy  <- 40\n\n# Mohr's circle parameters\ncenter_x    <- (sigma_x + sigma_y) / 2\nradius      <- sqrt(((sigma_x - sigma_y) / 2)^2 + tau_xy^2)\nsigma_1     <- center_x + radius\nsigma_2     <- center_x - radius\ntau_max     <- radius\ntwo_theta_p <- atan2(tau_xy, (sigma_x - sigma_y) / 2) * 180 / pi\n\n# Circle path (360 points)\ntheta_seq <- seq(0, 2 * pi, length.out = 360)\ncircle_df <- data.frame(\n  x = center_x + radius * cos(theta_seq),\n  y = radius * sin(theta_seq)\n)\n\n# Arc showing 2θp angle (measured from horizontal to line C to A at center)\narc_r   <- radius * 0.28\narc_seq <- seq(0, two_theta_p * pi / 180, length.out = 80)\narc_df  <- data.frame(\n  x = center_x + arc_r * cos(arc_seq),\n  y = arc_r * sin(arc_seq)\n)\nmid_angle   <- two_theta_p * pi / 360\narc_label_x <- center_x + arc_r * 1.5 * cos(mid_angle)\narc_label_y <- arc_r * 1.5 * sin(mid_angle)\n\n# Build labels using paste0 with unicode escapes so Edit tool can match ASCII source\nsigma_sym  <- \"σ\"\ntau_sym    <- \"τ\"\ntheta_sym  <- \"θ\"\ndeg_sym    <- \"°\"\nsub1       <- \"₁\"\nsub2       <- \"₂\"\n\nlabel_A     <- paste0(\"A  (\", sigma_sym, \"x=\", sigma_x, \")\")\nlabel_B     <- paste0(\"B  (\", sigma_sym, \"y=\", sigma_y, \")\")\nlabel_s1    <- paste0(sigma_sym, \"1=\", round(sigma_1, 1))\nlabel_s2    <- paste0(sigma_sym, \"2=\", round(sigma_2, 1))\nlabel_tmax  <- paste0(tau_sym, \"max=\", round(tau_max, 1))\nlabel_2tp   <- paste0(\"2\", theta_sym, \"p=\", round(two_theta_p, 1), deg_sym)\n\n# Grid lines with alpha (major and minor differentiated)\ngrid_color       <- adjustcolor(INK, alpha.f = 0.08)\ngrid_color_minor <- adjustcolor(INK, alpha.f = 0.05)\n\np <- ggplot() +\n  # Reference lines through center\n  geom_hline(yintercept = 0,\n             color = adjustcolor(INK_SOFT, alpha.f = 0.55),\n             linewidth = 0.5, linetype = \"dashed\") +\n  geom_vline(xintercept = center_x,\n             color = adjustcolor(INK_SOFT, alpha.f = 0.55),\n             linewidth = 0.5, linetype = \"dashed\") +\n  # Diameter line connecting A and B (passes through center C)\n  annotate(\"segment\",\n           x = sigma_x, y = tau_xy, xend = sigma_y, yend = -tau_xy,\n           color = INK_MUTED, linewidth = 0.8, linetype = \"dotted\") +\n  # Mohr's circle (primary element — Imprint brand green)\n  geom_path(data = circle_df, aes(x = x, y = y),\n            color = IMPRINT_PALETTE[1], linewidth = 1.5) +\n  # Arc showing angle 2θp\n  geom_path(data = arc_df, aes(x = x, y = y),\n            color = INK_SOFT, linewidth = 0.7) +\n  # Center point (filled circle marker)\n  annotate(\"point\", x = center_x, y = 0,\n           color = INK, fill = PAGE_BG, size = 3.5, shape = 21, stroke = 0.8) +\n  # Principal stress points sigma1, sigma2 (where circle meets sigma-axis)\n  annotate(\"point\", x = sigma_1, y = 0,\n           color = \"white\", fill = IMPRINT_PALETTE[1], size = 5.5, shape = 23,\n           stroke = 0.5) +\n  annotate(\"point\", x = sigma_2, y = 0,\n           color = \"white\", fill = IMPRINT_PALETTE[1], size = 5.5, shape = 23,\n           stroke = 0.5) +\n  # Maximum shear stress points (top and bottom of circle)\n  annotate(\"point\", x = center_x, y = tau_max,\n           color = \"white\", fill = IMPRINT_PALETTE[4], size = 4.5, shape = 24,\n           stroke = 0.5) +\n  annotate(\"point\", x = center_x, y = -tau_max,\n           color = \"white\", fill = IMPRINT_PALETTE[4], size = 4.5, shape = 25,\n           stroke = 0.5) +\n  # Stress point A (sigma_x, tau_xy) — upper right\n  annotate(\"point\", x = sigma_x, y = tau_xy,\n           color = \"white\", fill = IMPRINT_PALETTE[3], size = 5.0, shape = 21,\n           stroke = 0.5) +\n  # Stress point B (sigma_y, -tau_xy) — lower left\n  annotate(\"point\", x = sigma_y, y = -tau_xy,\n           color = \"white\", fill = IMPRINT_PALETTE[5], size = 5.0, shape = 21,\n           stroke = 0.5) +\n  # Label A: positioned to the left+above to stay within panel\n  annotate(\"text\", x = sigma_x - 3, y = tau_xy + 6,\n           label = label_A,\n           color = IMPRINT_PALETTE[3], hjust = 1, vjust = 0, size = 3.8) +\n  # Label B: positioned to the right+below to stay within panel\n  annotate(\"text\", x = sigma_y + 3, y = -tau_xy - 6,\n           label = label_B,\n           color = IMPRINT_PALETTE[5], hjust = 0, vjust = 1, size = 3.8) +\n  # Label sigma1: centered below intersection (outside lower arc)\n  annotate(\"text\", x = sigma_1, y = -9,\n           label = label_s1,\n           color = INK, hjust = 0.5, vjust = 1, size = 3.8) +\n  # Label sigma2: centered below intersection (outside lower arc)\n  annotate(\"text\", x = sigma_2, y = -9,\n           label = label_s2,\n           color = INK, hjust = 0.5, vjust = 1, size = 3.8) +\n  # Label tmax: to the left of top point (toward center)\n  annotate(\"text\", x = center_x - 3, y = tau_max + 4,\n           label = label_tmax,\n           color = IMPRINT_PALETTE[4], hjust = 1, vjust = 0, size = 3.8) +\n  # Label 2thetap angle: near midpoint of arc\n  annotate(\"text\", x = arc_label_x, y = arc_label_y,\n           label = label_2tp,\n           color = INK_SOFT, hjust = 0, vjust = 0.5, size = 3.0) +\n  coord_fixed(ratio = 1, clip = \"off\") +\n  labs(\n    x     = paste0(\"Normal Stress \", sigma_sym, \" (MPa)\"),\n    y     = paste0(\"Shear Stress \", tau_sym, \" (MPa)\"),\n    title = \"mohr-circle · r · ggplot2 · anyplot.ai\"\n  ) +\n  theme_minimal(base_size = 8) +\n  theme(\n    plot.background  = element_rect(fill = PAGE_BG, color = PAGE_BG),\n    panel.background = element_rect(fill = PAGE_BG, color = NA),\n    panel.grid.major = element_line(color = grid_color,       linewidth = 0.3),\n    panel.grid.minor = element_line(color = grid_color_minor, linewidth = 0.15),\n    panel.border     = element_rect(color = INK_SOFT, fill = NA, linewidth = 0.25),\n    axis.title       = element_text(color = INK,      size = 10),\n    axis.text        = element_text(color = INK_SOFT, size = 8),\n    plot.title       = element_text(color = INK,      size = 12, face = \"plain\"),\n    plot.margin      = margin(40, 50, 20, 30, \"pt\")\n  )\n\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 6,\n  height   = 6,\n  units    = \"in\",\n  dpi      = 400\n)\n"}