#!/usr/bin/env ruby Maths = Math Radius = ARGV.shift&.to_f || 50.0 Ring = ARGV.shift&.to_f || 15.0 Decimals = 6 Origin_x = Radius + Ring + 1 Origin_y = Radius + Ring + 1 Page_x = 2 * 2 * Origin_x Page_y = 2 * Origin_y def a_preamble(page_x, page_y) puts <<-EOT % [page_x, page_y, page_x, page_y] <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg width="%dmm" height="%dmm" viewBox="0 0 %d %d" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" > <g> EOT end def a_postamble puts <<-EOT </g> </svg> EOT end def a_circle(origin_x, origin_y, radius) puts <<-EOT % [origin_x, origin_y, radius, radius] <ellipse style="fill:none;stroke:#FF0000;stroke-width:0.1" cx="%.6f" cy="%.6f" rx="%.6f" ry="%.6f" /> EOT end def a_mark(xf, yf, xt, yt) puts <<-EOT % [xf, yf, xt, yt] <path style="fill:none;stroke:#0000FF;stroke-width:0.1" d="M %.6f,%.6f %.6f,%.6f" /> EOT end def a_label(origin_x, origin_y, radius, heading, mod, ticktext) xt = origin_x + (radius * Maths.cos(heading) * (1 + mod)) yt = origin_y + (radius * Maths.sin(heading) * (1 + mod)) puts <<-EOT % [xt, yt, ticktext] <text xml:space="preserve" style="fill:#000000;stroke:none;font-size:1.5px;font-family:'Google Sans'" x="%.6f" y="%.6f" text-anchor="middle" >%s</text> EOT end def a_double_label(origin_x, origin_y, radius, heading, mod, ticktext) a_label(origin_x, origin_y, radius, heading, -mod, ticktext) a_label(origin_x, origin_y, radius, heading, mod, ticktext) end def a_tick(mantissa, exponent, origin_x, origin_y, radius, intervals) scale = Maths::PI * 2 / intervals (0..0.9).step(0.1).each do |sub| tick = mantissa * (10 ** exponent) + sub heading = scale * (exponent + Maths.log10(mantissa + sub)) adj = case mantissa + sub when *[1.0,5.0] 0.06 when *[2.0,3.0,4.0,6.0,7.0,8.0,9.0] 0.04 else 0.02 end xi = origin_x + (radius * Maths.cos(heading) * (1 - adj)) yi = origin_y + (radius * Maths.sin(heading) * (1 - adj)) xo = origin_x + (radius * Maths.cos(heading) * (1 + adj)) yo = origin_y + (radius * Maths.sin(heading) * (1 + adj)) ticktext = if tick == 1.0 "#{tick.to_i}(#{"0" * intervals})" else "#{tick.to_i}" end a_mark(xi, yi, xo, yo) a_double_label(origin_x, origin_y, radius, heading, adj + 0.04, ticktext) if sub == 0 end end def a_scale(origin_x, origin_y, radius, intervals) intervals.times do |exponent| (1..9).each do |mantissa| a_tick(mantissa, exponent, origin_x, origin_y, radius, intervals) end end end a_preamble(Page_x + 1, Page_y + 1) a_circle(Origin_x, Origin_y, Radius) a_circle(Origin_x, Origin_y, Radius + Ring) a_circle(Origin_x + (2 * (Radius + Ring + 1)), Origin_y, Radius + Ring) a_circle(Origin_x, Origin_y, Radius - Ring) a_double_label(Origin_x, Origin_y, Radius - Ring, 0.05, 0.1, "x") a_scale(Origin_x, Origin_y, Radius - Ring, 1) a_double_label(Origin_x, Origin_y, Radius, 0.04, 0.1, "x^2") a_scale(Origin_x, Origin_y, Radius, 2) a_postamble