From 2674fb07b6a2d3aa7a31b227eb0329eaf31b7a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Tue, 4 Jun 2019 16:56:43 +0200 Subject: [PATCH 01/13] Add constants in B4Constants.java for thin lens type --- Sources/B4constants.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sources/B4constants.java b/Sources/B4constants.java index 15a84a7..09426a0 100755 --- a/Sources/B4constants.java +++ b/Sources/B4constants.java @@ -417,7 +417,8 @@ interface B4constants static final int OTYPE = 120; // 0=lens, 1=mirror, 2=iris... static final int OFORM = 121; // 0=ellip, 1=rect... static final int OPROFILE = 122; // 0=plane, 1=conic... - static final int ONPARMS = 123; // array size. + static final int OFOCAL = 123; //focal length of thin lens + static final int ONPARMS = 124; // array size. /*-------------OTABLE strings for OEJIF diagnostic-----------*/ @@ -456,7 +457,8 @@ interface B4constants static final int OTCBOUT = 10; // coordinate break output static final int OTBLFRONT = 11; // bimodal lens front static final int OTBLBACK = 12; // bimodal lens back - static final int OTUNK = 13; // unknown type; SNH. + static final int OTTHIN = 13; // perfect thin lens + static final int OTUNK = 14; // unknown type; SNH. // phantom is merely an OTLENS with equal indices. @@ -474,6 +476,7 @@ interface B4constants "cbOutput", // 10 "bilens_f", // 11 bimodal lens front surface "bilens_r", // 12 bimodal lens rear surface + "thin", // 13 perfect thin lens "unknown"}; // 11 SNH /*-----------OPROFILE attributes and strings------------------*/ From c34fda26ccbed8c9e739b34e43a33a124e12999f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Tue, 4 Jun 2019 18:11:54 +0200 Subject: [PATCH 02/13] Implement a first approach to the mathematics for thin perfect lens raytracing --- Sources/RT13.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Sources/RT13.java b/Sources/RT13.java index 63c768e..e4f3354 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1791,6 +1791,8 @@ static private int iRedirect(double rayseq[][], double surf[], int j, int g) return iCBIN(rayseq, surf, g); // copy previous local uvw case OTCBOUT: // CoordBreak output surface return iCBOUT(rayseq, surf, g); // copy previous local xyzuvw + case OTTHIN: + return iThin(rayseq[g],surf); } return RRNON; } @@ -1820,6 +1822,19 @@ static private int iCBOUT(double rayseq[][], double surf[], int g) return RROK; } + static private int iThin(double rayseq[], double surf[]) + // CoordBreak CBout output surface method + // Must copy previous local xyzuvw into this local surface. + { + double focal = surf[OFOCAL]; + double mx, my; + mx = ray[RTUL] / Math.sqrt(1 - Math.pow(ray[RTUL], 2)); + ray[RTUL] = (mx + ray[RTXL]) / Math.sqrt(Math.pow(focal, 2) + (mx + ray[RTXL])); + my = ray[RTVL] / Math.sqrt(1 - Math.pow(ray[RTVL], 2)); + ray[RTVL] = (my + ray[RTYL]) / Math.sqrt(Math.pow(focal, 2) + (my + ray[RTYL])); + ray[RTWL] = Math.sqrt(1 - Math.pow(ray[RTUL], 2) + Math.pow(ray[RTVL], 2)); + return RROK; + } static private int iMirror(double ray[], double surf[]) // M.Lampton STELLAR SOFTWARE (C) 1989, 2003 From 2432631cd5c8d8c8315f35336326a6dbfeb0cb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Tue, 4 Jun 2019 18:27:36 +0200 Subject: [PATCH 03/13] Add thin lens parsing to OEJIF --- Sources/OEJIF.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/OEJIF.java b/Sources/OEJIF.java index 91ca19c..3ea3f41 100755 --- a/Sources/OEJIF.java +++ b/Sources/OEJIF.java @@ -172,6 +172,8 @@ void parse() break; } break; + case 't': + case 'T': RT13.surfs[jsurf][OTYPE] = OTTHIN; default: RT13.surfs[jsurf][OTYPE] = OTLENS; break; } typetag[jsurf] = getTag(ifield, 2+jsurf); @@ -802,7 +804,11 @@ public static int getOptFieldAttrib(String s) return OIDIAM; case 'F': - case 'f': return OFORM; // "form" = nonnumerical + case 'f': switch(c2up) + { + case 'c': return OFOCAL; // focal length for thin perfect lenses + default: return OFORM; // "form" = nonnumerical + } case 'G': case 'g': switch(c1up) // Group or Grating groove density From f98d04fa44e0227c55d60518fb2009f70206ad66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Tue, 4 Jun 2019 18:41:06 +0200 Subject: [PATCH 04/13] Solve some basic programming mistakes --- Sources/OEJIF.java | 2 +- Sources/RT13.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/OEJIF.java b/Sources/OEJIF.java index 3ea3f41..97d4295 100755 --- a/Sources/OEJIF.java +++ b/Sources/OEJIF.java @@ -173,7 +173,7 @@ void parse() } break; case 't': - case 'T': RT13.surfs[jsurf][OTYPE] = OTTHIN; + case 'T': RT13.surfs[jsurf][OTYPE] = OTTHIN; break; default: RT13.surfs[jsurf][OTYPE] = OTLENS; break; } typetag[jsurf] = getTag(ifield, 2+jsurf); diff --git a/Sources/RT13.java b/Sources/RT13.java index e4f3354..a5c81df 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1822,7 +1822,7 @@ static private int iCBOUT(double rayseq[][], double surf[], int g) return RROK; } - static private int iThin(double rayseq[], double surf[]) + static private int iThin(double ray[], double surf[]) // CoordBreak CBout output surface method // Must copy previous local xyzuvw into this local surface. { From 689996106696784d4c43f5e066983e66db3aac4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Tue, 4 Jun 2019 20:17:24 +0200 Subject: [PATCH 05/13] Fix uppercase C oversight --- Sources/OEJIF.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/OEJIF.java b/Sources/OEJIF.java index 97d4295..f2ccbed 100755 --- a/Sources/OEJIF.java +++ b/Sources/OEJIF.java @@ -806,7 +806,7 @@ public static int getOptFieldAttrib(String s) case 'F': case 'f': switch(c2up) { - case 'c': return OFOCAL; // focal length for thin perfect lenses + case 'C': return OFOCAL; // focal length for thin perfect lenses default: return OFORM; // "form" = nonnumerical } From 0cb0a5ad0f4cdcc3c8930e713987b868707ef9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Tue, 4 Jun 2019 21:26:12 +0200 Subject: [PATCH 06/13] Fix math signs oversights --- Sources/RT13.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/RT13.java b/Sources/RT13.java index a5c81df..d4664dc 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1828,11 +1828,11 @@ static private int iThin(double ray[], double surf[]) { double focal = surf[OFOCAL]; double mx, my; - mx = ray[RTUL] / Math.sqrt(1 - Math.pow(ray[RTUL], 2)); - ray[RTUL] = (mx + ray[RTXL]) / Math.sqrt(Math.pow(focal, 2) + (mx + ray[RTXL])); - my = ray[RTVL] / Math.sqrt(1 - Math.pow(ray[RTVL], 2)); - ray[RTVL] = (my + ray[RTYL]) / Math.sqrt(Math.pow(focal, 2) + (my + ray[RTYL])); - ray[RTWL] = Math.sqrt(1 - Math.pow(ray[RTUL], 2) + Math.pow(ray[RTVL], 2)); + mx = focal * ray[RTUL] / Math.sqrt(1 - Math.pow(ray[RTUL], 2)); + my = focal * ray[RTVL] / Math.sqrt(1 - Math.pow(ray[RTVL], 2)); + ray[RTUL] = (mx - ray[RTXL]) / Math.sqrt(Math.pow(focal, 2) + Math.pow((mx - ray[RTXL]), 2)); + ray[RTVL] = (my - ray[RTYL]) / Math.sqrt(Math.pow(focal, 2) + Math.pow((my - ray[RTYL]), 2)); + ray[RTWL] = Math.sqrt(1 - Math.pow(ray[RTUL], 2) - Math.pow(ray[RTVL], 2)); return RROK; } From 7be1b5f38ccd6efc7e8765e78fdd09da8aba1cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Wed, 5 Jun 2019 11:55:32 +0200 Subject: [PATCH 07/13] Reimplement the mathematics in RT13 --- Sources/RT13.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Sources/RT13.java b/Sources/RT13.java index d4664dc..3a93772 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1827,12 +1827,16 @@ static private int iThin(double ray[], double surf[]) // Must copy previous local xyzuvw into this local surface. { double focal = surf[OFOCAL]; - double mx, my; - mx = focal * ray[RTUL] / Math.sqrt(1 - Math.pow(ray[RTUL], 2)); - my = focal * ray[RTVL] / Math.sqrt(1 - Math.pow(ray[RTVL], 2)); - ray[RTUL] = (mx - ray[RTXL]) / Math.sqrt(Math.pow(focal, 2) + Math.pow((mx - ray[RTXL]), 2)); - ray[RTVL] = (my - ray[RTYL]) / Math.sqrt(Math.pow(focal, 2) + Math.pow((my - ray[RTYL]), 2)); - ray[RTWL] = Math.sqrt(1 - Math.pow(ray[RTUL], 2) - Math.pow(ray[RTVL], 2)); + double[] r = new double[3]; + double d; + d = focal / ray[RTWL]; + r[0] = ray[RTUL] * d - ray[RTXL]; + r[1] = ray[RTVL] * d - ray[RTYL]; + r[2] = focal; + d = Math.sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); + ray[RTUL] = r[0] / d; + ray[RTVL] = r[1] / d; + ray[RTWL] = Math.abs(r[2] / d); return RROK; } From fa6fe8a34d55508f27a3c565ef4ac704c60c407c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Wed, 5 Jun 2019 12:18:17 +0200 Subject: [PATCH 08/13] Mathematics revised for the divergent ideal lens case --- Sources/RT13.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sources/RT13.java b/Sources/RT13.java index 3a93772..7cc5e2b 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1827,6 +1827,7 @@ static private int iThin(double ray[], double surf[]) // Must copy previous local xyzuvw into this local surface. { double focal = surf[OFOCAL]; + int sign = (int) Math.signum(focal); double[] r = new double[3]; double d; d = focal / ray[RTWL]; @@ -1834,9 +1835,9 @@ static private int iThin(double ray[], double surf[]) r[1] = ray[RTVL] * d - ray[RTYL]; r[2] = focal; d = Math.sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); - ray[RTUL] = r[0] / d; - ray[RTVL] = r[1] / d; - ray[RTWL] = Math.abs(r[2] / d); + ray[RTUL] = sign * r[0] / d; + ray[RTVL] = sign * r[1] / d; + ray[RTWL] = sign * r[2] / d; return RROK; } From a67cd7cb8ef8f4f2d655078c252b3e8e588d7409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Tue, 11 Jun 2019 20:55:48 +0200 Subject: [PATCH 09/13] Add Focal Length into Adjustable parameters --- Sources/B4constants.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/B4constants.java b/Sources/B4constants.java index 09426a0..8bcd926 100755 --- a/Sources/B4constants.java +++ b/Sources/B4constants.java @@ -185,12 +185,12 @@ interface B4constants "iri", // 11 "spi", // 12 "arr", // 13 - "Grp", // 14 + "Grp", // 14 "BiI", // 15 "BiO", // 16 "non"}; // 17 - + @@ -383,7 +383,8 @@ interface B4constants static final int OZ33 = 83; static final int OZ34 = 84; static final int OZ35 = 85; - static final int OFINALADJ = 86; // final autoadjustable parameter + static final int OFOCAL = 86; //focal length of thin lens + static final int OFINALADJ = 87; // final autoadjustable parameter static final int OTIRINDEX = 91; static final int OODIAOBS = 92; // observed from trace @@ -417,8 +418,7 @@ interface B4constants static final int OTYPE = 120; // 0=lens, 1=mirror, 2=iris... static final int OFORM = 121; // 0=ellip, 1=rect... static final int OPROFILE = 122; // 0=plane, 1=conic... - static final int OFOCAL = 123; //focal length of thin lens - static final int ONPARMS = 124; // array size. + static final int ONPARMS = 123; // array size. /*-------------OTABLE strings for OEJIF diagnostic-----------*/ @@ -885,7 +885,7 @@ interface B4constants {"Black", "F"}, // 16 {"Stereo", "F"}, // 17 {"Parallax", "5"} // 18 - }, + }, { // group 9 = UO_RAND From c40a08e14a6b2fe6e266de6154df583406f9e892 Mon Sep 17 00:00:00 2001 From: Mike Lampton Date: Sat, 14 Sep 2019 20:32:12 +0200 Subject: [PATCH 10/13] update to 208 --- Sources/AutoAdj.java | 33 +- Sources/B4constants.java | 527 ++++++++----- Sources/Comparo.java | 18 +- Sources/DMF.java | 120 ++- Sources/EJIF.java | 6 +- Sources/H1DPanel.java | 33 +- Sources/H2DPanel.java | 28 +- Sources/InOut.java | 52 +- Sources/LayoutPanel.java | 208 +++-- Sources/MEJIF.java | 19 +- Sources/MPlotPanel.java | 5 +- Sources/MapPanel.java | 25 +- Sources/OEJIF.java | 224 +++--- Sources/Options.java | 114 ++- Sources/Plot2Panel.java | 186 ++--- Sources/Plot3Panel.java | 130 ++-- Sources/REJIF.java | 94 +-- Sources/RT13.java | 1568 ++++++++++++++++++++++---------------- Sources/Random.java | 13 +- Sources/Triple.java | 2 +- Sources/U.java | 5 + Sources/Z.java | 88 ++- 22 files changed, 2063 insertions(+), 1435 deletions(-) diff --git a/Sources/AutoAdj.java b/Sources/AutoAdj.java index 64bc8e1..f81c9aa 100755 --- a/Sources/AutoAdj.java +++ b/Sources/AutoAdj.java @@ -6,7 +6,7 @@ /** AutoAdj.java - * + * A207: eliminated groups * class LMadj is at the bottom of this file. * A190, Nov 2015: introducing weights. * @author: M.Lampton (c) 2003..2006 STELLAR SOFTWARE all rights reserved. @@ -22,7 +22,7 @@ class AdjHost implements B4constants //----------parallel with InOut------------- private OEJIF optEditor = null; private REJIF rayEditor = null; - private int nsurfs=0, ngroups=0, nrays=0, onfields=0, rnfields=0; + private int nsurfs=0, nrays=0, onfields=0, rnfields=0; private int npts, nadj=0, onadj=0, rnadj=0, ngood=0, autongoals=0; private boolean bWFE=false; @@ -58,11 +58,10 @@ class AdjHost implements B4constants rayEditor.doStashForUndo(); nsurfs = DMF.giFlags[ONSURFS]; - ngroups = DMF.giFlags[ONGROUPS]; onfields = DMF.giFlags[ONFIELDS]; // fields per optic. nrays = DMF.giFlags[RNRAYS]; rnfields = DMF.giFlags[RNFIELDS]; // fields per ray. - if ((ngroups<1) || (onfields<1) || (nrays<1) || (rnfields<1)) + if ((onfields<1) || (nrays<1) || (rnfields<1)) return; // SNH graying. bWFE = DMF.giFlags[RWFEFIELD] > RABSENT; @@ -173,17 +172,13 @@ private double getDelta(int iadj) int j = optEditor.getAdjSurf(iadj); if ((j>0) && (j<=nsurfs)) { - int g = RT13.group[j]; - if ((g>0) && (g<=ngroups)) - { - for (int kray=1; kray<=nrays; kray++) - if (RT13.bGoodRay[kray]) - { - double rx = RT13.dGetRay(kray, g, RTXL); - double ry = RT13.dGetRay(kray, g, RTYL); - r = Math.max(r, Math.sqrt(rx*rx+ry*ry)); - } - } + for (int kray=1; kray<=nrays; kray++) + if (RT13.isRayOK[kray]) + { + double rx = RT13.dGetRay(kray, j, RTXL); + double ry = RT13.dGetRay(kray, j, RTYL); + r = Math.max(r, Math.sqrt(rx*rx+ry*ry)); + } } if (r < 1E-6) r = 0.5*dOsize; @@ -299,7 +294,7 @@ else if (autongoals==2) if (istatus==BADITER) { if (DMF.sAutoErr.equals("")) // no previous message - jL[7].setText("Ray risk. Stopping."); + jL[7].setText("Stopping: " + sResults[RT13.getFailCode()] + " " + RT13.getFailSurf()); else // retain previous message jL[7].setText(DMF.sAutoErr); } @@ -361,7 +356,7 @@ private void vUpdateRayTable() } if (op == RDEBUG) // debugger message here.... - rayEditor.putField(f, row, RT13.bGoodRay[kray] ? "OK" : "NG"); + rayEditor.putField(f, row, RT13.isRayOK[kray] ? "OK" : "NG"); if (op >= RGOAL) // Comparo updates floating goals, not Auto. @@ -369,11 +364,11 @@ private void vUpdateRayTable() if (op >= 100) // output table data are wanted here... { - int jsurf = RT13.getGroupNum(op); // handles "final" + int jsurf = RT13.getSurfNum(op); // handles "final" int iattr = RT13.getAttrNum(op); if ((iattr>=0) && (iattr0)) { - if (RT13.bGoodRay[kray]) + if (RT13.isRayOK[kray]) { double d = RT13.dGetRay(kray, jsurf, iattr); rayEditor.putFieldDouble(f, row, d); diff --git a/Sources/B4constants.java b/Sources/B4constants.java index 15a84a7..7366cd6 100755 --- a/Sources/B4constants.java +++ b/Sources/B4constants.java @@ -3,23 +3,30 @@ import java.awt.*; // Color /** - * B4constants.java -- an interface carrying static global constants. - * - * + * B4constants.java -- an interface carrying static global constants + * A207: attempting logic cleanup for bimodal optics + * A206: Converting all mirrors into bimodal mirrors, never killing rays + * A205: Autoadjust ray failure now announces surface & failure classification + * A204: fix the spider layout artwork (spider FUNCTIONS okay). + * A203: allow "asphericity" as well as previous "asph"; see OEJIF line 800. + * A202 wider editor fields. + * A201 Sept 2017 has user selected skeleton parameters for new files. * All fields here are public static final. (H&C p.206) * Added RTANGLE between ray and normal any surface, March 2015, Oct 2015. * Added RTNORMX, RTNORMY, RTNORMZ as new ray attributes. * Added lower case i, j, k to read out the surface normal vector. - * - * @author M.Lampton STELLAR SOFTWARE (c) 2004-2014 all rights reserved. + * Added OSGAUSS for 2D circular Gaussian shaped surface profile + * Added user selectable new file skeleton options A201 + * @author M.Lampton STELLAR SOFTWARE (c) 2004-2016 all rights reserved. */ interface B4constants -{ +{ static final String PRODUCT = "BEAM FOUR "; - static final String RELEASE = "Release 190, 13 January 2016"; - // fill in your compiler below... "Compiler was: Javac 1.6.0_65" for user compatibility - static final String COMPILER = "Compiler was: Javac 1.6.0_65"; - static final String COPYRIGHT = "(c) 2016 Stellar Software"; + static final String RELEASE = "Release 208, 15 Jan 2019"; + static final String COMPILER = "Compiler was: Javac 1.8.0_20"; + static final String COPYRIGHT = "(c) 2018 Stellar Software"; + static final boolean DEBUG = false; + static final char NULLCHAR = (char) 0; static final int BLINKMILLISEC = 300; // millisec @@ -48,15 +55,17 @@ interface B4constants static final int THINLINE = 0; static final int FATLINE = 1; - static final int IMAX = 256; // EPanel charTable - static final int JMAX = 3600; // EPanel charTable + static final int IMAX = 512; // Chars EPanel charTable + static final int JMAX = 3600; // Rows EPanel charTable static final int MAXFIELDS = 100; static final int MAXSURFS = 100; // < JMAX - static final int MAXGROUPS = MAXSURFS; + // static final int MAXGROUPS = MAXSURFS; static final int MAXRAYS = JMAX-3; // < JMAX + // note: 17 circles = 919 rays; 34 rings = 3571 rays. + static final int MAXRINGS = (int) (-0.5+Math.sqrt(12*MAXRAYS-3.)/6.); static final int MAXMEDIA = 200; // < JMAX static final int MAXGOALS = 7; // AutoAdjust - static final int MAXWFEGROUPS = 100; + // static final int MAXWFEGROUPS = 100; static final int MAXADJ = 100; static final int MAXMAP = 100; static final int MAXMP = 9; // multiplots per axis @@ -124,7 +133,7 @@ interface B4constants static final double MAXSIZE = 1.5e+6; // plot & layout sanity? static final double DENSE = 1.60; // heavy if refraction>DENSE static final double PLOTTICKFRAC = 0.015; // plot iristick/opticspan - static final double DOTTEDFRAC = 0.04; // extension/opticspan + // static final double DOTTEDFRAC = 0.04; // extension/opticspan static final double TICKHEIGHT = 0.015; // rulerticks/unitsquare /*---------------LMITER constants-------------------------*/ @@ -148,50 +157,112 @@ interface B4constants static final String RAYSTARTCHARS = "XYZUVWxyzuvw"; // for MapPanel -/*-------------------RunRay Tstring[] codes------------*/ +/*-------------------RunRay Tstring[] error codes---------------*/ +/*-----these could be simplified going to a 4x4 SURFxRAY plan---*/ +/*---have them pure ray errors, not mingled with surface IDs----*/ - static final int RROK = 0; // general no-failure code + static final int RROK = 0; // general no-failure error code + static final int RRMIS = 1; // ray missed surface. static final int RRBAK = 2; // ray intercepted but behind start. - static final int RRBRA = 3; // propagation fail bracket - static final int RRPRP = 4; // general propagation failure - static final int RRUNK = 5; // unknown diffraction wavelength or other. - static final int RRORD = 6; // redirection fail diffraction order - static final int RRTIR = 7; // redirection fail total internal reflection - static final int RRDIA = 8; // non-Iris Diameter - static final int RRdia = 9; // non-Iris diameter - static final int RRIRI = 10; // Iris OD fail - static final int RRiri = 11; // Iris ID fail - static final int RRSPI = 12; // spider leg - static final int RRARR = 13; // array setup invalid - static final int RRGRP = 14; // group failed - static final int RRBI = 15; // bimodal inner diam intercept - static final int RRBO = 16; // bimodal outer Diam intercept - static final int RRNON = 17; // not implemented + static final int RRBRA = 3; // bracket intercept fail + + static final int RRDIA = 4; // Diameter: obj or iris + + static final int RRdia = 5; // inner diameter: obj or iris + static final int RRSPI = 6; // spider leg + + static final int RRORD = 7; // redirection fail diffraction order + static final int RRTIR = 8; // redirection fail total internal reflection + static final int RRARR = 9; // array setup invalid + static final int RRBXO = 10; // bimodal crossover failure + static final int RRTER = 11; // terminate the trace at redirect() stage + static final int RRUNK = 12; // unknown or blf/blm, or not implemented // sResults[] are used by InOut to explain result[] + // Needs a special code for NonNumericalWavelength. static final String[] sResults = { "OK", // 0 "mis", // 1 "bak", // 2 "bra", // 3 - "pro", // 4 - "unk", // 5 - "ord", // 6 - "TIR", // 7 - "Dia", // 8 - "dia", // 9 - "Iri", // 10 - "iri", // 11 - "spi", // 12 - "arr", // 13 - "Grp", // 14 + "Dia", // 4 + "dia", // 5 + "Spi", // 6 + "Ord", // 7 + "TIR", // 8 + "Arr", // 9 + "BXO", // 10 + "Ter", // 11 + "Unk"}; // 12 + + // the 22 codex values are listed here... + static final int UNIOK = 0; + static final int UNIIF = 1; + static final int UNIPO = 2; // Pupil Outside fail + static final int UNIPI = 3; // Pupil Inside fail + static final int UNIRF = 4; // Redirection Failure - "BiI", // 15 - "BiO", // 16 - "non"}; // 17 - - + static final int BMOK = 5; + static final int BMIF = 6; + static final int BMPO = 7; + static final int BMPI = 8; + static final int BMRF = 9; + + static final int BLFOK = 10; + static final int BLFIF = 11; + static final int BLFPO = 12; + static final int BLFPI = 13; + static final int BLFRF = 14; + + static final int BLBOK = 15; + static final int BLBIF = 16; + static final int BLBPO = 17; + static final int BLBPI = 18; + static final int BLBRF = 19; + + static final int BTOK = 20; // bimodal terminator ray hit & kill + static final int BTIF = 21; // + static final int BTPO = 22; + static final int BTPI = 23; + static final int BTRF = 24; + + static final int BLBXO = 25; // bimpdal crossover failure + + static final int CODEXMULT = 5; // since 5 categories of ray failures + + static final String[] sCodex = { + "UNIOK", // 0 + "UNIIF", // 1 + "UNIPO", // 2 + "UNIPI", // 3 + "UNIRF", // 4 + + "BMOK", // 5 + "BMIF", // 6 + "BMPO", // 7 + "BMPI", // 8 + "BMRF", // 9 + + "BLFOK", // 10 + "BLFIF", // 11 + "BLFPO", // 12 + "BLFPI", // 13 + "BLFRF", // 14 + + "BLBOK", // 15 + "BLBIF", // 16 + "BLBPO", // 17 + "BLBPI", // 18 + "BLBRF", // 19 + + "BTOK", // 20 bimodal terminator ray hit & kill + "BTIF", // 21 bimodal terminator ray miss & bypass + "BTPO", // 22 bimodal terminator ray OD bypass + "BTPI", // 23 bimodal terminator ray ID bypass + "BTRF", // 24 bimodal terminator ray redirect fail: SNH + + "BLBXO"}; // 25 bimodal crossover failure /*------------ generic editor status[] index macro defs ------------*/ @@ -207,7 +278,7 @@ interface B4constants static final int OPRESENT = 0; // 0=absent=FALSE, 1=present=TRUE static final int ONLINES = 1; // generic static final int ONSURFS = 2; // generic - static final int ONGROUPS = 3; // new; testing... + // static final int ONGROUPS = 3; // new; testing... static final int ONFIELDS = 4; // generic static final int OMEDIANEEDED = 5; // 0=FALSE=okWithout, 1=TRUE=needsMedia. static final int OGRATINGPRESENT = 6; // 1=present @@ -291,7 +362,7 @@ interface B4constants "OK"}; // 16 -/*----------------------optics table column attributes-------------*/ +/*----------------------optics table column attribute fields-------------*/ static final int OABSENT = -1; static final int OREFRACT = 1; // refractive index approaching surface j @@ -331,93 +402,156 @@ interface B4constants static final int OA13 = 32; static final int OA14 = 33; - static final int OGX = 34; // any of this set triggers GROOVY - static final int OGY = 35; - static final int OORDER = 36; - static final int OVLS1 = 37; - static final int OVLS2 = 38; - static final int OVLS3 = 39; - static final int OVLS4 = 40; - static final int OHOEX1 = 41; - static final int OHOEY1 = 42; - static final int OHOEZ1 = 43; - static final int OHOEX2 = 44; - static final int OHOEY2 = 45; - static final int OHOEZ2 = 46; - static final int OHOELAM = 47; - static final int OGROOVY = 48; + + + +/* =======HETTRICK 22 MARCH 2016========== + + So, in summary, I (personally) would be happy as a clam with the + following (minimized) number of inputs: + + Gy, VY01, VY02, VY03, Gx, VX10, VX20, VX30, + VY10, VY20, VY30, VY11, VY12, VY21 + + Then BEAM4 internally uses the following formula to determine the + corresponding 6 constants needed for computing dN/dx: + + VX(i,j) = [(i+1)/j] * VY(i+1,j-1) for all j .ne. 0 + + resulting in the following: + + VX01 = VY10 + VX02 = 1/2 VY11 + VX03 = 1/3 VY12 + VX11 = 2 VY20 + VX12 = VY21 + VX21 = 3 VY30 + + ==== added 4-5 June 2016: fourth power ==== + Know what? + Numbers are cheap. + I'll stick in the whole group going to power-sum = 4: + VX40, VY40, VY04, VY13, VY22, VY31 user specifiable via .OPT + plus internally calculated VX13, VX22, VX31, VX04. +*/ + + static final int OORDER = 34; // any of this group triggers OGROOVY; see OEJIF. + static final int OGX = 35; // explicit; user synonyms "GX" or "VX00" + static final int OGY = 36; // explicit; user synonyms "GY" or "VY00" + + static final int OVX01 = 37; // implicit; see RT13::setEulers(). + static final int OVX02 = 38; // implicit + static final int OVX03 = 39; // implicit + static final int OVX04 = 40; // implicit + static final int OVX10 = 41; // "VX10"; straight groove + static final int OVX11 = 42; // implicit + static final int OVX12 = 43; // implicit + static final int OVX13 = 44; // implicit + static final int OVX20 = 45; // "VX20"; straight groove + static final int OVX21 = 46; // implicit + static final int OVX22 = 47; // implicit + static final int OVX30 = 48; // "VX30"; straight groove + static final int OVX31 = 49; // implicit + static final int OVX40 = 50; // "VX40"; straight groove + + static final int OVY01 = 51; // "VY01"; straight groove + static final int OVY02 = 52; // "VY02"; straight groove + static final int OVY03 = 53; // "VY03"; straight groove + static final int OVY04 = 54; // "VY04"; straight groove + static final int OVY10 = 55; // "VY10" + static final int OVY11 = 56; // "VY11" + static final int OVY12 = 57; // "VY12" + static final int OVY13 = 58; // "VY13" + static final int OVY20 = 59; // "VY20" + static final int OVY21 = 60; // "VY21" + static final int OVY22 = 61; // "VY22" + static final int OVY30 = 62; // "VY30" + static final int OVY31 = 63; // "VY31" + static final int OVY40 = 64; // "VY40" - static final int OZ00 = 50; // Zernike coefficient 0: piston - static final int OZ01 = 51; - static final int OZ02 = 52; - static final int OZ03 = 53; - static final int OZ04 = 54; - static final int OZ05 = 55; - static final int OZ06 = 56; - static final int OZ07 = 57; - static final int OZ08 = 58; - static final int OZ09 = 59; - static final int OZ10 = 60; - static final int OZ11 = 61; - static final int OZ12 = 62; - static final int OZ13 = 63; - static final int OZ14 = 64; - static final int OZ15 = 65; - static final int OZ16 = 66; - static final int OZ17 = 67; - static final int OZ18 = 68; - static final int OZ19 = 69; - static final int OZ20 = 70; - static final int OZ21 = 71; - static final int OZ22 = 72; - static final int OZ23 = 73; - static final int OZ24 = 74; - static final int OZ25 = 75; - static final int OZ26 = 76; - static final int OZ27 = 77; - static final int OZ28 = 78; - static final int OZ29 = 79; - static final int OZ30 = 80; - static final int OZ31 = 81; - static final int OZ32 = 82; - static final int OZ33 = 83; - static final int OZ34 = 84; - static final int OZ35 = 85; - static final int OFINALADJ = 86; // final autoadjustable parameter - - static final int OTIRINDEX = 91; - static final int OODIAOBS = 92; // observed from trace - static final int OIDIAM = 93; // used by parser only - static final int OIDIAX = 94; // used by clients - static final int OIDIAY = 95; // used by clients - static final int OODIAM = 96; // used by parser only - static final int OODIAX = 97; // used by clients - static final int OODIAY = 98; // used by clients - static final int OZMIN = 99; - static final int OZMAX = 100; - static final int OFFOX = 101; // offset from vertex - static final int OFFOY = 102; // offset from vertex - static final int OFFIX = 103; // offset from vertex - static final int OFFIY = 104; // offset from vertex - static final int OSCATTER = 105; // introduced Aug 2011 A128 - static final int ONSPIDER = 106; // number of spider legs - static final int OWSPIDER = 107; // width of spider leg - static final int ONARRAYX = 108; - static final int ONARRAYY = 109; - - static final int OE11 = 111; // Eulers computed by OEJIF parser - static final int OE12 = 112; // These convert lab to local. - static final int OE13 = 113; // For local to lab, use transpose. - static final int OE21 = 114; - static final int OE22 = 115; - static final int OE23 = 116; - static final int OE31 = 117; - static final int OE32 = 118; - static final int OE33 = 119; - static final int OTYPE = 120; // 0=lens, 1=mirror, 2=iris... - static final int OFORM = 121; // 0=ellip, 1=rect... - static final int OPROFILE = 122; // 0=plane, 1=conic... - static final int ONPARMS = 123; // array size. + static final int ORGAUSS = 65; // rms radius of circular Gaussian + static final int OHGAUSS = 66; // peak height of circular Gaussian + + static final int OHOEX1 = 71; + static final int OHOEY1 = 72; + static final int OHOEZ1 = 73; + static final int OHOEX2 = 74; + static final int OHOEY2 = 75; + static final int OHOEZ2 = 76; + static final int OHOELAM = 77; + static final int OGROOVY = 78; // OGX to OHOELAM nonzero set this groovy flag. + + static final int OZ00 = 80; // Zernike coefficient 0: piston + static final int OZ01 = 81; + static final int OZ02 = 82; + static final int OZ03 = 83; + static final int OZ04 = 84; + static final int OZ05 = 85; + static final int OZ06 = 86; + static final int OZ07 = 87; + static final int OZ08 = 88; + static final int OZ09 = 89; + static final int OZ10 = 90; + static final int OZ11 = 91; + static final int OZ12 = 92; + static final int OZ13 = 93; + static final int OZ14 = 94; + static final int OZ15 = 95; + static final int OZ16 = 96; + static final int OZ17 = 97; + static final int OZ18 = 98; + static final int OZ19 = 99; + static final int OZ20 = 100; + static final int OZ21 = 101; + static final int OZ22 = 102; + static final int OZ23 = 103; + static final int OZ24 = 104; + static final int OZ25 = 105; + static final int OZ26 = 106; + static final int OZ27 = 107; + static final int OZ28 = 108; + static final int OZ29 = 109; + static final int OZ30 = 110; + static final int OZ31 = 111; + static final int OZ32 = 112; + static final int OZ33 = 113; + static final int OZ34 = 114; + static final int OZ35 = 115; + static final int OFINALADJ = 116; // final autoadjustable parameter + + static final int OTIRINDEX = 121; + static final int OODIAOBS = 122; // observed from trace + static final int OIDIAM = 123; // used by parser only + static final int OIDIAX = 124; // used by clients + static final int OIDIAY = 125; // used by clients + static final int OODIAM = 126; // used by parser only + static final int OODIAX = 127; // used by clients + static final int OODIAY = 128; // used by clients + static final int OZMIN = 129; + static final int OZMAX = 130; + static final int OFFOX = 131; // offset from vertex + static final int OFFOY = 132; // offset from vertex + static final int OFFIX = 133; // offset from vertex + static final int OFFIY = 134; // offset from vertex + static final int OSCATTER = 135; // scatter angle field degrees, Aug 2011 A128; also A195. + static final int ONSPIDER = 137; // number of spider legs + static final int OWSPIDER = 138; // width of spider leg + static final int ONARRAYX = 139; + static final int ONARRAYY = 140; + + static final int OE11 = 141; // Eulers computed by OEJIF parser + static final int OE12 = 142; // These convert lab to local. + static final int OE13 = 143; // For local to lab, use transpose. + static final int OE21 = 144; + static final int OE22 = 145; + static final int OE23 = 146; + static final int OE31 = 147; + static final int OE32 = 148; + static final int OE33 = 149; + static final int OTYPE = 150; // 0=lens, 1=mirror, 2=iris... + static final int OFORM = 151; // 0=ellip, 1=rect... + static final int OPROFILE = 152; // 0=plane, 1=conic... + static final int ONPARMS = 153; // array size. /*-------------OTABLE strings for OEJIF diagnostic-----------*/ @@ -451,14 +585,20 @@ interface B4constants static final int OTLENSARRAY = 5; static final int OTMIRRARRAY = 6; static final int OTIRISARRAY = 7; - static final int OTSCATTER = 8; - static final int OTCBIN = 9; // coordinate break input - static final int OTCBOUT = 10; // coordinate break output - static final int OTBLFRONT = 11; // bimodal lens front - static final int OTBLBACK = 12; // bimodal lens back - static final int OTUNK = 13; // unknown type; SNH. + // static final int OTSCATTER = 8; + static final int OTGSCATTER = 8; // A195 Gaussian scatter type + static final int OTUSCATTER = 9; // A195 Uniform scatter type + static final int OTCBIN = 10; // coordinate break input + static final int OTCBOUT = 11; // coordinate break output + static final int OTBMIRROR = 12; // bimodal mirror + static final int OTBLFRONT = 13; // bimodal lens front + static final int OTBLBACK = 14; // bimodal lens back + static final int OTTERMINATE = 15; + static final int OTUNK = 16; // unknown type; SNH. // phantom is merely an OTLENS with equal indices. + // transmission grating is merely a groovy lens + // reflection grating is merely a groovy mirror static final String sTypes[] = { " lens", // 0 @@ -469,12 +609,15 @@ interface B4constants "lensArr", // 5 /// should be lens + OSOLVER=OSARRAY??? "mirrArr", // 6 /// nope, see RT13.dIntercept(). "irisArr", // 7 /// This is correct. - "scatter", // 8 - "cbInput", // 9 - "cbOutput", // 10 - "bilens_f", // 11 bimodal lens front surface - "bilens_r", // 12 bimodal lens rear surface - "unknown"}; // 11 SNH + "g scat ", // 8 + "u scat ", // 9 + "cbInput", // 10 + "cbOutput", // 11 + "bimirror", // 12 + "bilens_f", // 13 bimodal lens front surface + "bilens_r", // 14 bimodal lens rear surface + "terminate", // 15 bimodal terminator + "unknown"}; // 16 SNH /*-----------OPROFILE attributes and strings------------------*/ @@ -494,7 +637,8 @@ interface B4constants static final int OSZERNTOR = 13; static final int OSBICONIC = 14; static final int OSARRAY = 15; - static final int OSNFLAGS = 16; + static final int OSGAUSS = 16; + static final int OSNFLAGS = 17; static final String[] sProfiles = { "Plano", // 0 @@ -512,7 +656,8 @@ interface B4constants "ZernRev", // 12 "ZernTor", // 13 "Biconic", // 14 - "Array"}; // 15 + "Array", // 15 + "****Gauss****"}; // 16 @@ -532,7 +677,7 @@ interface B4constants static final int RSWAVEL = 7; // raystarts[][] only static final int RSCOLOR = 8; // raystarts[][] only static final int RSORDER = 9; // raystarts[][] only - static final int RNSTARTS = 10; // dimension of raystart[]. + static final int RNSTARTS = 10; // raystart[] attributes. /*-------------- ray output index local attribute macrodefs--------------*/ @@ -658,30 +803,31 @@ interface B4constants //-------User Option Group Macros-------------- - - static final int UO_IO = 0; - static final int UO_LAYOUT = 1; - static final int UO_AUTO = 2; - static final int UO_PLOT2 = 3; - static final int UO_MPLOT = 4; - static final int UO_MAP = 5; - static final int UO_PLOT3 = 6; - static final int UO_1D = 7; - static final int UO_2D = 8; - static final int UO_RAND = 9; - static final int UO_CAD = 10; - static final int UO_START = 11; - static final int UO_EDIT = 12; - static final int UO_GRAPH = 13; - static final int UO_DEF = 14; - static final int UO_1DRAY = 15; - static final int UO_2DRRAY = 16; - static final int UO_2DCRAY = 17; - static final int UO_2DCGAUS = 18; - static final int UO_RECENTO = 19; - static final int UO_RECENTR = 20; - static final int UO_RECENTM = 21; - static final int NUOGROUPS = 22; + + static final int UO_NEWFILE = 0; // skeleton options + static final int UO_IO = 1; + static final int UO_LAYOUT = 2; + static final int UO_AUTO = 3; + static final int UO_PLOT2 = 4; + static final int UO_MPLOT = 5; + static final int UO_MAP = 6; + static final int UO_PLOT3 = 7; + static final int UO_1D = 8; + static final int UO_2D = 9; + static final int UO_RAND = 10; + static final int UO_CAD = 11; + static final int UO_START = 12; + static final int UO_EDIT = 13; + static final int UO_GRAPH = 14; + static final int UO_DEF = 15; + static final int UO_1DRAY = 16; + static final int UO_2DRRAY = 17; + static final int UO_2DCRAY = 18; + static final int UO_2DCGAUS = 19; + static final int UO_RECENTO = 20; + static final int UO_RECENTR = 21; + static final int UO_RECENTM = 22; + static final int NUOGROUPS = 23; //--------UO strings: avoid "|" used in parsing----------- //----UO strings is a ragged right array, @@ -689,7 +835,13 @@ interface B4constants static final String UO[][][] = { - { // group 0 = UO_IO + { // group 0 = UO_NEWFILE + {"Nrecords", "15"}, // 0; nrows = Nrecords + 3 + {"Nfields", "10"}, // 1 + {"FieldWidth", "18"} // 2 + }, + + { // group 1 = UO_IO {"Show RMS when goals exist", "T"} }, @@ -732,7 +884,9 @@ interface B4constants {"Sticky uyspan", "0"}, // 35 {"Sticky uzspan", "0"}, // 36 {"Refractor connectors?", "F"}, // 37 - {"Retro visible?", "T"} // 38 + {"Retro visible?", "T"}, // 38 + {"Dotted extension %", "4"} // 39 + }, { // group 2 = UO_AUTO @@ -757,10 +911,10 @@ interface B4constants {"Plus", "F"}, // 6 {"Square", "F"}, // 7 {"Diamond", "F"}, // 8 - {"Good rays", "T"}, // 9 plot good rays - {"All rays", "F"}, // 10 plot all rays - {"Additional surface, none if zero", ""}, // 11 - {"Black Background", "F"} // 12 + {"Complete rays", "T"}, // 9 RROK + {"Sufficient rays", "F"}, // 10 enough surfs + // {"Additional surface, none if zero", ""}, // elim A207 + {"Black Background", "F"} // 11 }, { // group 4 = UO_MPLOT MultiPlot options @@ -843,8 +997,8 @@ interface B4constants {"Plus", "F"}, // 10 {"Sqr", "F"}, // 11 {"Diam", "F"}, // 12 - {"Good rays", "T"}, // 13 - {"All rays", "F"}, // 14 + {"Complete rays", "T"}, // 13 + {"Sufficient rays","F"}, // 14 {"White", "T"}, // 15 {"Black", "F"}, // 16 {"Stereo", "F"}, // 17 @@ -882,7 +1036,7 @@ interface B4constants {"Black", "F"}, // 16 {"Stereo", "F"}, // 17 {"Parallax", "5"} // 18 - }, + }, { // group 9 = UO_RAND @@ -1074,7 +1228,6 @@ interface B4constants {"RM8", ""}, {"RM9", ""} } - }; - -} //--------end of Constants.java--------------------- + }; +} //--------end of B4onstants.java--------------------- diff --git a/Sources/Comparo.java b/Sources/Comparo.java index ba8e514..203054d 100755 --- a/Sources/Comparo.java +++ b/Sources/Comparo.java @@ -27,7 +27,7 @@ class Comparo implements B4constants private static OEJIF optEditor = null; private static REJIF rayEditor = null; - private static int ngroups=0, nrays=0, onfields=0, rnfields=0; + private static int nrays=0, nsurfs=0, onfields=0, rnfields=0; private static int ngood=0, ngoals=0, nadj=0; private static int npts=0; private static double sos=0.0; @@ -62,7 +62,7 @@ public static void doResiduals() { for (int kray=1; kray<=nrays; kray++) { - if (RT13.bGoodRay[kray]) + if (RT13.isRayOK[kray]) for (int igoal=0; igoal RABSENT; @@ -119,7 +119,7 @@ private static boolean bSetup() if ((optEditor==null) || (rayEditor==null)) return false; // SNH graying. - if ((ngroups<1) || (onfields<1) || (nrays<1) || (rnfields<1)) + if ((onfields<1) || (nrays<1) || (rnfields<1)) return false; // SNH graying. if ((ngoals < 1) && !bHasWFE) @@ -164,11 +164,11 @@ private static void vSetupGoals() - private static double getRay(int kray, int iattrib) + private static double getRay(int kray, int iattrib) // at final surface { if ((iattrib>=RX) && (iattrib 0) // empty is trouble here. + if (REJIF.wavenames[kray].length() > 0) // empty is trouble here. for (int f=1; f <= giFlags[MNWAVES]; f++) - if (REJIF.wavenames[irec].equals(MEJIF.mwaves[f])) + if (REJIF.wavenames[kray].equals(MEJIF.mwaves[f])) { - RT13.gR2M[irec] = f; // found it. + RT13.gR2W[kray] = f; // found it! kray uses wavel ID "f" break; // abandon search. } - if (RT13.gR2M[irec] == ABSENT) + if (RT13.gR2W[kray] == ABSENT) { - unkwaverec = irec; - unkwavename = REJIF.wavenames[irec]; + unkwaverec = kray; + unkwavename = REJIF.wavenames[kray]; trouble = true; break; } @@ -1745,10 +1767,10 @@ public static void vMasterExit() } - - public static boolean writeSkeleton(String fname) - { - File f = new File(fname); +/** + public static boolean writeSkeleton(String fname) + { + File f = new File(fname); try { FileWriter fw = new FileWriter(f); @@ -1767,9 +1789,59 @@ public static boolean writeSkeleton(String fname) pw.flush(); pw.close(); } - catch (IOException e) {return false; } + catch (IOException e) + { + // System.out.println("DMF::writeSkeleton() failure; fname = "+fname); + return false; + } return true; } +*/ + public static boolean writeSkeleton(String fname) + { + int nrecords = U.suckInt(reg.getuo(UO_NEWFILE, 0)); + int nfields = U.suckInt(reg.getuo(UO_NEWFILE, 1)); + int fwidth = U.suckInt(reg.getuo(UO_NEWFILE, 2)); + String s = makeSkeleton(nrecords+3, nfields, fwidth); + + File f = new File(fname); + try + { + FileWriter fw = new FileWriter(f); + fw.write(s); + fw.close(); + } + catch (IOException e) + { + // System.out.println("DMF::writeSkeleton() failure; fname = "+fname); + return false; + } + return true; + } + + static String makeSkeleton(int nrows, int nfields, int fieldwidth) + { + String s = ""; + for (int row=0; row 0) return; - - - //---see if group assignments have changed---- - boolean bChanged = false; - for (int j=0; jRNATTRIBS)) return "Unknown variable: "+hst; @@ -236,7 +224,8 @@ private void doParse() hst = DMF.reg.getuo(UO_1D, 0); int op = REJIF.getCombinedRayFieldOp(hst); - hsurf = RT13.getGroupNum(op); + // hsurf = RT13.getGroupNum(op); + hsurf = RT13.getSurfNum(op); hattr = RT13.getAttrNum(op); nbins = U.parseInt(DMF.reg.getuo(UO_1D, 1)); nbins = Math.max(2, Math.min(MAXBINS, nbins)); @@ -250,7 +239,7 @@ private void doParse() RT13.iBuildRays(true); for (int kray=1; kray<=nrays; kray++) { - if (RT13.bGoodRay[kray]) + if (RT13.isRayOK[kray]) { double h = RT13.dGetRay(kray, hsurf, hattr); if (ngood==0) @@ -342,7 +331,7 @@ private void doParse() histo[i] = 0; for (int kray=1; kray<=nrays; kray++) - if (RT13.bGoodRay[kray]) + if (RT13.isRayOK[kray]) addRayToHisto(kray); } //---end doParse(). diff --git a/Sources/H2DPanel.java b/Sources/H2DPanel.java index def545d..4040752 100755 --- a/Sources/H2DPanel.java +++ b/Sources/H2DPanel.java @@ -8,7 +8,7 @@ /** * H2DPanel extends GPanel, draws 2D binned ray histogram. * Random ray responder is installed. - * + * A207: eliminates groups * * Because the x, y, and z scaling factors are different, * integer bins & counts are scaled to a unit cube for display. @@ -79,7 +79,6 @@ protected void doTechList(boolean bFullArt) // replaces abstract method // Called by GPanel for artwork: new, pan, zoom, & random ray group. { nsurfs = DMF.giFlags[ONSURFS]; // always needed. - ngroups = DMF.giFlags[ONGROUPS]; // always needed. nrays = DMF.giFlags[RNRAYS]; // always needed. ngood = RT13.iBuildRays(true); @@ -89,15 +88,7 @@ protected void doTechList(boolean bFullArt) // replaces abstract method if (warn.length() > 0) return; - //---see if group assignments have changed---- - boolean bChanged = false; - for (int j=0; jRNATTRIBS)) return "H var unknown: "+hst; String vst = DMF.reg.getuo(UO_2D, 3); int vop = REJIF.getCombinedRayFieldOp(vst); - int vsurf = RT13.getGroupNum(vop); + int vsurf = RT13.getSurfNum(vop); int vattr = RT13.getAttrNum(vop); if ((vsurf<0) || (vattr<0) || (vattr>RNATTRIBS)) return "V var unknown: "+vst; @@ -225,12 +215,12 @@ private void doParse() hst = DMF.reg.getuo(UO_2D, 2); int hop = REJIF.getCombinedRayFieldOp(hst); - hsurf = RT13.getGroupNum(hop); + hsurf = RT13.getSurfNum(hop); hattr = RT13.getAttrNum(hop); vst = DMF.reg.getuo(UO_2D, 3); int vop = REJIF.getCombinedRayFieldOp(vst); - vsurf = RT13.getGroupNum(vop); + vsurf = RT13.getSurfNum(vop); vattr = RT13.getAttrNum(vop); nhbins = U.parseInt(DMF.reg.getuo(UO_2D, 4)); @@ -260,7 +250,7 @@ private void doParse() RT13.iBuildRays(true); for (int kray=1; kray<=nrays; kray++) { - if (RT13.bGoodRay[kray]) + if (RT13.isRayOK[kray]) { double h = RT13.dGetRay(kray, hsurf, hattr); double v = RT13.dGetRay(kray, vsurf, vattr); @@ -387,7 +377,7 @@ private void doParse() for (int j=0; j= RGOAL) // Comparo handles floating goals update - continue; + if (op >= RGOAL) // Comparo handles floating goals update + continue; else - if (op >= 100) // output table data are wanted here... - { - rayEditor.putBlank(f, row); - int g = RT13.getGroupNum(op); // handles "final" - int ia = RT13.getAttrNum(op); - if ((ia>=0) && (ia0) && (g<=howfarRay)) - rayEditor.putFieldDouble(f, row, RT13.dGetRay(kray,g,ia)); - } + if (op >= 100) // output table results are wanted here... + { + rayEditor.putBlank(f, row); + int j = RT13.getSurfNum(op); // handles "final" + int ia = RT13.getAttrNum(op); + + if ((ia>=0) && (ia0) && (j<=howfarOK)) + { + double x = RT13.dGetRay(kray,j,ia); + if (U.isNotNegZero(x)) + rayEditor.putFieldDouble(f, row, RT13.dGetRay(kray,j,ia)); // in EJIF + } + } } // done with writing all fields for this ray. } // done with all rays. diff --git a/Sources/LayoutPanel.java b/Sources/LayoutPanel.java index 8c7eebf..bfb7989 100755 --- a/Sources/LayoutPanel.java +++ b/Sources/LayoutPanel.java @@ -1,12 +1,15 @@ package com.stellarsoftware.beam; import javax.swing.*; // obtain Graphics2D features +import java.util.Arrays; // to list an int array jhit[] below @SuppressWarnings("serial") /** * Custom artwork class furnishes layout artwork to GPanel. - * + * 26 Dec 2018 A207 line 1123 eliminated negative surfaces + * 30 Dec 2018 A207.11 skipping negative zero Z ray points -- line 1140; + * ^^ this allows bimodals to skip surfaces leaving -0.0 there. * * Fontcode accompanies each char, and use CenterOrigin for fontXY. * Internal coord frame is user dimensions cube, center origin, +y=up. @@ -100,8 +103,8 @@ public class LayoutPanel extends GPanel // implements B4constants via GPanel private char cArrayType[] = new char[MAXSURFS+1]; // 'I', 'L', 'M', else not an array. - //---------the surface radii----see line 416------------------ - private double rox[]; // = new double[MAXSURFS+1]; // working radius + //---------the surface radii----see line 528------------------ + private double rox[]; // = new double[MAXSURFS+1]; // working radius; see line 528 private double roy[]; // = new double[MAXSURFS+1]; // working radius private double gox[]; // = new double[MAXSURFS+1]; // given outer radius, x private double goy[]; // = new double[MAXSURFS+1]; // given outer radius, y @@ -137,15 +140,13 @@ public LayoutPanel(GJIF gj) //---protected methods mandated by GPanel-------- protected void doTechList(boolean bArtStatus) // replaces abstract "do" - // Called by GPanel when fresh artwork is needed: - // new, pan, zoom, rotate. + // Called by GPanel when fresh artwork is needed: new pan, zoom, rotate. // But this is not called for annotations or caret blinks. // For annotation, host's bitmap of TechList is blitted instead, // then annotation and caret are written atop the bitmap. // Copyright 2006 STELLAR SOFTWARE all rights reserved { nsurfs = DMF.giFlags[ONSURFS]; - ngroups = DMF.giFlags[ONGROUPS]; nrays = DMF.giFlags[RNRAYS]; ngood = RT13.iBuildRays(true); int istatus = DMF.giFlags[STATUS]; @@ -486,7 +487,7 @@ private void getNewAffines() zmax = zcenter + radius; //----set the affines in GPanel---- - //---and in doArt() be sure to addAffines() before drawing--- + //---and in doFullArt() be sure to addAffines() before drawing--- uxcenter = 0.5 * (hmax + hmin); // protected field of GPanel uycenter = 0.5 * (vmax + vmin); // protected field of GPanel @@ -571,7 +572,7 @@ private void doArrays() { for (int k=1; k<=nrays; k++) { - int jmax = RT13.getHowfarRay(k); + int jmax = RT13.getHowfarOK(k); for (int j=1; j<=jmax; j++) if (!bGivenOuterRadius[j]) // absentee found @@ -699,7 +700,7 @@ boolean isOuterRect(int j) /// 8 = arrayrect = ARRRECT /// 9 = connector = CONNECT /// - /// Better design: use ArrayList which is extendable? + /// Better design: use ArrayList whichbase is extendable? /// An array can be sorted; don't know about an ArrayList. boolean bbb[] = new boolean[MAXSORT]; // sorted foreground identifier @@ -900,17 +901,17 @@ else if ((OTRETRO == (int) RT13.surfs[j][OTYPE]) && !bRetroVis) /********* - private void add2D(double x, double y, int op, int which) + private void add2D(double x, double y, int op, int whichbase) // For 2D artwork scaled with current affines, for example rulers. // Do not call viewelaz(). { - addScaled(x, y, 0.0, op, which); // GPanel service + addScaled(x, y, 0.0, op, whichbase); // GPanel service } - private void addRawLocal(double x, int op, int which) + private void addRawLocal(double x, int op, int whichbase) // for unscaled 2D artwork in raw pixel units, for example linewidths. { - addRaw(x, 0.0, 0.0, op, which); // GPanel service + addRaw(x, 0.0, 0.0, op, whichbase); // GPanel service } ***********/ @@ -928,7 +929,7 @@ void doFullArt() RT13.refractLayoutShading[j] = RT13.getRefraction(j, 1); whitebkg = "T".equals(DMF.reg.getuo(UO_LAYOUT, 15)); - + // QBASE is a global constant, base of artwork; then QBATCH, QRAND, QFINISH, QANNO. clearList(QBASE); addRaw(0., 0., 0., whitebkg ? SETWHITEBKG : SETBLACKBKG, QBASE); addRaw(0., 0., 0., SETCOLOR + (whitebkg ? BLACK : WHITE), QBASE); @@ -961,7 +962,7 @@ void doFullArt() void doSkeleton() - // This is a simplified doArt(), no zsort, no rays, no shading. + // This is a simplified doFullArt(), no zsort, no rays, no shading. // Writes its quads to baseList. // It is displayed only during mouse-down drag/zoom/twirl motion. // Assumes we've already set rox[], roy[], nSpiderLegs[] etc. @@ -1097,7 +1098,7 @@ private void doFurniture() private void doBlank() - // A simplified doArt() that creates a blank field. + // A simplified doFullArt() that creates a blank field. // Used when artwork is requested but cannot be generated { clearList(QBASE); @@ -1106,24 +1107,34 @@ private void doBlank() } - private boolean drawOneRay(int kray, int which) - // called by doArt() and by doRandomRay(). + private boolean drawOneRay(int kray, int whichbase) + // called by doFullArt() and by doRandomRay(). // Puts a ray onto any specified quadList. // Returns boolean since doRandomRay() counts status. // Copyright 2006 STELLAR SOFTWARE all rights reserved - // howfar = 1...ngroups + // howfar = 0 to nsurfs; + // can skip points having Z=-0.0 for bimodals. + // Table rays are plotted into the memory area QBASE + // Random rays are batch mode and go into QBATCH. { + // System.out.println("-----Layout has started with kray = "+kray); + boolean isGood; if (kray == 0) isGood = RT13.bRunRandomRay(); else - isGood = RT13.bGoodRay[kray]; - int rayerr = RT13.getStatus(kray); // ray error status - int howfar = RT13.getHowfarLoop(kray); // end or trouble spot + isGood = RT13.isRayOK[kray]; + int rayerr = RT13.getStatus(kray); + boolean rrok = (rayerr == RROK); + int howfarOK = RT13.getHowfarOK(kray); + + // System.out.println("Layout starting kray = "+kray+", isGood = "+isGood+", howfarOK = "+howfarOK); + // double u0 = RT13.dGetRay(kray,0,RU); + // System.out.println("Layout starting kray has u0 = "+u0); + boolean bExtend = RT13.getExtend(kray); int kGuide = (kray==0) ? RT13.getGuideRay() : kray; - int jsolid = bExtend ? howfar-1 : howfar; - boolean rrok = (rayerr == RROK); + int icolor = (int) RT13.raystarts[kGuide][RSCOLOR]; if ((icolor==WHITE) && whitebkg) icolor=BLACK; @@ -1132,41 +1143,80 @@ private boolean drawOneRay(int kray, int which) if (widthRays == 0) return isGood; + + //------boil the surfaces down to the good (not-skipped) surfaces---- + int jhit[] = new int[nsurfs+1]; + jhit[0] = 0; // surface zero is always one hit. + int nBeyondZero = 0; // how many hits beyond zero + for (int j=1; j<=howfarOK; j++) + { + double Z = RT13.dGetRay(kray, j, RZ); + if (U.isNegZero(Z)) // skip absentee intercepts + continue; + else + nBeyondZero++; + jhit[nBeyondZero] = j; // gather good intercepts for artwork + } + int jsolid = jhit[nBeyondZero]; + if (DEBUG) + System.out.println("-----Layout jhit[] = " + Arrays.toString(jhit)); + + // DON'T EXIT THERE MIGHT BE JUST ONE HIT (NO SOLID) BUT COULD STILL HAVE AN EXTEND + // nSystem.out.println("LayoutPanel finds jsolid = "+jsolid); + + //------now draw this ray------------ - addRaw(0., 0., 0., COMMENTRAY, which); - addRaw(widthRays, 0., 0., SETSOLIDLINE, which); - addRaw(0., 0., 0., SETCOLOR+icolor, which); + addRaw(0., 0., 0., COMMENTRAY, whichbase); + addRaw(widthRays, 0., 0., SETSOLIDLINE, whichbase); + addRaw(0., 0., 0., SETCOLOR+icolor, whichbase); double xyz[] = {0., 0., 0.}; - if (jsolid > 0) // solid part, propagation OK + if (nBeyondZero > 0) // solid part, propagation OK { - for (int j=0; j<=jsolid; j++) + if (DEBUG) + System.out.println("-----Layout is starting kray = "+kray); + for (int h=0; h<=nBeyondZero; h++) { + + int j = jhit[h]; xyz[0] = RT13.dGetRay(kray, j, RX); xyz[1] = RT13.dGetRay(kray, j, RY); xyz[2] = RT13.dGetRay(kray, j, RZ); + if (DEBUG) + System.out.printf("-----Layout is adding hit, jsurf, x = %6d %6d %12.6f \n", h, j, xyz[0]); + viewelaz(xyz); - int itype = (int) RT13.dGetSurf(OTYPE,j); + int itype = (int) RT13.dGetSurfParm(OTYPE,j); boolean bCBIN = (OTCBIN == itype); boolean bCBOUT = (OTCBOUT == itype); int op = ((j==0 || bCBOUT) ? MOVETO : (j==jsolid || bCBIN) ? STROKE : PATHTO); - addScaled(xyz, op, which); + addScaled(xyz, op, whichbase); } } if (bExtend) { - addRaw(widthRays, 0., 0., SETDOTTEDLINE, which); + // Although the ray trace ends at howfar, RT13.bRunOneRay() used vExtendLabs() to + // gain another surface at howfar+1 that has the extension information. + // This extension is hidden by InOut so no one will be the wiser. Heh heh. + // The extension numbers are handled by RT13 + addRaw(widthRays, 0., 0., SETDOTTEDLINE, whichbase); + + if (DEBUG) + System.out.println("Layout extending from jsolid = "+jsolid); xyz[0] = RT13.dGetRay(kray, jsolid, RX); xyz[1] = RT13.dGetRay(kray, jsolid, RY); xyz[2] = RT13.dGetRay(kray, jsolid, RZ); viewelaz(xyz); - addScaled(xyz, MOVETO, which); + addScaled(xyz, MOVETO, whichbase); + + if (DEBUG) + System.out.println("Layout extending to jsolid+1 = "+(jsolid+1)); xyz[0] = RT13.dGetRay(kray, jsolid+1, RX); xyz[1] = RT13.dGetRay(kray, jsolid+1, RY); xyz[2] = RT13.dGetRay(kray, jsolid+1, RZ); viewelaz(xyz); - addScaled(xyz, STROKE, which); + addScaled(xyz, STROKE, whichbase); } return isGood; } @@ -1386,7 +1436,7 @@ private void doFinishArt() //--------putFunctions are for drawing individual parts------------ //-----these assume we've already set rox[], roy[], nSpiderLegs[] etc---- - void putSpiderHole(int j, int ihole, boolean bWholeHole, int which) + void putSpiderHole(int j, int ihole, boolean bWholeHole, int whichbase) // j = surface number, 1....nsurfs // ihole = hole number 0...nholes-1 // one four-arc hole is drawn per spider leg. @@ -1433,9 +1483,9 @@ void putSpiderHole(int j, int ihole, boolean bWholeHole, int which) vx2lab(xyz, RT13.surfs[j]); viewelaz(xyz); if (bWholeHole) - addScaled(xyz, (i==0) ? MOVETO : PATHTO, which); + addScaled(xyz, (i==0) ? MOVETO : PATHTO, whichbase); else - addScaled(xyz, (i==0) ? MOVETO : (i U.TOL) // inner periphery @@ -1465,7 +1515,7 @@ void putSpiderHole(int j, int ihole, boolean bWholeHole, int which) xyz[2] = Z.dGetZsurf(xyz[0], xyz[1], RT13.surfs[j]); vx2lab(xyz, RT13.surfs[j]); viewelaz(xyz); - addScaled(xyz, PATHTO, which); + addScaled(xyz, PATHTO, whichbase); } a = aThisLeg + aOuter; // outgoing leg side @@ -1478,7 +1528,7 @@ void putSpiderHole(int j, int ihole, boolean bWholeHole, int which) xyz[2] = Z.dGetZsurf(xyz[0], xyz[1], RT13.surfs[j]); vx2lab(xyz, RT13.surfs[j]); viewelaz(xyz); - addScaled(xyz, (i 0.998) + if (labx[whichbaseAxis] > 0.998) return "+X"; - if (labx[whichAxis] < -0.998) + if (labx[whichbaseAxis] < -0.998) return "-X"; double laby[] = {0, 1, 0}; viewelaz(laby); - if (laby[whichAxis] > 0.998) + if (laby[whichbaseAxis] > 0.998) return "+Y"; - if (laby[whichAxis] < -0.998) + if (laby[whichbaseAxis] < -0.998) return "-Y"; double labz[] = {0, 0, 1}; viewelaz(labz); - if (labz[whichAxis] > 0.998) + if (labz[whichbaseAxis] > 0.998) return "+Z"; - if (labz[whichAxis] < -0.998) + if (labz[whichbaseAxis] < -0.998) return "-Z"; return " "; } diff --git a/Sources/MEJIF.java b/Sources/MEJIF.java index 32af759..5ef291b 100755 --- a/Sources/MEJIF.java +++ b/Sources/MEJIF.java @@ -63,7 +63,7 @@ void parse() // replaces the abstract parse() in EJIF if (nglasses < 1) return; - /////////////// initialize the nongeneric output data ////////////// + /////////////// initialize the output data ////////////// DMF.giFlags[MNWAVES] = 0; DMF.giFlags[MSYNTAXERR] = 0; @@ -80,15 +80,21 @@ void parse() // replaces the abstract parse() in EJIF //////////// mwaves[1...] begin at field=1, line=1 ////// - for (int f=1; f 0) { - ok = parseOneStepVar(sHpar, asHp, ngroups); + ok = parseOneStepVar(sHpar, asHp, nsurfs); if (!ok) return "Hparallax is unknown"; } if (sVpar.length() > 0) { - ok = parseOneStepVar(sVpar, asVp, ngroups); + ok = parseOneStepVar(sVpar, asVp, nsurfs); if (!ok) return "Vparallax is unknown"; } @@ -435,7 +434,7 @@ private double getOpticsNominalValue(int iatt, int jsurf) { if (jsurf > nsurfs) return -0.0; - return RT13.dGetSurf(iatt, jsurf); + return RT13.dGetSurfParm(iatt, jsurf); } @@ -510,9 +509,9 @@ public void doBunchRays(int gBunch) //---trace the rays and gather the datum for this box-------- //---Note: REJIF line 88 sets each ray WFE group index=0 //---prior to running a trace for WFE evaluation. - - for (int kray=0; kray<=nrays; kray++) - RT13.iWFEgroup[kray] = 0; // all rays are in WFEgroup zero + // A207 eliminated WFEs + // for (int kray=0; kray<=nrays; kray++) + // RT13.iWFEgroup[kray] = 0; // all rays are in WFEgroup zero double d = -0.0; int ngood = RT13.iBuildRays(true); // builds all rays @@ -638,8 +637,8 @@ private double getRssPSF() // RFINAL in B4Constants = 10000; placeholder for 100*nsurfs term. int opxf = RFINAL + RTXL; // opcode for xfinal int opyf = RFINAL + RTYL; // opcode for yfinal - int xsurf = RT13.getGroupNum(opxf); // handles "final" surface - int ysurf = RT13.getGroupNum(opyf); // handles "final" surface + int xsurf = RT13.getSurfNum(opxf); // handles "final" surface + int ysurf = RT13.getSurfNum(opyf); // handles "final" surface if ((xsurf < 1) || (ysurf < 1)) return BADCELL; int n = 0; diff --git a/Sources/OEJIF.java b/Sources/OEJIF.java index 91ca19c..7f8aedc 100755 --- a/Sources/OEJIF.java +++ b/Sources/OEJIF.java @@ -12,6 +12,7 @@ * The function of parse() is to set values into DMF.giFlags[] and RT13.surfs[][]. * * It implements Constants via EJIF. + * The ACTUAL PARSING WORK is done by getOptFieldAttrib(String s), bottom of this file. * * parse() has no dirty bit worksavers; it always parses. * @@ -48,7 +49,6 @@ void parse() DMF.giFlags[OPRESENT] = status[GPRESENT]; DMF.giFlags[ONLINES] = status[GNLINES]; DMF.giFlags[ONSURFS] = nsurfs = status[GNRECORDS]; - DMF.giFlags[ONGROUPS] = nsurfs; DMF.giFlags[ONFIELDS] = nfields = status[GNFIELDS]; if (nsurfs < 1) return; @@ -64,9 +64,6 @@ void parse() RT13.surfs[j][ia] = -0.0; // minus zero means blank entry. RT13.surfs[j][OREFRACT] = 1.0; - RT13.jstart[j] = j; // groups - RT13.jstop[j] = j; // groups - RT13.group[j] = j; // groups } for (int f=0; f ABSENT) // groups column present? - { - for (int j=1; j<=nsurfs; j++) - cGroup[j] = U.getCharAt(getFieldTrim(ifield, 2+j), 0); - RT13.group[1] = 1; - RT13.jstart[1] = 1; - RT13.jstop[1] = 1; - - for ( int j=1; j<=MAXSURFS; j++) - { - boolean bNew = (cGroup[j] == ' ') - || (cGroup[j-1] == ' ') - || (cGroup[j] != cGroup[j-1]); - int g = bNew ? RT13.group[j-1]+1 : RT13.group[j-1]; - RT13.group[j] = g; - if (bNew) - RT13.jstart[g] = j; - RT13.jstop[g] = j; - } - for (int j=nsurfs+1; j<=MAXSURFS; j++) - RT13.group[j] = RT13.group[nsurfs]; - - DMF.giFlags[ONGROUPS] = RT13.group[nsurfs]; - } - - //----------refraction: sometimes numerical data-------------- //---if refraction LUT is needed, OREFRACT will be NaN.---- @@ -266,6 +244,7 @@ void parse() for (int f=0; f0.0) + for (int kg=OORDER; kg 0.) // found a Gaussian surface profile + { + iProfile = OSGAUSS; + } //---------apply hints to conic or cyl, not higher---------- switch (iProfile) @@ -534,6 +517,8 @@ else if (bX) if ('>' == typetag[j]) iProfile = OSYCYLGT; break; } + // System.out.println("OEJIF parse() surface= "+j+" finds iProfile= "+iProfile+" "+sProfiles[iProfile]); + RT13.surfs[j][OPROFILE] = iProfile; } @@ -542,14 +527,12 @@ else if (bX) dOsize = 0.0; for (int j=1; j<=nsurfs; j++) { - dOsize += Math.abs(RT13.surfs[j][OX]); - dOsize += Math.abs(RT13.surfs[j][OY]); - dOsize += Math.abs(RT13.surfs[j][OZ]); - dOsize += Math.abs(RT13.surfs[j][OODIAM]); - dOsize += Math.abs(RT13.surfs[j][OODIAX]); + dOsize = Math.max(dOsize, Math.abs(RT13.surfs[j][OX])); + dOsize = Math.max(dOsize, Math.abs(RT13.surfs[j][OY])); + dOsize = Math.max(dOsize, Math.abs(RT13.surfs[j][OZ])); + dOsize = Math.max(dOsize, Math.abs(RT13.surfs[j][OODIAM])); + dOsize = Math.max(dOsize, Math.abs(RT13.surfs[j][OODIAX])); } - if (nsurfs > 1) - dOsize /= nsurfs; if (dOsize < TOL) dOsize = 1.0; @@ -732,13 +715,19 @@ public static int getOptFieldAttrib(String s) // Table data should be numerical, except ABSENT, OFORM, OTYPE, OREFRACT. // Radius of curvature is written "RxCxxxx" i.e. c2up='C'. { - char c0=' ', c1up=' ', c2up=' ', c3up=' ', c4up=' '; + // System.out.println("OEJIF method getOptFieldAttrib() is given arg = "+s); + char c0=' ', c0up=' ', c1up=' ', c2up=' ', c3up=' ', c4up=' '; + String svls = ""; + s = s.trim(); int len = s.length(); if (len < 1) return ABSENT; - c0 = s.charAt(0); - s = s.toUpperCase(); + c0 = s.charAt(0); // save case of c0 + c0up = Character.toUpperCase(c0); + if ((len == 4) && (c0up == 'V')) + svls = s.toUpperCase(); + s = s.toUpperCase(); // ignore case beyond c0 if (len > 1) c1up = s.charAt(1); if (len > 2) @@ -776,9 +765,9 @@ public static int getOptFieldAttrib(String s) case '9': return OA9; case 'C': return OTYPE; // "ACTION" } - if (s.contains("X")) + if (s.endsWith("X")) return OASPHX; - if (s.contains("Y")) + if (s.endsWith("Y") && (len < 9)) // allows 'asphericity' return OASPHY; return OASPHER; @@ -810,17 +799,20 @@ public static int getOptFieldAttrib(String s) case 'R': return OGROUP; case 'X': return OGX; case 'Y': return OGY; - case '1': return OVLS1; - case '2': return OVLS2; - case '3': return OVLS3; - case '4': return OVLS4; + // case '1': return OVLS1; // removed 22 March 2016 A192 + // case '2': return OVLS2; + // case '3': return OVLS3; + // case '4': return OVLS4; } return ABSENT; case 'H': - case 'h': if (len < 4) // HOE entries - return ABSENT; - switch(c3up) + case 'h': if (len < 4) + return ABSENT; + if (c1up=='G') + return OHGAUSS; // height of 2D Gaussian + + switch(c3up) // HOE entries { case 'L': case 'l': return OHOELAM; @@ -873,29 +865,85 @@ public static int getOptFieldAttrib(String s) case 'p': return OPITCH; case 'R': - case 'r': if ((c2up=='C') && (c3up=='X')) return ORADX; + case 'r': if (c1up=='G') return ORGAUSS; // 2D Gaussian radius or sigma + if ((c2up=='C') && (c3up=='X')) return ORADX; if ((c2up=='C') && (c3up=='Y')) return ORADY; if (c2up=='C') return ORAD; return OROLL; case 'S': - case 's': if (c1up=='C') return OSCATTER; + case 's': if (c1up=='C') return OSCATTER; // angle, degrees return OSHAPE; case 'T': case 't': if (c1up == 'Y') return OTYPE; return OTILT; // tilt. - case 'V': - case 'v': switch (c3up) + case 'V': // twenty curl-free explicit VLS coefficients + case 'v': + if (svls.equals("VX00")) return OGX; // synonym + if (svls.equals("VX10")) return OVX10; + if (svls.equals("VX20")) return OVX20; + if (svls.equals("VX30")) return OVX30; + if (svls.equals("VX40")) return OVX40; + if (svls.equals("VY00")) return OGY; // synonym + if (svls.equals("VY01")) return OVY01; + if (svls.equals("VY02")) return OVY02; + if (svls.equals("VY03")) return OVY03; + if (svls.equals("VY04")) return OVY04; + if (svls.equals("VY10")) return OVY10; + if (svls.equals("VY11")) return OVY11; + if (svls.equals("VY12")) return OVY12; + if (svls.equals("VY13")) return OVY13; + if (svls.equals("VY20")) return OVY20; + if (svls.equals("VY21")) return OVY21; + if (svls.equals("VY22")) return OVY22; + if (svls.equals("VY30")) return OVY30; + if (svls.equals("VY31")) return OVY31; + if (svls.equals("VY40")) return OVY40; + return ABSENT; + + + /*************************************** + switch (c1up) { - case '1': return OVLS1; - case '2': return OVLS2; - case '3': return OVLS3; - case '4': return OVLS4; + case 'X': switch(c2up) + { + case '1': return OVLX10; + case '2': return OVLX20; + case '3': return OVLX30; + default: return ABSENT; + } + case 'Y': switch (c2up) + { + case '0': switch(c3up) + { + case '1': return OVLY01; + case '2': return OVLY02; + case '3': return OVLY03; + default: return ABSENT; + } + case '1': switch(c3up) + { + case '0': return OVLY10; + case '1': return OVLY11; + case '2': return OVLY12; + default: return ABSENT; + } + case '2': switch (c3up) + { + case '0': return OVLY20; + case '1': return OVLY21; + default: return ABSENT; + } + case '3': if (c3up == '0') return OVLY30; + } } return ABSENT; - + ********************************/ + + + case 'W': case 'w': if (c1up=='S') return OWSPIDER; diff --git a/Sources/Options.java b/Sources/Options.java index e8603c5..ef1ba09 100755 --- a/Sources/Options.java +++ b/Sources/Options.java @@ -15,7 +15,7 @@ * * Options extends JMenu, provides an options system using strings. * - * ALL OPTION STRINGS ARE DEFINED IN CONSTANTS.JAVA not here. + * ALL OPTION STRINGS ARE DEFINED IN B4constants.java not here. * * ActionListeners implement the dialogs to help separate GUI from code. * Both Registry and Options implement Constants. @@ -58,7 +58,18 @@ public Options(String menuname, JFrame gjf) /// the constructor { super(menuname); owner = gjf; - + + JMenuItem newfileItem = new JMenuItem("NewFile"); + newfileItem.addActionListener(new + ActionListener() + { + public void actionPerformed(ActionEvent ae) + { + doNewfileDialog(owner); + } + }); + this.add(newfileItem); + JMenuItem inoutItem = new JMenuItem("InOut"); inoutItem.addActionListener(new ActionListener() @@ -342,7 +353,35 @@ public void actionPerformed(ActionEvent ae) //------private dialog methods; each uses JOptionPane-------------- - + //------private dialog methods; each uses JOptionPane-------------- + //------private dialog methods; each uses JOptionPane-------------- + //------private dialog methods; each uses JOptionPane-------------- + //------private dialog methods; each uses JOptionPane-------------- + //------private dialog methods; each uses JOptionPane-------------- + //------private dialog methods; each uses JOptionPane-------------- + + void doNewfileDialog(JFrame frame) + // allows user to choose NewFile skeleton parameters + { + LabelDataBox nrecordsBox = new LabelDataBox(UO_NEWFILE, 0, NCHARS); + LabelDataBox nfieldsBox = new LabelDataBox(UO_NEWFILE, 1, NCHARS); + LabelDataBox nwidthBox = new LabelDataBox(UO_NEWFILE, 2, NCHARS); + + int result = JOptionPane.showOptionDialog(frame, + new Object[] {nrecordsBox, nfieldsBox, nwidthBox}, + "New File Options", + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.PLAIN_MESSAGE, + null, null, null); + if (result == JOptionPane.OK_OPTION) + { + DMF.reg.putuo(UO_NEWFILE, 0, nrecordsBox.getText()); + DMF.reg.putuo(UO_NEWFILE, 1, nfieldsBox.getText()); + DMF.reg.putuo(UO_NEWFILE, 2, nwidthBox.getText()); + } + } + + void doInOutDialog(JFrame frame) { LabelBitBox rms = new LabelBitBox(UO_IO, 0); @@ -368,6 +407,7 @@ void doLayoutDialog(JFrame frame) LabelDataBox el = new LabelDataBox(UO_LAYOUT, 0, NCHARS); LabelDataBox az = new LabelDataBox(UO_LAYOUT, 1, NCHARS); LabelDataBox ar = new LabelDataBox(UO_LAYOUT, 3, NCHARS); + LabelDataBox dx = new LabelDataBox(UO_LAYOUT, 39, NCHARS); // RT13 line 2500 LabelBitBox sticky = new LabelBitBox(UO_LAYOUT, 2); String title1 = "Which axis is to point upward?"; @@ -390,7 +430,7 @@ void doLayoutDialog(JFrame frame) UO_LAYOUT, 15, frame); int result = JOptionPane.showOptionDialog(frame, - new Object[] {el, az, ar, sticky, shading, connect, + new Object[] {el, az, ar, dx, sticky, shading, connect, retrovis, vert, ax, rb, db, bhsb}, "Layout Options", JOptionPane.OK_CANCEL_OPTION, @@ -403,6 +443,7 @@ void doLayoutDialog(JFrame frame) DMF.reg.putuo(UO_LAYOUT, 1, az.getText()); DMF.reg.putuo(UO_LAYOUT, 2, sticky.isSelected() ? "T" : "F"); DMF.reg.putuo(UO_LAYOUT, 3, ar.getText()); + DMF.reg.putuo(UO_LAYOUT, 39, dx.getText()); for (int i=0; i<6; i++) DMF.reg.putuo(UO_LAYOUT, 4+i, vert.isSelected(i) ? "T" : "F"); for (int i=0; i<5; i++) @@ -470,14 +511,13 @@ void doPlot2Dialog(JFrame frame) LabelDataBox wave = new LabelDataBox(UO_PLOT2, 4, NCHARS); BorVertRadioBox spot = new BorVertRadioBox("Dot style", UO_PLOT2, 5, 4); JLabel blank = new JLabel(" "); - BorVertRadioBox rays = new BorVertRadioBox("Which rays", UO_PLOT2, 9, 2); - LabelDataBox other = new LabelDataBox(UO_PLOT2, 11, 3); - LabelBitBox black = new LabelBitBox(UO_PLOT2, 12); + BorVertRadioBox rays = new BorVertRadioBox("Which rays", UO_PLOT2, 9, 2); // 9=Complete; 10=Sufficient + LabelBitBox black = new LabelBitBox(UO_PLOT2, 11); int result = JOptionPane.showOptionDialog(frame, new Object[] {hvar, hran, hlabel, hblank, vvar, vran, vlabel, vblank, - wave, spot, blank, rays, other, black}, + wave, spot, blank, rays, black}, "Plot2Dim Options", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, @@ -497,8 +537,7 @@ void doPlot2Dialog(JFrame frame) for (int i=0; i<2; i++) DMF.reg.putuo(UO_PLOT2, 9+i, rays.isSelected(i) ? "T" : "F"); - DMF.reg.putuo(UO_PLOT2, 11, other.getText()); - DMF.reg.putuo(UO_PLOT2, 12, black.isSelected() ? "T" : "F"); + DMF.reg.putuo(UO_PLOT2, 11, black.isSelected() ? "T" : "F"); updateAllInstances("Plot2Dim"); } @@ -633,18 +672,18 @@ void doMapDialog(JFrame frame) void doPlot3Dialog(JFrame frame) { - LabelDataBox avar = new LabelDataBox(UO_PLOT3, 0, NCHARS); - LabelDataBox aran = new LabelDataBox(UO_PLOT3, 1, NCHARS); - LabelDataBox bvar = new LabelDataBox(UO_PLOT3, 2, NCHARS); - LabelDataBox bran = new LabelDataBox(UO_PLOT3, 3, NCHARS); - LabelDataBox cvar = new LabelDataBox(UO_PLOT3, 4, NCHARS); - LabelDataBox cran = new LabelDataBox(UO_PLOT3, 5, NCHARS); + LabelDataBox avar = new LabelDataBox(UO_PLOT3, 0, NCHARS); // A var + LabelDataBox aran = new LabelDataBox(UO_PLOT3, 1, NCHARS); // A span + LabelDataBox bvar = new LabelDataBox(UO_PLOT3, 2, NCHARS); // B var + LabelDataBox bran = new LabelDataBox(UO_PLOT3, 3, NCHARS); // B span + LabelDataBox cvar = new LabelDataBox(UO_PLOT3, 4, NCHARS); // C var + LabelDataBox cran = new LabelDataBox(UO_PLOT3, 5, NCHARS); // C span LabelBox clabel = new LabelBox("Set any span=0.0 for auto scaling"); - LabelDataBox elev = new LabelDataBox(UO_PLOT3, 6, NCHARS); - LabelDataBox azim = new LabelDataBox(UO_PLOT3, 7, NCHARS); - LabelDataBox wave = new LabelDataBox(UO_PLOT3, 8, NCHARS); - BorHorizRadioBox spot = new BorHorizRadioBox("Dot style", UO_PLOT3, 9, 4); - BorVertRadioBox rays = new BorVertRadioBox("Which rays", UO_PLOT3, 13, 2); + LabelDataBox elev = new LabelDataBox(UO_PLOT3, 6, NCHARS); // elev + LabelDataBox azim = new LabelDataBox(UO_PLOT3, 7, NCHARS); // azim + LabelDataBox wave = new LabelDataBox(UO_PLOT3, 8, NCHARS); // wavel + BorHorizRadioBox spot = new BorHorizRadioBox("Dot style", UO_PLOT3, 9, 4); // 9,10,11,12 + BorVertRadioBox rays = new BorVertRadioBox("Which rays", UO_PLOT3, 13, 2); // 13=Complete, 14=Sufficient BorHorizStereoBox bhsb = new BorHorizStereoBox("Format", UO_PLOT3, 15, frame); int result = JOptionPane.showOptionDialog(frame, @@ -1146,7 +1185,9 @@ void doRay1dDialog(JFrame frame) // Ray Generator, 1D //// now try putting the coordinates into place int errcode = iPut1Drays(igoal, iwhich, dCenter, dSpan, nCount, istartrow); - if (errcode != 0) + if (errcode < 0) + JOptionPane.showMessageDialog(frame, "Too many rays"); + if (errcode > 0) { String w[] = {"X", "Y", "Z", "U", "V", "W"}; char c = (igoal==0) ? '0' : 'g'; @@ -1245,7 +1286,11 @@ void doRayRectDialog(JFrame frame) // Ray generator 2D rect int q = iPutRectRays(igoal, iwhich, dCenter1, dSpan1, nCount1, dCenter2, dSpan2, nCount2, istartrow); - if (q != 0) + + if (q < 0) + JOptionPane.showMessageDialog(frame, "Too many rays requested"); + + if (q > 0) { String w1[] = {"X", "X", "Y", "U", "U", "V"}; String w2[] = {",Y", ",Z", ",Z", ",V", ",W", ",W"}; @@ -1287,7 +1332,8 @@ void doRayCircDialog(JFrame frame) // circular pattern ray builder LabelDataBox off2 = new LabelDataBox(UO_2DCRAY, 7, NCHARS); LabelDataBox radius = new LabelDataBox(UO_2DCRAY, 8, NCHARS); String s3 = "How many concentric circles?"; - BorderedHexBox bhb = new BorderedHexBox(s3, UO_2DCRAY, 9, 17, 1, frame); + // note: 17 circles = 919 rays; 34 rings = 3571 rays. + BorderedHexBox bhb = new BorderedHexBox(s3, UO_2DCRAY, 9, MAXRINGS, 1, frame); JLabel blank = new JLabel(" "); LabelDataBox start = new LabelDataBox(UO_2DCRAY, 10, NCHARS); @@ -1376,7 +1422,8 @@ void doRayGausDialog(JFrame frame) // circular Gaussian ray builder LabelDataBox radius = new LabelDataBox(UO_2DCGAUS, 8, NCHARS); String s3 = "How many concentric circles?"; - BorderedHexBox bhb = new BorderedHexBox(s3, UO_2DCGAUS, 9, 17, 0, frame); + // note: 17 circles = 919 rays; 34 rings = 3571 rays. + BorderedHexBox bhb = new BorderedHexBox(s3, UO_2DCGAUS, 9, MAXRINGS, 0, frame); JLabel blank = new JLabel(" "); LabelDataBox start = new LabelDataBox(UO_2DCGAUS, 10, NCHARS); @@ -1482,6 +1529,8 @@ private int iPut1Drays(int g, int w, double dC, double dS, int nrays, int istart // w chooses which coordinate: x,y,z,u,v,w = 0...5 { int icoord[] = {RX, RY, RZ, RU, RV, RW}; + if (nrays >= MAXRAYS) + return -1; if ((w < 0) || (w > 5)) return 1; int i1 = icoord[w]; @@ -1533,6 +1582,10 @@ private int iPutRectRays(int g, int w, double dC1, double dS1, int n1, // Used by doRayRectDialog() to make a rectangular ray pattern. // g=1: goals; g=0: raystarts { + int nrays = n1*n2; + if (nrays >= MAXRAYS) + return -1; + int icoord1[] = {RX, RX, RY, RU, RU, RV}; int icoord2[] = {RY, RZ, RZ, RV, RW, RW}; if ((w < 0) || (w > 5)) @@ -1545,9 +1598,9 @@ private int iPutRectRays(int g, int w, double dC1, double dS1, int n1, if (redit == null) return 2; - int nrays = n1*n2; - if ((n1<1) || (n2<1) || (nrays>999)) + if ((n1<1) || (n2<1)) return 3; + if ((dS1<=0.0) || (dS2<=0.0)) return 4; @@ -1605,6 +1658,7 @@ private int iPutCircles(int g, int w, int ncircles, double d1, double d2, double R, int istart) // Used by doRayCircDialog() to make circular ray patterns. // g=1: goals; g=0: raystarts + // note: MAXRAYS is enforced via host NRINGS selector { int icoord1[] = {RX, RX, RY, RU, RU, RV}; int icoord2[] = {RY, RZ, RZ, RV, RW, RW}; @@ -1618,8 +1672,6 @@ private int iPutCircles(int g, int w, int ncircles, double d1, if (redit == null) return 2; - if ((ncircles<1) || (ncircles>17)) - return 3; if (R<=0.0) return 4; @@ -1627,7 +1679,6 @@ private int iPutCircles(int g, int w, int ncircles, double d1, { f1 = REJIF.rI2F[i1]; f2 = REJIF.rI2F[i2]; - } else // ray goal { @@ -1683,6 +1734,7 @@ private int iPutGaussian(int g, int w, int ncircles, double d1, double d2, double R, int istart) // Used by doRayGausDialog() to make circular Gaussian ray patterns. // g=1: goals; g=0: raystarts + // note: MAXRAYS is enforced via host MAXRINGS { int icoord1[] = {RX, RX, RY, RU, RU, RV}; int icoord2[] = {RY, RZ, RZ, RV, RW, RW}; @@ -1696,8 +1748,6 @@ private int iPutGaussian(int g, int w, int ncircles, double d1, if (redit == null) return 2; - if ((ncircles<1) || (ncircles>17)) - return 3; if ((R <= 0.0)) return 4; diff --git a/Sources/Plot2Panel.java b/Sources/Plot2Panel.java index 784f3ad..3edff15 100755 --- a/Sources/Plot2Panel.java +++ b/Sources/Plot2Panel.java @@ -5,6 +5,10 @@ @SuppressWarnings("serial") /** + * A207.11: eliminated groups; using bimodals; + * dropping "additional surface" option; + * uses howfarOK[] and skips negative zero data points. + * * Custom artwork class extends GPanel, supplies artwork. * Generates local font information from GetUOGraphicsFontCode(). * Properly responds to changes in nsurfs & nrays (A112). @@ -31,15 +35,13 @@ public class Plot2Panel extends GPanel private int CADstyle = 0; private int iSymbol = 0; - private int nsurfs, nprev, ngroups, nrays, ngood; + private int nsurfs, nprev, nrays, ngood; private int hsurf, hattr, vsurf, vattr; - private int prevGroups[] = new int[MAXSURFS+1]; // detect new groups - private int jOtherSurface = 0; private String hst, vst; private double wavel = 0.0; - private boolean blackbkg = false; + private boolean blackbkg = false; // option number 11 see below private boolean badUO = false; @@ -63,27 +65,16 @@ protected void doTechList(boolean bFullArt) // replaces abstract method // Called by GPanel when fresh Plot2Panel artwork is needed. { nsurfs = DMF.giFlags[ONSURFS]; // always needed. - ngroups = DMF.giFlags[ONGROUPS]; // always needed. nrays = DMF.giFlags[RNRAYS]; // always needed. ngood = RT13.iBuildRays(true); String warn = getUOwarning(); // never crashes. myGJIF.postWarning(warn); - if (warn.length() > 0) badUO = true; // use this in setting display scale - //---see if group assignments have changed---- - boolean bChanged = false; - for (int j=0; j= jmin); - if (bStatus) + // First get a ray: new random, or from existing table + boolean isGood; + int base; + if (kray==0) { - int icolor = (int) RT13.raystarts[kray][RSCOLOR]; - if (blackbkg && (icolor==BLACK)) - icolor = WHITE; - - double xxx = RT13.dGetRay(kray, hsurf, hattr); - double yyy = RT13.dGetRay(kray, vsurf, vattr); - addScaled(xxx, yyy, 0., iSymbol+icolor, QBASE); - if ((jOtherSurface > 0) && (hsurf == vsurf)) - { - xxx = RT13.dGetRay(kray, jOtherSurface, hattr); - yyy = RT13.dGetRay(kray, jOtherSurface, vattr); - icolor = blackbkg ? WHITE : BLACK; - addScaled(xxx, yyy, 0., iSymbol+icolor, QBASE); - } - return true; + isGood = RT13.bRunRandomRay(); + base = QBATCH; + } + else + { + isGood = RT13.isRayOK[kray]; + base = QBASE; } - return false; - } - - boolean drawOneRandomRay() - // Relies upon iSymbol, jOtherSurface, hsurf, ..setup as part of doArt(). - // Success criterion depends on: do we want to require jFinal for all rays? - // or just plot rays that get as far as our plot surface? - { - int jmin = ngroups; - if(DMF.reg.getuo(UO_PLOT2, 10).equals("T")) // plot all rays? - jmin = U.imax3(hsurf, vsurf, jOtherSurface); - - // jmin now encapsulates our complete success criterion - - boolean bStatus; - - RT13.bRunRandomRay(); // run one random ray. - bStatus = (RT13.getHowfarRay(0) >= jmin); - - if (bStatus) + // Now test the ray + + boolean bHasEnough = RT13.getHowfarOK(kray) >= Math.max(hsurf, vsurf); + boolean bHasComplete = RT13.getHowfarOK(kray) == nsurfs; + boolean bWantEnough = DMF.reg.getuo(UO_PLOT2, 10).equals("T"); // option 10 is "Sufficient" + boolean bWantComplete = DMF.reg.getuo(UO_PLOT2, 9).equals("T"); // option 9 is "Complete" + + int iColor; + if (kray==0) + iColor = (int) RT13.raystarts[RT13.getGuideRay()][RSCOLOR]; + else + iColor = (int) RT13.raystarts[kray][RSCOLOR]; + if (blackbkg && (iColor==BLACK)) + iColor = WHITE; + if (DEBUG) + { + System.out.println("Plot2Panel.drawOneRay has iSymbol, iColor = " + iSymbol + " " + iColor); + System.out.println("Plot2panel.drawOneRay() bHasComplete, bHasEnough, bWantComplete, bWantEnough = " + +bHasComplete+bHasEnough+bWantComplete+bWantEnough); + } + if ((bWantEnough && bHasEnough) || (bWantComplete && bHasComplete)) { - int kGuide = RT13.getGuideRay(); - int kkk = kGuide; - int icolor = (int) RT13.raystarts[kkk][RSCOLOR]; - if (blackbkg && (icolor==BLACK)) - icolor = WHITE; - - double xxx = RT13.dGetRay(0, hsurf, hattr); - double yyy = RT13.dGetRay(0, vsurf, vattr); - addScaled(xxx, yyy, 0., iSymbol+icolor, QBATCH); - if ((jOtherSurface > 0) && (hsurf == vsurf)) + double xxx = RT13.dGetRay(kray, hsurf, hattr); + double yyy = RT13.dGetRay(kray, vsurf, vattr); + if (U.isNotNegZero(xxx) && U.isNotNegZero(yyy)) { - xxx = RT13.dGetRay(0, jOtherSurface, hattr); - yyy = RT13.dGetRay(0, jOtherSurface, vattr); - icolor = blackbkg ? WHITE : BLACK; - addScaled(xxx, yyy, 0., iSymbol+icolor, QBATCH); + if (DEBUG) + System.out.printf("Plot2Panel is adding one point at xxx, yyy = %8.4f %8.4f \n", xxx, yyy); + addScaled(xxx, yyy, 0., iSymbol+iColor, base); + return true; } - return true; } return false; } +} //----------end of public class------------------ - - private int getOther(int ngroups) - { - int myOther = 0; - String sOther = DMF.reg.getuo(UO_PLOT2, 11); - char cOther = U.getCharAt(sOther, 0); - if ((cOther == 'f') || (cOther == 'F')) // final surface - myOther = ngroups; - else - myOther = U.suckInt(sOther); - if ((myOther < 1) || (myOther > ngroups)) - myOther = 0; - return myOther; - } -} diff --git a/Sources/Plot3Panel.java b/Sources/Plot3Panel.java index 42f2d3c..95f6929 100755 --- a/Sources/Plot3Panel.java +++ b/Sources/Plot3Panel.java @@ -11,6 +11,7 @@ * Unit Cube: uxcenter=0, uxspan=1, etc. * * Uses CenterOrigin for character locations. + * A207: needs -zero detection for absent data, see line 223 * * DeImplemented: additional surface "jOther" * Not yet implemented: optical path. @@ -34,11 +35,10 @@ public class Plot3Panel extends GPanel final double NCHARSOFFSET = 1.5; private int CADstyle = 0; private int iSymbol = 0; - private int jOther = 0; private double wavel = 0.0; - private boolean whitebkg = true; + private boolean blackbkg = false; // option 16 in B4Constants.java - private int ngroups, nsurfs, nprev, nrays, ngood, asurf, aattr, bsurf, battr, csurf, cattr; + private int nsurfs, nprev, nrays, ngood, asurf, aattr, bsurf, battr, csurf, cattr; private String ast, bst, cst; private int prevGroups[] = new int[MAXSURFS+1]; // detect new groups @@ -81,7 +81,6 @@ protected void doTechList(boolean bFullArt) // replaces abstract method // For annotation, host's bitmap is blitted instead. { nsurfs = DMF.giFlags[ONSURFS]; // always needed. - ngroups = DMF.giFlags[ONGROUPS]; // always needed. nrays = DMF.giFlags[RNRAYS]; // always needed. ngood = RT13.iBuildRays(true); @@ -90,17 +89,7 @@ protected void doTechList(boolean bFullArt) // replaces abstract method if (warn.length() > 0) return; - - //---see if group assignments have changed---- - boolean bChanged = false; - for (int j=0; jRNATTRIBS)) return "Unknown: '"+bst+"'"; @@ -181,7 +170,7 @@ private String getUOwarning() String cst = DMF.reg.getuo(UO_PLOT3, 4); op = REJIF.getCombinedRayFieldOp(cst); - int csurf = RT13.getGroupNum(op); + int csurf = RT13.getSurfNum(op); int cattr = RT13.getAttrNum(op); if ((cattr<0) || (cattr>RNATTRIBS)) return "Unknown: '"+cst+"'"; @@ -199,22 +188,20 @@ private void doParseSizes() ast = DMF.reg.getuo(UO_PLOT3, 0); int op = REJIF.getCombinedRayFieldOp(ast); - asurf = RT13.getGroupNum(op); + asurf = RT13.getSurfNum(op); aattr = RT13.getAttrNum(op); bst = DMF.reg.getuo(UO_PLOT3, 2); op = REJIF.getCombinedRayFieldOp(bst); - bsurf = RT13.getGroupNum(op); + bsurf = RT13.getSurfNum(op); battr = RT13.getAttrNum(op); cst = DMF.reg.getuo(UO_PLOT3, 4); op = REJIF.getCombinedRayFieldOp(cst); - csurf = RT13.getGroupNum(op); + csurf = RT13.getSurfNum(op); cattr = RT13.getAttrNum(op); //--------------view angles-------------- - - // jOther = getOther(ngroups); el = U.suckDouble(DMF.reg.getuo(UO_PLOT3, 6)); cosel = U.cosd(el); @@ -229,7 +216,7 @@ private void doParseSizes() int ngood=0; for (int kray=1; kray<=nrays; kray++) { - if (RT13.bGoodRay[kray]) + if (RT13.isRayOK[kray]) { a = RT13.dGetRay(kray, asurf, aattr); b = RT13.dGetRay(kray, bsurf, battr); @@ -291,16 +278,16 @@ private void doParseSizes() //-------ARTWORK--------------- - private void addView(double x, double y, double z, int op, int which) + private void addView(double x, double y, double z, int op, int whichbase) { double xyz[] = {x, y, z}; - addView(xyz, op, which); + addView(xyz, op, whichbase); } - private void addView(double xyz[], int op, int which) + private void addView(double xyz[], int op, int whichbase) { viewelaz(xyz); - addScaled(xyz, op, which); + addScaled(xyz, op, whichbase); } @@ -315,11 +302,11 @@ private void doArt() iSymbol = SQUARE; if ("T".equals(DMF.reg.getuo(UO_PLOT3, 12))) iSymbol = DIAMOND; - whitebkg = "T".equals(DMF.reg.getuo(UO_PLOT3, 15)); - + blackbkg = "T".equals(DMF.reg.getuo(UO_PLOT3, 16)); + clearList(QBASE); - addRaw(0., 0., 0., whitebkg ? SETWHITEBKG : SETBLACKBKG, QBASE); - addRaw(0., 0., 0., SETCOLOR + (whitebkg ? BLACK : WHITE), QBASE); + addRaw(0., 0., 0., blackbkg ? SETBLACKBKG : SETWHITEBKG, QBASE); + addRaw(0., 0., 0., SETCOLOR+(blackbkg ? WHITE : BLACK), QBASE); addRaw(1., 0., 0., SETSOLIDLINE, QBASE); addRaw(0., 0., 0., COMMENTRULER, QBASE); @@ -327,20 +314,17 @@ private void doArt() drawBruler(); drawCruler(); - // jOther = getOther(ngroups); - jOther = 0; - // finally.... draw the ray hits. addRaw(1., 0., 0., SETSOLIDLINE, QBASE); addRaw(0., 0., 0., COMMENTRAY, QBASE); for (int k=1; k<=nrays; k++) - drawOneRay(k, QBASE); + drawOneRay(k); } - - private boolean drawOneRay(int kray, int which) + /* + private boolean oldDrawOneRay(int kray, int whichbase) // Called both by RandomRay and TableRay. - // Relies upon iSymbol, jOther, asurf, bsurf...set up in doArt(). + // Relies upon iSymbol, asurf, bsurf...set up in doArt(). { int jmin = ngroups; int icolor = 0; @@ -357,7 +341,7 @@ private boolean drawOneRay(int kray, int which) bStatus = (RT13.getHowfarRay(0) >= jmin); } else - bStatus = (RT13.getHowfarRay(kray) >= jmin); + bStatus = (RT13.getHowfarOK(kray) >= jmin); if (bStatus) { @@ -376,7 +360,7 @@ private boolean drawOneRay(int kray, int which) xyz[0] = (aa-amid)/aspan; // unit cube xyz[1] = (bb-bmid)/bspan; // unit cube xyz[2] = (cc-cmid)/cspan; // unit cube - addView(xyz, iSymbol+icolor, which); + addView(xyz, iSymbol+icolor, whichbase); if ((jOther > 0) && (asurf == bsurf) && (asurf == csurf)) { aa = RT13.dGetRay(kray, jOther, aattr); @@ -385,12 +369,70 @@ private boolean drawOneRay(int kray, int which) xyz[0] = (aa-amid)/aspan; // unit cube xyz[1] = (bb-bmid)/bspan; // unit cube xyz[2] = (cc-cmid)/cspan; // unit cube - addView(xyz, iSymbol+icolor, which); + addView(xyz, iSymbol+icolor, whichbase); } return true; } return false; } + */ + + + + boolean drawOneRay(int kray) + // Relies upon iSymbol, hsurf, ..setup as part of doArt(). + // Handles random rays k=0 also table rays 1<=kray<=nrays. + // A207.11 Dec 2018 with bimodals; no groups; no OtherSurface. + // Plot all that reach these two surfaces, or only OK rays? + // These are UO_PLOT3D option 13 "good" vs option 14 "all" + { + // First get a ray + boolean isGood; + int base; + if (kray==0) + { + isGood = RT13.bRunRandomRay(); + base = QBATCH; + } + else + { + isGood = RT13.isRayOK[kray]; + base = QBASE; + } + + // Now test the ray + boolean bHasEnough = RT13.getHowfarOK(kray) >= U.imax3(asurf, bsurf, csurf); + boolean bHasComplete = RT13.getHowfarOK(kray) == nsurfs; + boolean bWantEnough = DMF.reg.getuo(UO_PLOT3, 14).equals("T"); // option 14 is "Sufficient" + boolean bWantComplete = DMF.reg.getuo(UO_PLOT3, 13).equals("T"); // option 13 is "Complete" + + int icolor; + if (kray==0) + icolor = (int) RT13.raystarts[RT13.getGuideRay()][RSCOLOR]; + else + icolor = (int) RT13.raystarts[kray][RSCOLOR]; + if (blackbkg && (icolor==BLACK)) + icolor = WHITE; + + if ((bWantEnough && bHasEnough) || (bWantComplete && bHasComplete)) + { + double xyz[] = new double[3]; + double a = RT13.dGetRay(kray, asurf, aattr); + double b = RT13.dGetRay(kray, bsurf, battr); + double c = RT13.dGetRay(kray, csurf, cattr); + if (U.isNotNegZero(a) && U.isNotNegZero(b) && U.isNotNegZero(c)) + { + if (DEBUG) + System.out.println("Plot3D is loading one triplet."); + xyz[0] = (a-amid)/aspan; // unit cube + xyz[1] = (b-bmid)/bspan; // unit cube + xyz[2] = (c-cmid)/cspan; // unit cube + addView(xyz, iSymbol+icolor, base); + return true; + } + } + return false; + } private void drawAruler() diff --git a/Sources/REJIF.java b/Sources/REJIF.java index 21c8b25..da94182 100755 --- a/Sources/REJIF.java +++ b/Sources/REJIF.java @@ -8,6 +8,7 @@ /** * REJIF is a concrete ray editor class extending EJIF. + * Output is to RT13.raystarts[nrays][nattribs]; see line 194. * It supplies EJIF's abstract method parse(). * It implements Consts via EJIF. * A174: includes ray-intercept normal components {i,j,k} @@ -17,7 +18,7 @@ * * Uses EJIF for getTag(f,r) and getFieldTrim(f,r). * - * Writes to external RT13.raystarts[][][] + * Writes to external RT13.raystarts[][] * also to RT13.smins[], RT13.spans[] for random <=RX) && (op=RX) && (op 0) break; // break out of field loop to preserve location. - } //-------end of field loop------------- + } //-------end of field loop; fixupUVW() is done in RT13--------- DMF.giFlags[RSYNTAXERR] = rsyntaxerr; DMF.giFlags[RALLWAVESNUMERIC] = allWavesNumeric ? 1 : 0; DMF.giFlags[RNADJ] = iParseAdjustables(nrays); - DMF.giFlags[RNWFEGROUPS] = iParseWFEgroups(nrays); - setSminsSpans(); // needs WFEgroups, above. + setSminsSpans(); } //---------end of parse()--------------- @@ -408,6 +407,8 @@ private int iParseAdjustables(int nrays) // fills in private ArrayList of adjustables, with slaves & antislaves. // Returns how many groups were found based on rayStart tags. { + if (nrays < 1) + return 0; boolean bLookedAt[] = new boolean[nrays+1]; adjustables.clear(); for (int field=0; fieldnsurfs)) // group failure (singles are OK here) - { - stat[kray] = RRGRP; - break; - } - - jfound[kray][g] = j; - labtovx(rayseq[g-1], rayseq[g], surfs[j]); - - boolean bFront = (OTBLFRONT==surfs[j][OTYPE]) && (OTBLBACK==surfs[j+1][OTYPE]); - boolean bBack = (OTBLFRONT==surfs[j-1][OTYPE]) && (OTBLBACK==surfs[j][OTYPE]); - boolean bBimodal = bFront || bBack; - - double d = dIntercept(rayseq[g], surfs[j]); - if (d<0.0) // intercept failure: bak, mis, Dia, ... - { - stat[kray] = (int) (-d); // miss or backward - d = 0.0; - if (!bBimodal) - { - vExtend(rayseq[g]); // short dotted extension - bExtend[kray] = true; - } - else // bimodal situation: relabel, no reversing needed - { - if (stat[kray]==RRDIA) - stat[kray] = RRBO; - if (stat[kray]==RRdia) - stat[kray] = RRBI; - propagated = false; // these did not use propagation - } - } - - if ((stat[kray]==RROK) || (bBack && bFrontOK(prev))) - { - double dIndex = getRefraction(g, kray); - vPropagate(rayseq[g], d, dIndex, surfs[j]); - propagated = true; - stat[kray] = iDiams(rayseq[g], surfs[j]); - if (bBimodal && (stat[kray]==RRdia)) - stat[kray] = RRBI; - if (bBimodal && (stat[kray]==RRDIA)) - stat[kray] = RRBO; - } - - if (propagated && ((stat[kray]==RRBI) || (stat[kray]==RRBO))) // reverse - { - double dIndex = getRefraction(g, kray); - vPropagate(rayseq[g], -d, dIndex, surfs[j]); - } - - if (stat[kray]==RROK) - stat[kray] = iRedirect(rayseq, surfs[j], j, g); // TIR, whatever. - - vxtolab(rayseq[g], surfs[j]); // update all coordinates; no more motions. - - if (bBack) // approve inside and outside bypass but not TIR etc - { - if (bBypass(prev, stat[kray])) - stat[kray] = RROK; - else - stat[kray] = Math.max(prev, stat[kray]); // pick worse - } - - prev = stat[kray]; - - boolean bLoop = (stat[kray]==RROK) || (bFront && bFrontOK(stat[kray])); - if (!bLoop) // bail out of surface loop - break; - } - - if (RROK==stat[kray]) // update the ray table; but also in iBuildRays() ??? - { - for (int g=0; g<=howfar[kray]; g++) - for (int iatt=0; iatt=0.0) ? RROK : (int) (-dTrial[j]); - if (iTrial[j]==RROK) - { - vPropagate(rayseq[g], dTrial[j], 1.0, surfs[j]); - iTrial[j] = iDiams(rayseq[g], surfs[j]); - vPropagate(rayseq[g], -dTrial[j], 1.0, surfs[j]); - } - } - int jBest = -1; // absentee code - double dBest = BIGVAL; - for (int j=jstart[g]; j<=jstop[g]; j++) - if ((dTrial[j]>TOL) && (dTrial[j] ONPARMS)) // allows OTYPE etc + return -0.0; + if ((jsurf < 1) || (jsurf > MAXSURFS)) + return -0.0; + return surfs[jsurf][iatt]; } - - static public int getGroupNum(int opcode) - // Converts a given opcode into its group number. - // This handles the case of "final" by returning ngroups. + static public int getSurfNum(int opcode) + // Converts a given opcode into its surface number. + // This handles the case of "final" by returning nsurfs. // Callers should always test this result for error situation = -1! { - int ngroups = DMF.giFlags[ONGROUPS]; + int nsurfs = DMF.giFlags[ONSURFS]; if (opcode < 0) return -1; int attr = opcode % 100; if (attr > 20) // eliminate RNOTE, RBUG... return -1; - int group = opcode/100; - if (group == RFINAL/100) // handles "final" - return ngroups; - if (group > ngroups) + int surf = opcode/100; + if (surf == RFINAL/100) // handles "final" + return nsurfs; + if (surf > nsurfs) return -1; - return group; + return surf; } + static public int getAttrNum(int opcode) // Always test result for situation = -1! { @@ -549,24 +291,26 @@ static public int getAttrNum(int opcode) static public int getStatus(int kray) // Returns RROK or ray error code for "kray" + // Decode these with B4constants sResults[] array. { - return stat[kray]; + return status[kray]; } static public int getHowfarLoop(int kray) // Returns how far the *loop* went, 1...ngroups - // even though the ray may have Diametered out. + // even though the ray may have failed or terminated OK. // Use this in InOut's explanations. { - return howfar[kray]; + return howfarLoop[kray]; } - static public int getHowfarRay(int kray) - // Returns how far the *ray* went, 0....ngroups + + static public int getHowfarOK(int kray) + // Returns how far the *ray* went, 0....nsurfs + // Used by Layout for jsolid, and Plot2D Plot3D for item validation { - int ngroups = DMF.giFlags[ONGROUPS]; - return (stat[kray] == RROK) ? ngroups : howfar[kray]-1; + return howfarOK[kray]; } @@ -579,9 +323,13 @@ static public boolean getExtend(int kray) return bExtend[kray]; } + static public int getGuideRay() // Returns the number 1...nrays of ray whose color, wavel, order is in use. // Most useful for random rays, where kray=0. + // Yikes in A207 this is always zero! Must never be zero! + // Modifying it to return a random integer 1...Nrays + // MUST NEVER RETURN ZERO. { return kGuideRay; } @@ -589,7 +337,8 @@ static public int getGuideRay() static public double getRefraction(int jsurf, int gkray) // if gwave==0: Returns index approaching jsurf, using gkray @wave. - // if gwave>0: returns intex approaching jsurf, using media @gwave. + // if gwave>0: returns index approaching jsurf, using media @gwave. + // Mostly called by public iBuildRays() // Called by LayoutPanel for shading with gkray=1. // Called by redirectors, below, for Snell's law and optical path. // gO2M[] is evaluated in DMF when parsing is complete @@ -597,6 +346,7 @@ static public double getRefraction(int jsurf, int gkray) { // First: try to get refr from surfs[][] set by OEJIF. // If OK, use it; else use media LUT. + // System.out.println("-------RT13.getRefraction is starting with jsurf, gkray = "+jsurf+" "+gkray); int nsurfs = DMF.giFlags[ONSURFS]; if (jsurf<1) return 1.0; // error condition @@ -605,32 +355,59 @@ static public double getRefraction(int jsurf, int gkray) double refr = surfs[jsurf][OREFRACT]; if (Double.isNaN(refr)) { - int k = (gkray==0) ? getGuideRay() : gkray; + // System.out.println("RT13.getRefraction finds NAN at jsurf, kray = "+jsurf+" "+gkray); + int k = gkray; + if (gkray==0) + { + k = getGuideRay(); + // System.out.println("RT13.getRefraction is trying GuideRay = "+k); + } + + // int k = (gkray==0) ? getGuideRay() : gkray; if (k<1) - return 1.0; // error condition; + { + // System.out.println("RT13.getRefraction has a null ray; error, exitting."); + return 1.0; // error condition; + } int iglass = gO2M[jsurf]; + // System.out.println("RT13.getRefraction finds iglass = "+iglass); if (iglass<1) return 1.0; // error condition - int iwave = gR2M[k]; + int iwave = gR2W[k]; + // System.out.println("RT13.getRefraction finds iwave = "+iwave); if (gwave>0) // global mandate to use given iwave: MPlotPanel - iwave = gwave; + { + // System.out.println("RT13.getRefraction finds positive gwave = "+gwave); + iwave = gwave; + } if (iwave<1) - return 1.0; // error condition - return media[iglass][iwave]; + { + // System.out.println("RT13.getRefraction finds iwave < 1: error, exitting."); + return 1.0; // error condition + } + double n = media[iglass][iwave]; // media[][] was filled in by MEJIF line 100 + // System.out.printf("RT13.getRefraction using media[][], gets n = %8.4f\n", n); + return n; } + // System.out.printf("RT13.getRefraction using surfs: n = %8.4f \n", refr); if (refr == 0.0) - refr = 1.0; + { + // System.out.println("RT13.getRefraction finds zero! returning 1.0 and exitting."); + refr = 1.0; + } return refr; } static public void setEulers() + // fixes up all missing fields in optical surface definition // Generate matrix converting local to lab frame. // Use transpose to convert lab frame to local. // Sequence is tilt(x), pitch(y'), roll(z"). // Called by Auto.dNudge(), OEJIF.parse(), MPlot. // Used by RT13:: labtovx() and vxtolab()(). // M.Lampton STELLAR SOFTWARE (C) 1989, 2003 + // Enlarged to include six Hettrick implicit groove parameters, A192 March 2016 { double ct, st, cp, sp, cr, sr; for (int j=1; j<=DMF.giFlags[ONSURFS]; j++) @@ -651,6 +428,300 @@ static public void setEulers() surfs[j][OE32] = sr*sp*ct + cr*st; // Z <- y; M32 surfs[j][OE33] = cp*ct; // Z <- z; M33 } + + //---Hettrick implicit polynomial coefficients A192; A193--------- + for (int j=1; j 0) - // One or more absentees; fix up lastAbsentAttrib. - // Since absentees are -0.0, no need to skip their summation. - // Normalize later; also handles null vector case. + double span = 1.0 - U.cosd(dIsoRadius); + switch(iUserOptionMethod) { - double sign = bUserOptionPositive ? 1.0 : -1.0; - double sumsq = 0.0; - for (int i=RU; i<=RW; i++) - sumsq += rayseq[0][i]*rayseq[0][i]; - if (sumsq <= 1.0) - rayseq[0][lastAbsentAttrib] = sign*Math.sqrt(1-sumsq); + case 0: // volume + break; + case 1: // isotropic U0 + { + double s = span * Math.random(); + double p = U.TWOPI * Math.random(); + double q = bUserOptionPositive ? 1-s : s-1; + double r = Math.sqrt(1.0 - q*q); + raystarts[0][RU] = q; + raystarts[0][RV] = r * Math.cos(p); + raystarts[0][RW] = r * Math.sin(p); + } + break; + case 2: // isotropic V0 + { + double s = span * Math.random(); + double p = U.TWOPI * Math.random(); + double q = bUserOptionPositive ? 1-s : s-1; + double r = Math.sqrt(1.0 - q*q); + raystarts[0][RV] = q; + raystarts[0][RU] = r * Math.cos(p); + raystarts[0][RW] = r * Math.sin(p); + } + break; + case 3: // isotropic W0 + { + double s = span * Math.random(); + double p = U.TWOPI * Math.random(); + double q = bUserOptionPositive ? 1-s : s-1; + double r = Math.sqrt(1.0 - q*q); + raystarts[0][RW] = q; + raystarts[0][RU] = r * Math.cos(p); + raystarts[0][RV] = r * Math.sin(p); + } + break; } + fixupLabUVW(0); + // System.out.printf("RT13.iCreateRandomRay() using smins[RU] = %8.4f \n", smins[RU]); + // System.out.printf("RT13.iCreateRandomRay() using spans[RU] = %8.4f \n", spans[RU]); + // System.out.printf("RT13.iCreateRandomRay() has generated U0 = %8.4f \n", raystarts[0][RU]); + // System.out.printf("RT13.iCreateRandomRay() has generated V0 = %8.4f \n", raystarts[0][RV]); + // System.out.printf("RT13.iCreateRandomRay() has generated W0 = %8.4f \n", raystarts[0][RW]); + return krand; + } - normalizeLab(rayseq[0]); // normalizes, repairs null vector. - for (int i=RX; i<=RW; i++) - if (-0.0==rayseq[0][i]) - rayseq[0][i] = 0.0; // clean up any remaining -0.0 cases. - return kray; - } static private double getRand(int which, double dConcen) // returns 0= 0.0) + vPropagate(kray, jsurf, d); + else + code = (int) Math.round(-d); // RRMIS=1, RRBAK=2, RRBRA=3 + // System.out.println("intercept is returning " + sResults[code]); + return code; + } + static private double dIntercept(double ray[], double surf[]) - // This does not move the ray. Instead, if OK, recommends d>=0; + // Mathematical surface intercept test does not test Diameters. + // Returns d>0 if an intercept can be identified.. // RAY length = ZERO is VALID for plane surfaces; (exactly zero? slightly negative?) // RAY length = ZERO is INVALID for curved surfaces. - // vPropagate() is called later if decision after Diams = GO. + // vPropagate() is called later if decision after result = RROK // M.Lampton STELLAR SOFTWARE (C) 1989, 2003 - // Return values: RROK, -RRMIS, -RRBAK, -RRDIA, -RRSPI, etc + // Return values: RROK, -RRMIS, -RRBAK, -RRBRA. { int iType = U.getInt(surf[OTYPE]); double dpro = surf[OPROFILE]; int profile = U.getInt(dpro); - + boolean rayok = isNormalizedVx(ray); boolean bArray = ((iType==OTLENSARRAY) || (iType==OTMIRRARRAY)); // irisarray? double d = 0.0; if (iType == OTIRISARRAY) @@ -1217,8 +1268,11 @@ else switch(profile) case OSPOLYREV: case OSZERNREV: case OSZERNTOR: - case OSBICONIC: d = dNumSolve(ray, surf); + case OSBICONIC: + case OSGAUSS: d = dNumSolve(ray, surf); break; + default: System.out.println("RT13.dIntercept() has unknown profile = "+profile); + } if (Math.abs(d) < TOL) d = 0.0; @@ -1232,6 +1286,10 @@ static private double dPlaneSolve(double ray[], double surf[]) // ZERO=VALID is OK here. // M.Lampton STELLAR SOFTWARE (C) 1989, 2003, 2005, 2010 { + // System.out.printf(" RT13.dPlaneSolve() starting with RTWL = %12.6f \n", ray[RTWL]); + boolean rayOK = isNormalizedVx(ray); + if (!rayOK) + System.out.println(" RT13.dPlaneSolve() has an UNNORMALIZED ray."); if (Math.abs(ray[RTWL]) < TOL) return -RRMIS; // negative code double d = -ray[RTZL] / ray[RTWL]; @@ -1256,6 +1314,8 @@ static private double dQuadSolve(double arrayox, double arrayoy, // M.Lampton STELLAR SOFTWARE (C) 1989, 2003, 2007, 2012 // Returns error codes -RRMIS, -RRBAK, -RRDIA, -RRSPI, ... { + // System.out.println("Starting dQuadSolve()."); + boolean rayok = isNormalizedVx(ray); double c, s, x, y, z, u, v, w, d; double[] dd = new double[2]; double abc[] = new double[3]; @@ -1314,12 +1374,15 @@ static private double dQuadSolve(double arrayox, double arrayoy, //-------get positive roots and test them------------- int nroots = iGetPosRoots(abc, dd); - + + // System.out.println("dQuadSolve nroots = "+nroots); + double cz0 = c*(z+w*dd[0]); // vxframe departure from plano double cz1 = c*(z+w*dd[1]); // vxframe departure from plano boolean E0 = s*cz0 < 1.0; // existence check boolean E1 = s*cz1 < 1.0; // existence check + // System.out.printf("dQuadSolve cx0, cz1 = %6.3f %6.3f \n", cz0, cz1); switch (nroots) { case -1: // no real roots whatsoever @@ -1344,8 +1407,8 @@ static private double dQuadSolve(double arrayox, double arrayoy, //----both roots exist; test Diameters---------- - int D0 = testDiameter(dd[0], ray, surf); // RROK=0 or RRDIA, RRSPI, ... - int D1 = testDiameter(dd[1], ray, surf); // RROK=0 or RRDIA, RRSPI, ... + int D0 = testDiameter(dd[0], ray, surf); + int D1 = testDiameter(dd[1], ray, surf); if ((D0==RROK) && (D1!=RROK)) // one good intercept return dd[0]; @@ -1426,11 +1489,9 @@ static private double dArrayQuadSolve(double ray[], double surf[]) return dBest; } - - static private double dNumSolve(double ray[], double surf[]) // Returns propagation length if OK, else -1.0. - // Relies upon Z.vGetZsurf() for the surface model. + // Relies upon Z.dGetZsurf() for the surface model. // How to manage HINT for best efficiency? // M.Lampton STELLAR SOFTWARE (C) 1989, 2003, 2005 // Error: -RRBAK @@ -1444,8 +1505,6 @@ static private double dNumSolve(double ray[], double surf[]) return -RRBAK; // bracket fail is usually due to backward ray } - - private static boolean bBracket(double d[], double r[], double s[]) { int MAXIT1 = 10; // allowed initial iterations for d[0] @@ -1497,11 +1556,10 @@ static private double getHint(double ray[]) } - private static int iBrent(double t[], double ray[], double surf[]) // Given a bracket (t[0], t[1]), Brent() sets t[0] to root, // and returns the number of calls to zDiff() taken. - // Relies upon Z.vGetZsurf() for the surface model. + // Relies upon Z.dGetZsurf() for the surface model. // Press et al NUMERICAL RECIPES IN C 2nd edition 1992 p.361 // R.P.Brent ALGORITHMS... Prentice-Hall, NJ 1973. { @@ -1588,7 +1646,7 @@ private static int iBrent(double t[], double ray[], double surf[]) static private double zDiff(double d, double ray[], double surf[]) // This is the engine that is called by bBracket() and iBrent(). // Returns the z-component of discrepancy ray-surface. - // Relies upon Z.vGetZsurf() for the surface model. + // Relies upon Z.dGetZsurf() for the surface model. { double xyz[] = new double[3]; xyz[0] = ray[RTXL] + ray[RTUL]*d; @@ -1599,17 +1657,28 @@ static private double zDiff(double d, double ray[], double surf[]) - /*--------------------Diameters and iris-------------------*/ - /*--------------------Diameters and iris-------------------*/ - /*--------------------Diameters and iris-------------------*/ + + + + + /*--------------------Diameters-------------------*/ + /*--------------------Diameters-------------------*/ + /*---A207 eliminating special code for iris-------*/ + + + static private int validate(int kray, int jsurf) + { + int code = iDiams(dRays[kray][jsurf], surfs[jsurf]); + // System.out.println("Validate is returning " + sResults[code]); + return code; + } + static private int iDiams(double ray[], double surf[]) // Returns RROK if ok, else a positive failure code RRDIA, RRiri, etc. // M.Lampton STELLAR SOFTWARE (C) 1989, 2003, 2013 { - boolean bIris = (OTIRIS == surf[OTYPE]); - boolean bIRect = ((OFIRECT==surf[OFORM]) || (OFBRECT==surf[OFORM])); boolean bORect = ((OFORECT==surf[OFORM]) || (OFBRECT==surf[OFORM])); @@ -1632,7 +1701,7 @@ static private int iDiams(double ray[], double surf[]) boolean bhole = bIRect ? Math.max(sx,sy)<1.0 : sx+sy<1.0; if (bhole) - return bIris ? RRiri : RRdia; + return RRdia; } //-----do the outer edge-------- @@ -1652,7 +1721,7 @@ static private int iDiams(double ray[], double surf[]) boolean bedge = bORect ? Math.max(sx,sy)>1.0 : sx+sy>1.0; if (bedge) - return bIris ? RRIRI : RRDIA; + return RRDIA; } // Now do the spider legs in X,Y plane @@ -1680,14 +1749,12 @@ static private int iDiams(double ray[], double surf[]) return RROK; } - - static private int iIrisArray(double ray[], double surf[]) // Returns RROK or RRIRI or RRDIA. // Model: infinite plane barrier with holes. // ** Within Rinner, ray passes with RROK; // ** Beyond Router, ray dies with RRDIA; - // ** In between, ray dies with RRiri. + // ** In between, ray dies with RRdia // M.Lampton STELLAR SOFTWARE (C) 2007 { boolean bIRect = ((OFIRECT==surf[OFORM]) || (OFBRECT==surf[OFORM])); @@ -1727,9 +1794,9 @@ static private int iIrisArray(double ray[], double surf[]) double sy = 4 * y*y/(diay*diay); // if either is too big, we hit the mask: if (bIRect && (Math.max(sx, sy) > 1.0)) - return RRiri; + return RRdia; if (!bIRect && (sx + sy > 1.0)) - return RRiri; + return RRdia; } return RROK; } @@ -1741,17 +1808,21 @@ static private int iIrisArray(double ray[], double surf[]) - - - - - /*-------------------------redirectors----------------------*/ /*-------------------------redirectors----------------------*/ /*-------------------------redirectors----------------------*/ + + static private int redirect(int kray, int jsurf) + // attempts to redirect a ray segment; returns RROK or error code + { + // System.out.println("RT13.redirect() is given kray, jsurf = "+kray+" "+jsurf); + int code = iRedirect(dRays[kray], surfs[jsurf], jsurf); + // System.out.println("RT13.redirect is returning " + sResults[code]); + return code; + } - static private int iRedirect(double rayseq[][], double surf[], int j, int g) + static private int iRedirect(double rayseq[][], double surf[], int j) // M.Lampton STELLAR SOFTWARE (C) 2013 // // Modifies the local-frame u,v,w to redirect this ray. @@ -1761,38 +1832,44 @@ static private int iRedirect(double rayseq[][], double surf[], int j, int g) // Receives status from preceding Diam() check. // Returns RROK, RRUNK, RRORD, RRTIR. { - vSetAngle(rayseq[g], surf); // sets incoming RTANGLE fields before modifying ray direction + vSetAngle(rayseq[j], surf); // sets incoming RTANGLE fields before modifying ray direction boolean bGroovy = surf[OGROOVY] != 0.0; int surftype = (int) surf[OTYPE]; switch(surftype) { case OTBLFRONT: // successful refraction at bimodal lens case OTBLBACK: - return iTG(rayseq[g], surf, j); + return iTG(rayseq[j], surf, j); + case OTBMIRROR: + return iMirror(rayseq[j], surf); case OTDISTORT: return RROK; case OTIRIS: case OTIRISARRAY: return RROK; // no redirection needed. case OTRETRO: - return iRetro(rayseq[g], surf); + return iRetro(rayseq[j], surf); case OTMIRROR: case OTMIRRARRAY: if (bGroovy) - return iRgrating(rayseq[g], surf); + return iRgrating(rayseq[j], surf); else - return iMirror(rayseq[g], surf); + return iMirror(rayseq[j], surf); case OTLENS: case OTLENSARRAY: - return iTG(rayseq[g], surf, j); - case OTSCATTER: - return iScatter(rayseq[g], surf); - case OTCBIN: // CoordBreak input surface - return iCBIN(rayseq, surf, g); // copy previous local uvw - case OTCBOUT: // CoordBreak output surface - return iCBOUT(rayseq, surf, g); // copy previous local xyzuvw + return iTG(rayseq[j], surf, j); + case OTGSCATTER: + return iGScatter(rayseq[j], surf); // A195 + case OTUSCATTER: + return iUScatter(rayseq[j], surf); // A195 + case OTCBIN: // CoordBreak input surface + return iCBIN(rayseq, surf, j); // copy previous local uvw + case OTCBOUT: // CoordBreak output surface + return iCBOUT(rayseq, surf, j); // copy previous local xyzuvw + case OTTERMINATE: // ray killer MUST BECOME BIMODAL + return RRTER; } - return RRNON; + return RRUNK; } @@ -1878,6 +1955,7 @@ static private int iSnell(double ray[], double surf[], int jsurf) double numer, denom, mu, ax, ay, az, bx, by, bz, b2, gamma, dotin; int kray = getGuideRay(); + System.out.println("iSnell called getGuideRay() and has got " + kray); numer = getRefraction(jsurf, kray); denom = getRefraction(jsurf+1, kray); @@ -1917,14 +1995,58 @@ static private int iSnell(double ray[], double surf[], int jsurf) } + static private void getG(double ray[], double surf[], double G[]) + // evaluates local groove density. Returns G[0]=gx, G[1]=gy. + { + double x = ray[RTXL]; + double x2 = x*x; + double x3 = x2*x; + double x4 = x2*x2; + double y = ray[RTYL]; + double y2 = y*y; + double y3 = y2*y; + double y4 = y2*y2; + + double gx = surf[OGX] + x*surf[OVX10] + x2*surf[OVX20] + x3*surf[OVX30] + x4*surf[OVX40] + + y*surf[OVX01] + y2*surf[OVX02] + y3*surf[OVX03] + y4*surf[OVX04] + + x*y*surf[OVX11] + x*y2*surf[OVX12] +x*y3*surf[OVX13] + + x2*y*surf[OVX21] + x2*y2*surf[OVX22] + x3*y*surf[OVX31]; + + double gy = surf[OGY] + x*surf[OVY10] + x2*surf[OVY20] + x3*surf[OVY30] + x4*surf[OVY40] + + y*surf[OVY01] + y2*surf[OVY02] + y3*surf[OVY03] + y4*surf[OVY04] + + x*y*surf[OVY11] + x*y2*surf[OVY12] + x*y3*surf[OVY13] + + x2*y*surf[OVY21] + x2*y2*surf[OVY22] + x3*y*surf[OVY31]; + + if (Math.abs(surf[OHOELAM]) > TOL) // add HOE terms..... + { + double d1 = Math.sqrt( U.sqr(ray[RTXL] - surf[OHOEX1]) + + U.sqr(ray[RTYL] - surf[OHOEY1]) + + U.sqr(ray[RTZL] - surf[OHOEZ1])); + + double d2 = Math.sqrt( U.sqr(ray[RTXL] - surf[OHOEX2]) + + U.sqr(ray[RTYL] - surf[OHOEY2]) + + U.sqr(ray[RTZL] - surf[OHOEZ2])); + + if ((d1 > TOL) && (d2 > TOL)) + { + double a1 = 1.0 / (d1*surf[OHOELAM]); // virtual HOE if <0 + double a2 = 1.0 / (d2*surf[OHOELAM]); + gx += a1*(ray[RTXL]-surf[OHOEX1])-a2*(ray[RTXL]-surf[OHOEX2]); + gy += a1*(ray[RTYL]-surf[OHOEY1])-a2*(ray[RTYL]-surf[OHOEY2]); + } + } + G[0] = gx; + G[1] = gy; + } + static private int iTG(double ray[], double surf[], int jsurf) - // Transmission grating solver: refraction and diffraction combined. + // Plane Transmission grating solver: refraction and diffraction combined. // Must have numerical wavelength not literal if using diffraction. // // Could replace iSnell() ! // - // Has VPHs but excludes HOEs. - // M.Lampton STELLAR SOFTWARE (C) 2015 rev A186 + // Has VPHs and HOEs. + // M.Lampton STELLAR SOFTWARE (C) 2015 rev A186, A194 // Spencer & Murty JOSA 52#6 672 (1962) eqn 49, three terms in local frame // Refraction of incoming ray S... // S' = (n2/n1)*S @@ -1963,51 +2085,21 @@ static private int iTG(double ray[], double surf[], int jsurf) // Get order from raystart, or if absent, from the optic table. double order = surf[OORDER]; double rayorder = raystarts[kray][RSORDER]; - if (!U.isNegZero(rayorder)) + if (U.isNotNegZero(rayorder)) order = rayorder; if (order != 0) // diffractive? { double wavel = raystarts[kray][RSWAVEL]; if (Double.isNaN(wavel)) return RRUNK; + double waveorder = wavel*order; - - double gx = surf[OGX]; // density in vertex frame - double gy = surf[OGY]; // density in vertex frame - - if (waveorder != 0.) // and wavy? + + if (waveorder != 0.) // If it is wavy... { - if (Math.abs(gx) > TOL) // add VLS in vertex frame... - gx += ray[RTXL] * (surf[OVLS1] - + ray[RTXL] * (surf[OVLS2] - + ray[RTXL] * (surf[OVLS3] - + ray[RTXL] * surf[OVLS4]))); - else if (Math.abs(gy) > TOL) - gy += ray[RTYL] * (surf[OVLS1] - + ray[RTYL] * (surf[OVLS2] - + ray[RTYL] * (surf[OVLS3] - + ray[RTYL] * surf[OVLS4]))); - - if (Math.abs(surf[OHOELAM]) > TOL) // add HOE terms..... - { - double d1 = Math.sqrt( U.sqr(ray[RTXL] - surf[OHOEX1]) - + U.sqr(ray[RTYL] - surf[OHOEY1]) - + U.sqr(ray[RTZL] - surf[OHOEZ1])); - - double d2 = Math.sqrt( U.sqr(ray[RTXL] - surf[OHOEX2]) - + U.sqr(ray[RTYL] - surf[OHOEY2]) - + U.sqr(ray[RTZL] - surf[OHOEZ2])); - - if ((d1 > TOL) && (d2 > TOL)) - { - double a1 = 1.0 / (d1*surf[OHOELAM]); // virtual HOE if <0 - double a2 = 1.0 / (d2*surf[OHOELAM]); - gx += a1*(ray[RTXL]-surf[OHOEX1])-a2*(ray[RTXL]-surf[OHOEX2]); - gy += a1*(ray[RTYL]-surf[OHOEY1])-a2*(ray[RTYL]-surf[OHOEY2]); - } - } - - Triple Grating = new Triple(gx, gy, 0.); // in vertex frame + double G[] = new double[2]; + getG(ray, surf, G); + Triple Grating = new Triple(G[0], G[1], 0.); // in vertex frame Triple Diffract = Triple.getPerp(Grating, Unorm); // in vertex frame double coef = waveorder/denom; // scaling factor Grating = Triple.getProduct(Grating, coef); // in vertex frame @@ -2039,12 +2131,18 @@ else if (Math.abs(gy) > TOL) - static private int iScatter(double ray[], double surf[]) + static private int iGScatter(double ray[], double surf[]) + // A196: scatter is with respect to local normal not incoming ray direction { - double radians = (Math.PI/180.0) * surf[OSCATTER]; - ray[RTUL] += radians * U.grand(); - ray[RTVL] += radians * U.grand(); - ray[RTWL] += radians * U.grand(); + double[] Norm = new double[RNATTRIBS]; + vGetPerp(ray, surf, Norm); + double radians = (Math.PI/180.0) * surf[OSCATTER]; // get the Gaussian scatter angle + // ray[RTUL] += radians * U.grand(); // add to previous ray direction + // ray[RTVL] += radians * U.grand(); // add to previous ray direction + // ray[RTWL] += radians * U.grand(); // add to previous ray direction + ray[RTUL] = Norm[RTUL] + radians * U.grand(); // deviate from local normal + ray[RTVL] = Norm[RTVL] + radians * U.grand(); // deviate from local normal + ray[RTWL] = 1.; double sum = U.sqr(ray[RTUL]) + U.sqr(ray[RTVL]) + U.sqr(ray[RTWL]); sum = Math.sqrt(sum); ray[RTUL] /= sum; @@ -2053,6 +2151,25 @@ static private int iScatter(double ray[], double surf[]) return RROK; } + static private int iUScatter(double ray[], double surf[]) // A195 uniform scatter + // A196: scatter is with respect to local normal not vertex normal + { + double[] Norm = new double[RNATTRIBS]; + vGetPerp(ray, surf, Norm); + double azimuth = 2*Math.PI * Math.random(); + double maxdeg = Math.max(0., Math.min(89.99, surf[OSCATTER])); + double maxradians = (Math.PI/180.)* maxdeg; + double radius = Math.sqrt(Math.random())*maxradians; + ray[RTUL] = Norm[RTUL] + radius*Math.cos(azimuth); + ray[RTVL] = Norm[RTVL] + radius*Math.sin(azimuth); + ray[RTWL] = 1.; + double sum = U.sqr(ray[RTUL]) + U.sqr(ray[RTVL]) + U.sqr(ray[RTWL]); + sum = Math.sqrt(sum); + ray[RTUL] /= sum; + ray[RTVL] /= sum; + ray[RTWL] /= sum; + return RROK; + } static private int iRgrating(double ray[], double surf[]) { @@ -2072,7 +2189,7 @@ static private int iGrating(double ray[], double surf[], boolean bRefl) // and wave frequency match sets.... // |Ke| = |Ki|*v1/v2 = |Ki|*n2/n1. // - // May 2013: better is to include S&M's refraction. Unit ray directions S1, S2: + // May 2013: better is to include Spencer & Murty's refraction. Unit ray directions S1, S2: // S2 x Normal = (n1/n2)* S1 x Normal + M*G*lambda**Q/n2 // where Q is the unit vector parallel to local rulings. // Sept 2015 A186 doing this implementation @@ -2094,7 +2211,7 @@ static private int iGrating(double ray[], double surf[], boolean bRefl) // classical gratings, except the local groove frequency vector gx gy gz // is computed from grad(PathDifference)/HOELambda, using the fact that // when the path difference is an integer number of lambda we have local - // constructive interference and a groove, but when it is a fraction + // constructive interference and a groove, but when it is half // of a wavelength we have destructive interference and no groove. // M.Lampton STELLAR SOFTWARE (C) 1989, 2003 { @@ -2113,51 +2230,21 @@ static private int iGrating(double ray[], double surf[], boolean bRefl) // or if absent, from the optic table. double order = surf[OORDER]; double rayorder = raystarts[kray][RSORDER]; - if (!U.isNegZero(rayorder)) + if (U.isNotNegZero(rayorder)) order = rayorder; - if (wavel*order == 0.0) + double waveorder = wavel*order; + if (waveorder == 0.0) { if (bRefl) return iMirror(ray, surf); else return RROK; } - - gx = surf[OGX]; - gy = surf[OGY]; - - if (Math.abs(gx) > TOL) // add VLS terms.... - gx += ray[RTXL] * (surf[OVLS1] - + ray[RTXL] * (surf[OVLS2] - + ray[RTXL] * (surf[OVLS3] - + ray[RTXL] * surf[OVLS4]))); - else if (Math.abs(gy) > TOL) - gy += ray[RTYL] * (surf[OVLS1] - + ray[RTYL] * (surf[OVLS2] - + ray[RTYL] * (surf[OVLS3] - + ray[RTYL] * surf[OVLS4]))); - - if (Math.abs(surf[OHOELAM]) > TOL) // add HOE terms..... - { - d1 = Math.sqrt( U.sqr(ray[RTXL] - surf[OHOEX1]) - + U.sqr(ray[RTYL] - surf[OHOEY1]) - + U.sqr(ray[RTZL] - surf[OHOEZ1])); - - d2 = Math.sqrt( U.sqr(ray[RTXL] - surf[OHOEX2]) - + U.sqr(ray[RTYL] - surf[OHOEY2]) - + U.sqr(ray[RTZL] - surf[OHOEZ2])); - - if ((d1 > TOL) && (d2 > TOL)) - { - a1 = 1.0 / (d1*surf[OHOELAM]); // virtual HOE if <0 - a2 = 1.0 / (d2*surf[OHOELAM]); - gx += a1*(ray[RTXL]-surf[OHOEX1])-a2*(ray[RTXL]-surf[OHOEX2]); - gy += a1*(ray[RTYL]-surf[OHOEY1])-a2*(ray[RTYL]-surf[OHOEY2]); - // gz += a1*(ray[RTZL]-surf[OHOEZ1])-a2*(ray[RTZL]-surf[OHOEZ2]); - } - } + double G[] = new double[2]; // groove density in x,y + getG(ray, surf, G); + // Get the unit groove vector Q in vertex coords. // Method: Q = Norm cross G // Caution: Q must be a unit vector, even if G is zero, because it will @@ -2168,9 +2255,9 @@ else if (Math.abs(gy) > TOL) double[] Norm = new double[13]; vGetPerp(ray, surf, Norm); - qx = -Norm[RTWL] * gy; - qy = Norm[RTWL] * gx; - qz = Norm[RTUL] * gy - Norm[RTVL] * gx; + qx = -Norm[RTWL] * G[1]; + qy = Norm[RTWL] * G[0]; + qz = Norm[RTUL] * G[1] - Norm[RTVL] * G[0]; // normalize these qq = U.sqr(qx) + U.sqr(qy) + U.sqr(qz); @@ -2184,9 +2271,9 @@ else if (Math.abs(gy) > TOL) else // g=0, nothing to diffract { if (bRefl) - return iMirror(ray, surf); + return iMirror(ray, surf); // reflect without diffracting else - return RROK; + return RROK; // transmit unchanged } // Get the local groove perpendicular P in vertex coordinates @@ -2199,7 +2286,7 @@ else if (Math.abs(gy) > TOL) sp = px*ray[RTUL] + py*ray[RTVL] + pz*ray[RTWL]; // incident dot grooveperp sq = qx*ray[RTUL] + qy*ray[RTVL] + qz*ray[RTWL]; // incident dot groove - sr = Norm[RTUL]*ray[RTUL] + Norm[RTVL]*ray[RTVL] + Norm[RTWL]*ray[RTWL]; // inc dot normal + sr = Norm[RTUL]*ray[RTUL] + Norm[RTVL]*ray[RTVL] + Norm[RTWL]*ray[RTWL]; // incident dot normal double posdot = (sr >= 0.0) ? 1.0 : -1.0; // Diffract the ray in local grating coordinates @@ -2228,7 +2315,7 @@ else if (Math.abs(gy) > TOL) /*-------------vGetPerp finds the perp for any surface------------*/ - /*---------------it always calls Z.vGetZnorm()--------------------*/ + /*---------------it always calls Z.vGetNormal()--------------------*/ static private void vGetPerp(double ray[], double surf[], double p[]) // ray[13]; surf[121]; perp[13] is in local frame RTUL, RTVL, RTWL. @@ -2236,7 +2323,7 @@ static private void vGetPerp(double ray[], double surf[], double p[]) // Then, converts perp "q" from 3-Dim to 13-dim space for RT13. { double q[] = new double[3]; - Z.vGetZnorm(ray[RTXL], ray[RTYL], surf, q); + Z.vGetNormal(ray[RTXL], ray[RTYL], surf, q); p[RTUL] = q[0]; p[RTVL] = q[1]; p[RTWL] = q[2]; // USUALLY NEGATIVE. WHY? @@ -2245,58 +2332,179 @@ static private void vGetPerp(double ray[], double surf[], double p[]) - /*-----------------some math utilities--------------------*/ - /*-----------------some math utilities--------------------*/ - /*-----------------some math utilities--------------------*/ + /*-----------------some coordinate changing utilities--------------------*/ + /*-----------------some coordinate changing utilities--------------------*/ + /*-----------------some coordinate changing utilities--------------------*/ - - static private void labtovx(double rprev[], double rthis[], double surf[]) - // Coordinate frame changer, also moves from surf=j to j+1. - // Matrix OE converts local to lab coordinates; must transpose it here. - // Also carries RPATH forward from rprev[] to rthis[]. + + static private void labtovx(int k, int jprev, int j) + // Coordinate frame changer from lab jprev to vertex frame j. + // Matrix OE converts local to lab coordinates; so use its transpose here. + // Also carries RPATH forward from rprev[] to rthis[] ?? // M.Lampton STELLAR SOFTWARE (C) 1989, 2003 { - double a, b, c; - a = rprev[RX] - surf[OX]; - b = rprev[RY] - surf[OY]; - c = rprev[RZ] - surf[OZ]; - rthis[RTXL] = surf[OE11]*a + surf[OE21]*b + surf[OE31]*c; - rthis[RTYL] = surf[OE12]*a + surf[OE22]*b + surf[OE32]*c; - rthis[RTZL] = surf[OE13]*a + surf[OE23]*b + surf[OE33]*c; - a = rprev[RU]; - b = rprev[RV]; - c = rprev[RW]; - rthis[RTUL] = surf[OE11]*a + surf[OE21]*b + surf[OE31]*c; - rthis[RTVL] = surf[OE12]*a + surf[OE22]*b + surf[OE32]*c; - rthis[RTWL] = surf[OE13]*a + surf[OE23]*b + surf[OE33]*c; - rthis[RPATH] = rprev[RPATH]; + double x, y, z, dx, dy, dz, u, v, w; + boolean rayok = isNormalizedLab(dRays[k][jprev]); + if (!rayok) + { + System.out.println("labtovx() starting with BAAD LAB NORMALIZATION; k, jprev, j= "+k+" "+jprev+" "+j); + System.out.println("....norm error = "+getNormErrorLab(dRays[k][jprev])); + } + + x = dRays[k][jprev][RX]; + y = dRays[k][jprev][RY]; + z = dRays[k][jprev][RZ]; + u = dRays[k][jprev][RU]; + v = dRays[k][jprev][RV]; + w = dRays[k][jprev][RW]; + // System.out.printf("labtovx input x,y,z,u,v,w = %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f \n", x,y,z,u,v,w); + + dx = dRays[k][jprev][RX] - surfs[j][OX]; + dy = dRays[k][jprev][RY] - surfs[j][OY]; + dz = dRays[k][jprev][RZ] - surfs[j][OZ]; + + dRays[k][j][RTXL] = surfs[j][OE11]*dx + surfs[j][OE21]*dy + surfs[j][OE31]*dz; + dRays[k][j][RTYL] = surfs[j][OE12]*dx + surfs[j][OE22]*dy + surfs[j][OE32]*dz; + dRays[k][j][RTZL] = surfs[j][OE13]*dx + surfs[j][OE23]*dy + surfs[j][OE33]*dz; + + dRays[k][j][RTUL] = surfs[j][OE11]*u + surfs[j][OE21]*v + surfs[j][OE31]*w; + dRays[k][j][RTVL] = surfs[j][OE12]*u + surfs[j][OE22]*v + surfs[j][OE32]*w; + dRays[k][j][RTWL] = surfs[j][OE13]*u + surfs[j][OE23]*v + surfs[j][OE33]*w; + dRays[k][j][RPATH] = dRays[k][jprev][RPATH]; + + x = dRays[k][j][RTXL]; + y = dRays[k][j][RTYL]; + z = dRays[k][j][RTZL]; + u = dRays[k][j][RTUL]; + v = dRays[k][j][RTVL]; + w = dRays[k][j][RTWL]; + // System.out.printf("labtovx output x,y,z,u,v,w = %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f \n", x,y,z,u,v,w); } - static private void vxtolab(double ray[], double surf[]) - // Coordinate frame changer, single surface. + + static private void vxtolab(int k, int j) + // Coordinate frame changer, ray="k", single surface "j". // Here the OE matrix is used directly, local to lab conversion. // Converts a vertex-frame ray descriptor to lab frame. // M.Lampton STELLAR SOFTWARE (C) 1989, 2003 { - double a = ray[RTUL]; - double b = ray[RTVL]; - double c = ray[RTWL]; - ray[RU] = surf[OE11]*a + surf[OE12]*b + surf[OE13]*c; - ray[RV] = surf[OE21]*a + surf[OE22]*b + surf[OE23]*c; - ray[RW] = surf[OE31]*a + surf[OE32]*b + surf[OE33]*c; - a = ray[RTXL]; - b = ray[RTYL]; - c = ray[RTZL]; - ray[RX] = surf[OE11]*a + surf[OE12]*b + surf[OE13]*c; - ray[RY] = surf[OE21]*a + surf[OE22]*b + surf[OE23]*c; - ray[RZ] = surf[OE31]*a + surf[OE32]*b + surf[OE33]*c; - ray[RX] += surf[OX]; - ray[RY] += surf[OY]; - ray[RZ] += surf[OZ]; + double x, y, z, u, v, w; + + boolean rayok = isNormalizedVx(dRays[k][j]); + if (!rayok) + { + System.out.println("vxtolab() starting with BAAD LAB NORMALIZATION; k, j= "+k+" "+j); + System.out.println("....norm error = "+getNormErrorVx(dRays[k][j])); + } + // System.out.println("vxtolab() being called; surf[OZ] = "+surf[OZ]); + + x = dRays[k][j][RTXL]; + y = dRays[k][j][RTYL]; + z = dRays[k][j][RTZL]; + u = dRays[k][j][RTUL]; + v = dRays[k][j][RTVL]; + w = dRays[k][j][RTWL]; + // System.out.printf("vxtolab input x,y,z,u,v,w = %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f \n", x,y,z,u,v,w); + + dRays[k][j][RU] = surfs[j][OE11]*u + surfs[j][OE12]*v + surfs[j][OE13]*w; + dRays[k][j][RV] = surfs[j][OE21]*u + surfs[j][OE22]*v + surfs[j][OE23]*w; + dRays[k][j][RW] = surfs[j][OE31]*u + surfs[j][OE32]*v + surfs[j][OE33]*w; + + dRays[k][j][RX] = surfs[j][OE11]*x + surfs[j][OE12]*y + surfs[j][OE13]*z; + dRays[k][j][RY] = surfs[j][OE21]*x + surfs[j][OE22]*y + surfs[j][OE23]*z; + dRays[k][j][RZ] = surfs[j][OE31]*x + surfs[j][OE32]*y + surfs[j][OE33]*z; + + x = dRays[k][j][RX] += surfs[j][OX]; + y = dRays[k][j][RY] += surfs[j][OY]; + z = dRays[k][j][RZ] += surfs[j][OZ]; + u = dRays[k][j][RU]; + v = dRays[k][j][RV]; + w = dRays[k][j][RW]; + // System.out.printf("vxtolab output x,y,z,u,v,w = %8.4f %8.4f %8.4f %8.4f %8.4f %8.4f \n", x,y,z,u,v,w); + rayok = isNormalizedLab(dRays[k][j]); + if (!rayok) + { + System.out.println("vxtolab() exitting with BAAD LAB NORMALIZATION; k, j = "+k+" "+j); + System.out.println("....norm error = "+getNormErrorLab(dRays[k][j])); + } + } + + + static private void clobberUVW(int k, int j) + // used only to zero out failed redirections to blank InOut and graphic data points. + // Assumes that InOut, Plot2D and Plot3D skip minus zero data! + { + dRays[k][j][RTUL] = -0.0; + dRays[k][j][RTVL] = -0.0; + dRays[k][j][RTWL] = +1.0; + dRays[k][j][RU] = -0.0; + dRays[k][j][RV] = -0.0; + dRays[k][j][RW] = +1.0; + } + + static private void clobberAll(int k, int j) + // clears out a skipped ray surface combo. + { + dRays[k][j][RTXL] = -0.0; + dRays[k][j][RTYL] = -0.0; + dRays[k][j][RTZL] = -0.0; + dRays[k][j][RX] = -0.0; + dRays[k][j][RY] = -0.0; + dRays[k][j][RZ] = -0.0; + dRays[k][j][RTUL] = -0.0; + dRays[k][j][RTVL] = -0.0; + dRays[k][j][RTWL] = -0.0; + dRays[k][j][RU] = -0.0; + dRays[k][j][RV] = -0.0; + dRays[k][j][RW] = -0.0; + } + + static private void vExtendLabs(int kray) + // Extends lab coords of a failed ray for layout dotted indicator. + // Extends from howfarOK[k] to howfarOK[k]+1. + // Just like vPropagate() but used only for failed rays. + // Extension length depends on OEJIF size metric via DMF.getOsize(). + // Does not update ray[RPATH] nor should it. + // Apply this only AFTER each ray's loop terminates with bExtend[]=true. + { + int j = howfarOK[kray]; + String fracStr = DMF.reg.getuo(UO_LAYOUT, 39); // factory default: B4constants line 870 + double frac = 0.01* Double.parseDouble(fracStr); + double size = DMF.getOsize(); + double dist = frac * size; + if (DEBUG) + { + System.out.println("RT13.vExtendLabs() is extending LAB coords starting at howfarOK = "+j); + System.out.printf("RT13.vExtendLabs() has frac, size, dist = %9.3f %9.3f %9.3f \n", frac, size, dist); + } + dRays[kray][j+1][RX] = dRays[kray][j][RX] + dRays[kray][j][RU] * dist; + dRays[kray][j+1][RY] = dRays[kray][j][RY] + dRays[kray][j][RV] * dist; + dRays[kray][j+1][RZ] = dRays[kray][j][RZ] + dRays[kray][j][RW] * dist; } + static private void fixupLabUVW(int k) + { + int j = 0; + double sign = dRays[k][j][RW] < 0 ? -1.0 : +1.0; + double sos = U.sqr(dRays[k][j][RU]) + U.sqr(dRays[k][j][RV]); + if (sos > 1.0) + { + double r = Math.sqrt(sos); + dRays[k][j][RU] /= r; + dRays[k][j][RV] /= r; + dRays[k][j][RW] = 0.0; + } + else + dRays[k][j][RW] = sign*Math.sqrt(1 - sos); + boolean rayok = isNormalizedLab(dRays[k][j]); + if (!rayok) + System.out.println("fixupLabUVW() exitting, failed lab normalization."); + } + + + static private void normalizeLab(double ray[]) // Normalizes ray components RU RV RW in lab frame // Does not repair minus zeros. @@ -2333,18 +2541,26 @@ static private void normalizeVx(double ray[]) } + static private double getNormErrorVx(double[] ray) + { + return ray[RTUL]*ray[RTUL] + ray[RTVL]*ray[RTVL] + ray[RTWL]*ray[RTWL] - 1.0; + } + static private boolean isNormalizedVx(double[] ray) { - double r2 = ray[RTUL]*ray[RTUL] + ray[RTVL]*ray[RTVL] + ray[RTWL]*ray[RTWL]; - double err = r2 - 1.0; - return Math.abs(err) < TOL; + double err = getNormErrorVx(ray); + return Math.abs(err) < TOL; + } + + static private double getNormErrorLab(double[] ray) + { + return U.sqr(ray[RU]) + U.sqr(ray[RV]) + U.sqr(ray[RW]) - 1.0; } - static private boolean isNormalizedLab(double[] ray) { - double err = U.sqr(ray[RU]) + U.sqr(ray[RV]) + U.sqr(ray[RW]) - 1.0; - return Math.abs(err) < TOL; + double err = getNormErrorLab(ray); + return Math.abs(err) < TOL; } diff --git a/Sources/Random.java b/Sources/Random.java index 1c073a3..baea814 100755 --- a/Sources/Random.java +++ b/Sources/Random.java @@ -24,12 +24,13 @@ * + add random rays to a MTF * * - * Uses RT13 for rayseq[][] and runray(). - * Actually, no random rays are generated herein, - * nor are any ray calculations are performed here. - * This routine's client panel simply manages RT13 ray number zero. - * All the math work is done within RT13. - * Only the kickoff management is done here. + * + * For each random ray, this timer task requests that the + * owner "targetPanel.doRandomRay()" and return True or False. + * + * The targetPanel gets results by requesting RT13.bRunRandomRay(), + * and then uses RT13.dGetRay(0, hsurf, hattr) to gather each point. + * Only the kickoff management and scorekeeping is done here. * * * @author: M.Lampton (c) 2003 STELLAR SOFTWARE all rights reserved. diff --git a/Sources/Triple.java b/Sources/Triple.java index f82e595..6d51df2 100644 --- a/Sources/Triple.java +++ b/Sources/Triple.java @@ -1,6 +1,6 @@ package com.stellarsoftware.beam; -/** Revised 7 Oct 2015 for improved accuracy +/** Revised 7 Oct 2015 for improved accuracy: * Replaced arccos(dotProduct) with arctan2(crossProduct, dotProduct); */ diff --git a/Sources/U.java b/Sources/U.java index 43e663c..8d715b6 100755 --- a/Sources/U.java +++ b/Sources/U.java @@ -206,6 +206,11 @@ static boolean isNegZero(double x) { return 1.0/x == Double.NEGATIVE_INFINITY; } + + static boolean isNotNegZero(double x) + { + return 1.0/x != Double.NEGATIVE_INFINITY; + } static double sqr(double x) { diff --git a/Sources/Z.java b/Sources/Z.java index 4709bdf..7d81319 100755 --- a/Sources/Z.java +++ b/Sources/Z.java @@ -2,7 +2,7 @@ /** class Z is entirely static methods, never instantiated. - * Provides surface function vGetZsurf() for Layout, all surface types. + * Provides surface function dGetZsurf() for Layout, all surface types. * Also supplies vGetSurf() for RT13 for higher surface types. * * PHANTOM HYPERBOLOIDS ARE FORBIDDEN @@ -40,42 +40,58 @@ class Z implements B4constants static public double dGetZsurf(double x, double y, double surf[]) // Uses x,y and returns z for general surface. // Called by Layout graphics with xyz[3] all local. - // Called by RT13 for all surface types. + // Called by RT13.dIntercept() only for higher surface types; + // RT13.dIntercept uses its local dPlaneSolve and dQuadSolve() for simple types. + // ?? Why only "higher" surfaces & numerical methods? + // Apparently fails to be called for OSGAUSS which certainly needs a numerical intercept. + // The interceptor switchyard is in RT13.dIntercept() lines 1200-1400. + // The profile classifier sets OPROFILE; it is in OEJIF.java, lines 400-500 // Copyright 2006 STELLAR SOFTWARE all rights reserved. + // A better plan: use profile flags, and coadd all flagged surface types. { x = dSawtoothX(x, surf); y = dSawtoothY(y, surf); - switch ((int) surf[OPROFILE]) + int iPro = (int) surf[OPROFILE]; + // System.out.println("Z.java dGetZsurf() has been sent "+sProfiles[iPro]); + switch (iPro) { - case OSPLANO: return 0.0; + case OSPLANO: return 0.0; // unused; see RT13.dIntercept(). case OSCONIC: case OSCONICLT: - case OSCONICGT: return zConic(x, y, surf); + case OSCONICGT: // System.out.println("dGetZsurf() is branching to zConic()."); + return zConic(x, y, surf); // unused; see RT13.dIntercept(). case OSXCYL: case OSXCYLLT: - case OSXCYLGT: return zXcyl(x, y, surf); + case OSXCYLGT: return zXcyl(x, y, surf); // unused; see RT13.dIntercept(). case OSYCYL: case OSYCYLLT: - case OSYCYLGT: return zYcyl(x, y, surf); + case OSYCYLGT: return zYcyl(x, y, surf); // unused; see RT13.dIntercept(). case OSTORIC: return zToric(x, y, surf); - case OSPOLYREV: return zPolyRevCombiner(x, y, surf); + case OSPOLYREV: // System.out.println("dGetZsurf() is branching to zPolyRevCombiner"); + return zPolyRevCombiner(x, y, surf); case OSZERNREV: return zZernRevCombiner(x, y, surf); case OSZERNTOR: return zZernTorCombiner(x, y, surf); case OSBICONIC: return zBiconic(x, y, surf); + case OSGAUSS: // System.out.println("dGetZsurf() is branching to zGauss"); + return zGauss(x, y, surf); default: return 0.0; } } - static public void vGetZnorm(double x, double y, double surf[], double norm[]) + static public void vGetNormal(double x, double y, double surf[], double norm[]) // x, y, and surf[] are input; result is norm[3]. - // Each method called gives its gradient in norm[0], norm[1]; + // Each method called reports its gradient into norm[0], norm[1]; // Converted to normalized normal at end of this method. // A189: changed signs so that norm[2] is towards +z. + // The profile classifier sets OPROFILE; it is in OEJIF.java, lines 400-500. + // A better plan: use profile flags, and coadd all flagged surface types. { x = dSawtoothX(x, surf); y = dSawtoothY(y, surf); - switch ((int) surf[OPROFILE]) + int iPro = (int) surf[OPROFILE]; + // System.out.println("Z.java dGetNormal() has been sent "+sProfiles[iPro]); + switch (iPro) { case OSPLANO: vGradPlane(norm); break; case OSCONIC: @@ -92,6 +108,8 @@ static public void vGetZnorm(double x, double y, double surf[], double norm[]) case OSZERNREV: vGradZernRevCombiner(x, y, surf, norm); break; case OSZERNTOR: vGradZernTorCombiner(x, y, surf, norm); break; case OSBICONIC: vGradBiconic(x, y, surf, norm); break; + case OSGAUSS: // System.out.println("vGetNormal() is branching to vGradGauss()"); + vGradGauss(x, y, surf, norm); break; default: vGradPlane(norm); break; } norm[0] *= -1.0; // 2015 Oct 7, A189 @@ -272,8 +290,31 @@ static private double zPoly2D(double x, double y, double surf[]) sum = (sum + surf[i+OA1-1])*r; return sum; } - - + + + + + static private double zGauss(double x, double y, double surf[]) + // 2D circular Gaussian, rms radius "sigma" = surf[ORGAUSS] + // Copyright 2017 STELLAR SOFTWARE all rights reserved. + { + // System.out.println("zGauss has been called."); + if (surf[ORGAUSS] <= 0.) + { + // System.out.println("zGauss is returning negative zero"); + return -0.0; + } + double r2 = x*x + y*y; + double s2 = surf[ORGAUSS]*surf[ORGAUSS]; + double result = surf[OHGAUSS] * Math.exp(-0.5*r2/s2); + // System.out.println("zGauss is returning "+result); + return result; + } + + + + + static private double zZern(double x, double y, double surf[]) // Always fully 2-dimensional. // Copyright 2006 STELLAR SOFTWARE all rights reserved. @@ -502,7 +543,6 @@ static private void vGradPolyRev(double x, double y, double surf[], double grad[ // Poly2D alone; gives unnormalized gradient. // Copyright 2006 STELLAR SOFTWARE all rights reserved { - // System.out.println("class Z, vGradPolyRev has been called."); double r2 = x*x + y*y; double r = Math.sqrt(r2); grad[0] = 0.0; @@ -525,8 +565,6 @@ static private void vGradToric(double x, double y, double surf[], double grad[]) // Polynomial terms OS1..OA14 are included. // Copyright 2007 STELLAR SOFTWARE all rights reserved. { - // System.out.println("class Z, vGradToric has been called."); - // double absy = Math.abs(y); double sy = surf[OASPHER] + 1.0; double cx = surf[OCURVX]; double cy = surf[OCURVE]; @@ -576,8 +614,22 @@ static private void vGradToric(double x, double y, double surf[], double grad[]) grad[1] = ratio * dfdy / arg2; } - - + static private void vGradGauss(double x, double y, double surf[], double grad[]) + // Copyright STELLAR SOFTWARE 2017 + // For debugging, don't call zGauss(); instead repeat its math locally. + { + // System.out.println("vGradGauss() has been called."); + grad[0] = 0.0; + grad[1] = 0.0; + if (surf[ORGAUSS] <= 0.0) /// S.N.H. + return; + double r2 = x*x + y*y; + double s2 = surf[ORGAUSS]*surf[ORGAUSS]; + double z = surf[OHGAUSS] * Math.exp(-0.5*r2/s2); + grad[0] = -x * z / s2; + grad[1] = -y * z / s2; + // System.out.println("vGradGauss() is returning its gradient."); + } //-------------Zernike gradient------------------------------- From 4a25210bd875bfcb8f1afbf28fa66f3da0ce7412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Fri, 27 Sep 2019 20:50:15 +0200 Subject: [PATCH 11/13] Fix commenting in iThin raytracing function --- Sources/RT13.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/RT13.java b/Sources/RT13.java index c792af7..83bc653 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1900,8 +1900,8 @@ static private int iCBOUT(double rayseq[][], double surf[], int g) } static private int iThin(double ray[], double surf[]) - // CoordBreak CBout output surface method - // Must copy previous local xyzuvw into this local surface. + // Jaime García @gvJaime 2019 + // Ray tracing according to thin lens hypothesis. { double focal = surf[OFOCAL]; int sign = (int) Math.signum(focal); From 794bba847d1d0c56a980fd8c3a992d26b393f3e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Fri, 27 Sep 2019 21:09:43 +0200 Subject: [PATCH 12/13] Make small modification to RT13 so Focal is expressed in diopters --- Sources/RT13.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/RT13.java b/Sources/RT13.java index 83bc653..f3ed396 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1903,7 +1903,7 @@ static private int iThin(double ray[], double surf[]) // Jaime García @gvJaime 2019 // Ray tracing according to thin lens hypothesis. { - double focal = surf[OFOCAL]; + double focal = 1 / surf[OFOCAL]; int sign = (int) Math.signum(focal); double[] r = new double[3]; double d; From ef70c5610c88649db7a71a594a89a8324b3ff0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa=20Villena?= Date: Fri, 27 Sep 2019 21:25:24 +0200 Subject: [PATCH 13/13] Rename Focal parameter as Diopters. Add a safe for when this value is still unassigned --- Sources/B4constants.java | 2 +- Sources/OEJIF.java | 8 +++----- Sources/RT13.java | 5 ++++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Sources/B4constants.java b/Sources/B4constants.java index 2571c64..aa42039 100755 --- a/Sources/B4constants.java +++ b/Sources/B4constants.java @@ -517,7 +517,7 @@ So, in summary, I (personally) would be happy as a clam with the static final int OZ33 = 113; static final int OZ34 = 114; static final int OZ35 = 115; - static final int OFOCAL = 116; //focal length of thin lens + static final int ODIOP = 116; //focal length of thin lens static final int OFINALADJ = 117; // final autoadjustable parameter static final int OTIRINDEX = 121; diff --git a/Sources/OEJIF.java b/Sources/OEJIF.java index c1a95e8..794eab0 100755 --- a/Sources/OEJIF.java +++ b/Sources/OEJIF.java @@ -790,6 +790,8 @@ public static int getOptFieldAttrib(String s) return OODIAX; if (s.contains("Y")) return OODIAY; + if (s.contains("P")) + return ODIOP; return OODIAM; case 'd': if (s.contains("X")) @@ -799,11 +801,7 @@ public static int getOptFieldAttrib(String s) return OIDIAM; case 'F': - case 'f': switch(c2up) - { - case 'C': return OFOCAL; // focal length for thin perfect lenses - default: return OFORM; // "form" = nonnumerical - } + case 'f': return OFORM; // "form" = nonnumerical case 'G': case 'g': switch(c1up) // Group or Grating groove density diff --git a/Sources/RT13.java b/Sources/RT13.java index f3ed396..7978177 100755 --- a/Sources/RT13.java +++ b/Sources/RT13.java @@ -1903,7 +1903,10 @@ static private int iThin(double ray[], double surf[]) // Jaime García @gvJaime 2019 // Ray tracing according to thin lens hypothesis. { - double focal = 1 / surf[OFOCAL]; + double focal = surf[ODIOP]; + if (focal == 0) return RROK; // if the value is unparsed, or is 0, leave rays unbent. + // Invert focal for calculations. + focal = 1 / focal; int sign = (int) Math.signum(focal); double[] r = new double[3]; double d;