/** * Set the front state * * @param fsegment length of first segment in graphics coord * @param rsegment length of repeating segment in graphics coord * @param fshapes shapes of the front * @param fred first reds * @param fgreen first greens * @param fblue first blues * @param rshapes repeating shapes * @param rred repeating reds * @param rgreen repeating greens * @param rblue repeating blues * @throws RemoteException On badness * @throws VisADException On badness */ private void setFrontState( float fsegment, float rsegment, float[][][] fshapes, float[] fred, float[] fgreen, float[] fblue, float[][][] rshapes, float[] rred, float[] rgreen, float[] rblue) throws VisADException, RemoteException { fsegment_length = fsegment; rsegment_length = rsegment; nrshapes = rshapes.length; for (int i = 0; i < nrshapes; i++) { if ((rshapes[i] == null) || (rshapes[i].length != 2) || (rshapes[i][0] == null) || (rshapes[i][1] == null) || (rshapes[i][0].length != rshapes[i][1].length)) { throw new VisADException("bad rshapes[" + i + "]"); } } if ((rred == null) || (rred.length != nrshapes) || (rgreen == null) || (rgreen.length != nrshapes) || (rblue == null) || (rblue.length != nrshapes)) { throw new VisADException("bad rcolors"); } repeat_tris = new int[nrshapes][][]; for (int i = 0; i < nrshapes; i++) { repeat_tris[i] = DelaunayCustom.fill(rshapes[i]); } repeat_shapes = new float[nrshapes][2][]; int rlen = 0; for (int i = 0; i < nrshapes; i++) { int n = rshapes[i][0].length; rlen += n; repeat_shapes[i][0] = new float[n]; repeat_shapes[i][1] = new float[n]; System.arraycopy(rshapes[i][0], 0, repeat_shapes[i][0], 0, n); System.arraycopy(rshapes[i][1], 0, repeat_shapes[i][1], 0, n); } rprofile_length = rlen; repeat_red = new float[nrshapes]; repeat_green = new float[nrshapes]; repeat_blue = new float[nrshapes]; System.arraycopy(rred, 0, repeat_red, 0, nrshapes); System.arraycopy(rgreen, 0, repeat_green, 0, nrshapes); System.arraycopy(rblue, 0, repeat_blue, 0, nrshapes); if (fshapes == null) { // if no different first shapes, just use repeat shapes nfshapes = nrshapes; first_tris = repeat_tris; first_shapes = repeat_shapes; first_red = repeat_red; first_green = repeat_green; first_blue = repeat_blue; } else { nfshapes = fshapes.length; for (int i = 0; i < nfshapes; i++) { if ((fshapes[i] == null) || (fshapes[i].length != 2) || (fshapes[i][0] == null) || (fshapes[i][1] == null) || (fshapes[i][0].length != fshapes[i][1].length)) { throw new VisADException("bad fshapes[" + i + "]"); } } if ((fred == null) || (fred.length != nfshapes) || (fgreen == null) || (fgreen.length != nfshapes) || (fblue == null) || (fblue.length != nfshapes)) { throw new VisADException("bad fcolors"); } first_tris = new int[nfshapes][][]; for (int i = 0; i < nfshapes; i++) { first_tris[i] = DelaunayCustom.fill(fshapes[i]); } first_shapes = new float[nfshapes][2][]; int flen = 0; for (int i = 0; i < nfshapes; i++) { int n = fshapes[i][0].length; flen += n; first_shapes[i][0] = new float[n]; first_shapes[i][1] = new float[n]; System.arraycopy(fshapes[i][0], 0, first_shapes[i][0], 0, n); System.arraycopy(fshapes[i][1], 0, first_shapes[i][1], 0, n); } fprofile_length = flen; first_red = new float[nfshapes]; first_green = new float[nfshapes]; first_blue = new float[nfshapes]; System.arraycopy(fred, 0, first_red, 0, nfshapes); System.arraycopy(fgreen, 0, first_green, 0, nfshapes); System.arraycopy(fblue, 0, first_blue, 0, nfshapes); } if (rprofile_length < 5) { rprofile_length = 5; } if (fprofile_length < 5) { fprofile_length = 5; } }
/** * Create a front from the curve * * @param curve the curve coordinates * @param flip true to flip the pips * @return The front as a FieldImpl * @throws RemoteException On badness * @throws VisADException On badness */ private FieldImpl curveToFront(float[][] curve, boolean flip) throws VisADException, RemoteException { if (flipTheFlip) { flip = !flip; } // compute various scaling factors int len = curve[0].length; if (len < 2) { return null; } float[] seg_length = new float[len - 1]; float curve_length = curveLength(curve, seg_length); float delta = curve_length / (len - 1); // curve[findex] where // float findex = ibase + mul * repeat_shapes[shape][0][j] float mul = rprofile_length * zoom / rsegment_length; // curve_perp[][findex] * ratio * repeat_shapes[shape][1][j] float ratio = delta * mul; // compute unit perpendiculars to curve float[][] curve_perp = new float[2][len]; for (int i = 0; i < len; i++) { int im = i - 1; int ip = i + 1; if (im < 0) { im = 0; } if (ip > len - 1) { ip = len - 1; } float yp = curve[0][ip] - curve[0][im]; float xp = curve[1][ip] - curve[1][im]; xp = -xp; float d = (float) Math.sqrt(xp * xp + yp * yp); if (flip) { d = -d; } xp = xp / d; yp = yp / d; curve_perp[0][i] = xp; curve_perp[1][i] = yp; } // build Vector of FlatFields for each shape of each segment Vector inner_field_vector = new Vector(); for (int segment = 0; true; segment++) { // curve[findex] where // float findex = ibase + mul * repeat_shapes[shape][0][j] float segment_length = (segment == 0) ? fsegment_length : rsegment_length; int profile_length = (segment == 0) ? fprofile_length : rprofile_length; mul = profile_length * zoom / segment_length; // curve_perp[][findex] * ratio * repeat_shapes[shape][1][j] // float ratio = delta * mul; // figure out if clipping is needed for this segment // only happens for last segment boolean clip = false; float xclip = 0.0f; // int ibase = segment * profile_length; int ibase = (segment == 0) ? 0 : fprofile_length + (segment - 1) * rprofile_length; int iend = ibase + profile_length; if (ibase > len - 1) { break; } if (iend > len - 1) { clip = true; iend = len - 1; xclip = (iend - ibase) / mul; } // set up shapes for first or repeating segment int nshapes = nrshapes; float[][][] shapes = repeat_shapes; int[][][] tris = repeat_tris; float[] red = repeat_red; float[] green = repeat_green; float[] blue = repeat_blue; if (segment == 0) { nshapes = nfshapes; shapes = first_shapes; tris = first_tris; red = first_red; green = first_green; blue = first_blue; } // iterate over shapes for segment for (int shape = 0; shape < nshapes; shape++) { float[][] samples = shapes[shape]; int[][] ts = tris[shape]; /* // if needed, clip shape if (clip) { float[][][] outs = new float[1][][]; int[][][] outt = new int[1][][]; DelaunayCustom.clip(samples, ts, 1.0f, 0.0f, xclip, outs, outt); samples = outs[0]; ts = outt[0]; } */ if ((samples == null) || (samples[0].length < 1)) { break; } float[][] ss = mapShape(samples, len, ibase, mul, ratio, curve, curve_perp); // **** get rid of previous calls to fill() **** ts = DelaunayCustom.fill(ss); // jeffmc: For now don't clip. This seems to fix the problem of too short a front boolean DOCLIP = false; if (clip && DOCLIP) { float[][] clip_samples = { {xclip, xclip, xclip - CLIP_DELTA}, {CLIP_DELTA, -CLIP_DELTA, 0.0f} }; float[][] clip_ss = mapShape(clip_samples, len, ibase, mul, ratio, curve, curve_perp); // now solve for: // xc * clip_samples[0][0] + yc * clip_samples[1][0] = 1 // xc * clip_samples[0][1] + yc * clip_samples[1][1] = 1 // xc * clip_samples[0][2] + yc * clip_samples[1][2] < 1 float det = (clip_samples[0][1] * clip_samples[1][0] - clip_samples[0][0] * clip_samples[1][1]); float xc = (clip_samples[1][0] - clip_samples[1][1]) / det; float yc = (clip_samples[0][1] - clip_samples[0][0]) / det; float v = 1.0f; if (xc * clip_samples[0][2] + yc * clip_samples[1][2] > v) { xc = -xc; yc = -yc; v = -v; } float[][][] outs = new float[1][][]; int[][][] outt = new int[1][][]; DelaunayCustom.clip(ss, ts, xc, yc, v, outs, outt); ss = outs[0]; ts = outt[0]; } if (ss == null) { break; } int n = ss[0].length; // create color values for field float[][] values = new float[3][n]; float r = red[shape]; float g = green[shape]; float b = blue[shape]; for (int i = 0; i < n; i++) { values[0][i] = r; values[1][i] = g; values[2][i] = b; } // construct set and field DelaunayCustom delaunay = new DelaunayCustom(ss, ts); Irregular2DSet set = new Irregular2DSet(curve_type, ss, null, null, null, delaunay); FlatField field = new FlatField(front_inner, set); field.setSamples(values, false); inner_field_vector.addElement(field); // some crazy bug - see Gridded3DSet.makeNormals() } // end for (int shape=0; shape<nshapes; shape++) } // end for (int segment=0; true; segment++) int nfields = inner_field_vector.size(); Integer1DSet iset = new Integer1DSet(front_index, nfields); FieldImpl front = new FieldImpl(front_type, iset); FlatField[] fields = new FlatField[nfields]; for (int i = 0; i < nfields; i++) { fields[i] = (FlatField) inner_field_vector.elementAt(i); } front.setSamples(fields, false); return front; }