/** * Leaf rotation toward light */ private void setLeafOrientation(CS_Params par) { if (par.LeafBend == 0) { return; } // FIXME: make this function as fast as possible - a tree has a lot of leafs // rotation outside Vector3 pos = transf.getT(); // the z-vector of transf is parallel to the // axis of the leaf, the y-vector is the normal // (of the upper side) of the leaf Vector3 norm = transf.getY3(); float tpos = (float)(Math.Atan2(pos.Y, pos.X) * 180 / Math.PI); float tbend = tpos - (float)(Math.Atan2(norm.Y, norm.X) * 180 / Math.PI);; // if (tbend>180) tbend = 360-tbend; float bend_angle = par.LeafBend * tbend; // transf = transf.rotz(bend_angle); // rotate about global z-axis transf = transf.rotaxis(bend_angle, DX_Transformation.Z_AXIS); // rotation up norm = transf.getY3(); float fbend = (float)(Math.Atan2((float)Math.Sqrt(norm.X * norm.X + norm.Y * norm.Y), norm.Z) * 180 / Math.PI); bend_angle = par.LeafBend * fbend; transf = transf.rotx(bend_angle); // this is from the paper, but is equivalent with // local x-rotation (upper code line) // // double orientation = Vector.atan2(norm.getY(),norm.getX()); // transf = transf // .rotaxis(-orientation,Vector.Z_AXIS) // .rotx(bend_angle) // .rotaxis(orientation,Vector.Z_AXIS); }
/** * Position at the beginning of the segment * * @return beginning point of the segment */ public Vector3 getLowerPosition() { // self.stem.DBG("segmenttr0: %s, t: %s\n"%(self.transf_pred,self.transf_pred.t())) return(transf.getT()); }
// makes the segments of the stem int makeSegments(int start_seg, int end_seg) { // if (start_seg>end_seg) throw new ArbaroException("Error in segment creation end_seg<start_seg."); if (stemlevel == 1) { tree.updateGenProgress(); } //if (par.verbose) { /* * if (! pruneTest) { * if (stemlevel==0) Console.progressChar('='); * else if (stemlevel==1 && start_seg==0) Console.progressChar('/'); * else if (stemlevel==2 && start_seg==0) Console.progressChar(); * } * //} */ DX_Transformation trf = transf; for (int s = start_seg; s < end_seg; s++) { if (stemlevel == 0) { tree.updateGenProgress(); } if (!pruneTest) {// && par.verbose) { //if (stemlevel==0) Console.progressChar('|'); } // curving trf = newDirection(trf, s); /* * if (Console.debug()) * TRF("Stem.make_segments(): after new_direction ",trf); */ // segment radius float rad1 = stemRadius(s * segmentLength); float rad2 = stemRadius((s + 1) * segmentLength); // create new segment CS_SegmentImpl segment = new CS_SegmentImpl(this, s, trf, rad1, rad2); segment.make(); segments.Add(segment); // create substems // self.DBG("SS-makingsubst? pt: %d, lev: %d\n"%(self.prunetest,self.level)) if (!pruneTest && lpar.level < par.Levels - 1) { // self.DBG("SS-making substems\n") makeSubstems(segment); } if (!pruneTest && lpar.level == par.Levels - 1 && par.Leaves != 0) { makeLeaves(segment); } // shift to next position trf = trf.translate(trf.getZ3() * (segmentLength)); //self.DBG("transf: %s\n"%(transf)) //self.DBG("pos: %s\n"%(transf.vector)) // test if too long if (pruneTest && !isInsideEnvelope(trf.getT())) { // DBG("PRUNE: not inside - return %d\n"%(s)) return(s); } // splitting (create clones) if (s < end_seg - 1) { int segm = makeClones(trf, s); // trf is changed by make_clones // prune test - clone not inside envelope if (segm >= 0) { //DBG("PRUNE: clone not inside - return %d\n"%(segm)) return(segm); } } } return(-1); }