/* Last edited on 2013-01-03 00:50:06 by stolfilocal */ /* Creates a test chart of dots and dashes */ import java.lang.Math; import java.util.Arrays; import java.io.IOException; import minetto.utils.FloatImage; import minetto.utils.FloatImagePaint; public class MakeDotDashChart { public static void main(String[] args) throws IOException { String out_dir = args[0]; System.err.println("Creating a test chart with dots and dashes of various sizes and positions"); int noctaves = 3; /* Octaves covered by chart. */ int nsteps = 4; /* Steps per octave. */ double rmin = 1; FloatImage img = make_chart(noctaves, nsteps, rmin); img.write_as_png(out_dir + "/chart_dotdash.png", 0.0f, 1.0f, 2.5, true); } public static FloatImage make_chart(int noctaves, int nsteps, double rmin) { double rmax = rmin*Math.pow(2.0, noctaves); int nsy = nsteps*noctaves + 1; /* Number of Y radii to show. */ return make_dot_dash_chart(nsy, rmin, rmax); } /* ---------------------------------------------------------------------- Makes a chart with {nspots} dots and round-capped dashes with dot/cap radius varying from {rmin} to {rmax}. */ private static FloatImage make_dot_dash_chart(int nsy, double rmin, double rmax) { int nsx = 7; assert(nsx >= 2); assert(nsy >= 2); /* Background and foreground colors: */ float[] bg_rgb = new float[]{ 1.0000f, 0.9500f, 0.8500f }; float[] fg_rgb = new float[]{ 0.0000f, 0.2500f, 0.7500f }; /* Compute image size and alocate: */ int nc = 3; FloatImage out = null; int[] nx_slice = new int[nsy]; /* {nx_slice[ky]} is effective width of row {ky} of slots. */ for (int ky = 0; ky < nsy; ky++) { nx_slice[ky] = 0; } int nx = 0, ny = 0; for (int ypass = 0; ypass < 2; ypass++) { /* First pass we just compute {nx,ny,nx_slice[0..nsy-1]}. Second pass is for real: */ int ymin = 0; for (int ky = 0; ky < nsy; ky++) { int iradmin = nsy - ky; double rad = rmin*Math.pow(rmax/rmin, ((double)nsy - 1 - ky)/(nsy-1)); int irad = (int)Math.ceil(rad); /* Radius rounded up. */ if (irad < iradmin) { irad = iradmin; } if (out == null) { System.err.print(" radius[" + ky + "] should be " + String.format("%7.4f",rad)); System.err.println(" rounded to " + irad); } int hy = 20; /* Slice height in multiples of {irad}. */ int ylim = ymin + hy*irad; /* Make sure that each slot is a multiple of 8 pixels high: */ assert((ymin % 4) == 0); assert((ylim % 4) == 0); if (out == null) { /* Update image height. */ ny = ylim; } int xmin = (out == null ? 0 : (nx - nx_slice[ky])/2); for (int kx = 0; kx < nsx; kx++) { int hx = 8; /* Slot width in multiples of {irad} (must be mod 4). */ int xlim = xmin + hx*irad; assert((xmin % 4) == 0); assert((xlim % 4) == 0); if (out == null) { nx_slice[ky] = xlim; if (xlim > nx) { nx = xlim; } } if (out != null) { /* Paint dots or dashes in slot: */ if (kx == 0) { /* Three spaced dots with coords {(0,0),(0,2),(2,2)} mod 4. */ double xctr0 = xmin + 4*irad; double xctr1 = xctr0 + 2; assert(xctr1 < xlim - irad); double yctr0 = ymin + 4*irad; double yctr1 = yctr0 + 4*irad + 2; double yctr2 = yctr0 + 8*irad + 2; assert(yctr2 <= ylim - 4*irad); FloatImagePaint.paint_ellipse(out, xctr0, yctr0, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr0, yctr1, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr1, yctr2, irad, irad, 0.0, fg_rgb); } else if (kx == 1) { /* Three spaced dots with coords {(1,0),(1,1),(1,2)} mod 4: */ double xctr = xmin + 4*irad + 1; double yctr0 = ymin + 4*irad; double yctr1 = yctr0 + 4*irad + 1; double yctr2 = yctr0 + 8*irad + 2; assert(yctr2 <= ylim - 4*irad); FloatImagePaint.paint_ellipse(out, xctr, yctr0, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr, yctr1, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr, yctr2, irad, irad, 0.0, fg_rgb); } else if (kx == 2) { /* Four dots only {{3,4,5}*irad} apart. */ double xctr = (xlim + xmin)/2; double yctr0 = ymin + 4*irad; double yctr1 = yctr0 + 3*irad; double yctr2 = yctr1 + 4*irad; double yctr3 = yctr2 + 5*irad; assert(yctr3 <= ylim - 4*irad); FloatImagePaint.paint_ellipse(out, xctr, yctr0, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr, yctr1, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr, yctr2, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr, yctr3, irad, irad, 0.0, fg_rgb); } else if ((kx == 3) || (kx == 4) || (kx == 5)) { /* A single vertical dash with various X alignments. */ double xctr = (xlim + xmin)/2 - (kx - 3); double yctr0 = ymin + 4*irad; double yctr1 = ylim - 4*irad; assert(yctr1 >= yctr0 + 8*irad); FloatImagePaint.paint_ellipse(out, xctr, yctr0, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr, yctr1, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_rectangle(out, xctr-irad, xctr+irad, yctr0, yctr1, 0.0, fg_rgb); } else if (kx == 6) { /* Two vertical dashes separated by {2*irad}. */ double xctr0 = (xlim + xmin)/2 - 2*irad; assert(xctr0 > xmin + irad); double xctr1 = (xlim + xmin)/2 + 2*irad; assert(xctr1 < xlim - irad); double yctr0 = ymin + 4*irad; double yctr1 = ylim - 4*irad; assert(yctr1 >= yctr0 + 8*irad); FloatImagePaint.paint_ellipse(out, xctr0, yctr0, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr0, yctr1, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_rectangle(out, xctr0-irad, xctr0+irad, yctr0, yctr1, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr1, yctr0, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_ellipse(out, xctr1, yctr1, irad, irad, 0.0, fg_rgb); FloatImagePaint.paint_rectangle(out, xctr1-irad, xctr1+irad, yctr0, yctr1, 0.0, fg_rgb); } else { assert(false); } } xmin = xlim; } if (out == null) { System.err.println(" slice width[" + ky + "] = " + nx_slice[ky]); } ymin = ylim; } if (out == null) { System.err.println(" image size = " + nx + " x " + ny); out = new FloatImage(nc, nx, ny); out.set_all_pixels(bg_rgb); } } return out; } }