Exemplo n.º 1
0
        /**
         * Gives a clone a new direction (splitting)
         *
         * @param trf The base transformation of the clone
         * @param s_angle The splitting angle
         * @param nseg The segment number, where the clone begins
         * @param nsplits The number of clones
         * @return The new direction for the clone
         */

        DX_Transformation split(DX_Transformation trf,
                                float s_angle, int nseg, int nsplits)
        {
            // applies a split angle to the stem - the Weber/Penn method
            int remaining_seg = segmentCount - nseg - 1;

            // the splitangle
            // FIXME: don't know if it should be nSplitAngle or nSplitAngle/2
            float declination = (float)(Math.Acos(trf.getZ3().Z) * 180 / Math.PI);
            float split_angle = Math.Max(0, (lpar.nSplitAngle
                                             + lpar.var(lpar.nSplitAngleV) - declination));

            // FIXME: first works better for level 0, second for further levels
            // transf = transf.rotxz(split_angle,s_angle)
            trf = trf.rotx(split_angle);

            // adapt split correction
            splitCorrection -= split_angle / remaining_seg;
            //t_corr = Transformation().rotx(-split_angle/remaining_seg)

            float split_diverge;

            if (s_angle > 0)
            { // original stem has s_angle==0
                if (par._0BaseSplits > 0 && stemlevel == 0 && nseg == 0)
                {
                    split_diverge = s_angle + lpar.var(lpar.nSplitAngleV);
                }
                else
                {
                    split_diverge = (float)(20 + 0.75 * (30 + Math.Abs(declination - 90))
                                            * Math.Pow((lpar.var(1) + 1) / 2.0, 2));
                    if (lpar.var(1) >= 0)
                    {
                        split_diverge = -split_diverge;
                    }
                }

                trf = trf.rotaxis(split_diverge, DX_Transformation.Z_AXIS);
            }
            else
            {
                split_diverge = 0;  // for debugging only
            }
            // adjust some parameters
            //split_cnt = split_cnt+1;

            // lower substem prospensity
            if (!pruneTest)
            {
                substemsPerSegment /= (float)(nsplits + 1);
                // FIXME: same reduction for leaves_per_segment?
            }
            return(trf);
        }
Exemplo n.º 2
0
        /**
         *	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);
        }
Exemplo n.º 3
0
        /**
         * Calcs a new direction for the current segment
         *
         * @param trf The transformation of the previous segment
         * @param nsegm The number of the segment ( for testing, if it's the
         *              first stem segment
         * @return The new transformation of the current segment
         */

        DX_Transformation newDirection(DX_Transformation trf, int nsegm)
        {
            // next segments direction

            // The first segment shouldn't get another direction
            // down and rotation angle shouldn't be falsified
            if (nsegm == 0)
            {
                return(trf);
            }

            /*
             * if (Console.debug())
             *  TRF("Stem.new_direction() before curving",trf);
             */

            // get curving angle
            double delta;

            if (lpar.nCurveBack == 0)
            {
                delta = lpar.nCurve / lpar.nCurveRes;
            }
            else
            {
                if (nsegm < (lpar.nCurveRes + 1) / 2)
                {
                    delta = lpar.nCurve * 2 / lpar.nCurveRes;
                }
                else
                {
                    delta = lpar.nCurveBack * 2 / lpar.nCurveRes;
                }
            }
            delta += splitCorrection;

            /*
             * if (Console.debug())
             *  DBG("Stem.new_direction(): delta: "+delta);
             */

            trf = trf.rotx(delta);


            // With Weber/Penn the orientation of the x- and y-axis
            // shouldn't be disturbed (maybe, because proper curving relies on this)
            // so may be such random rotations shouldn't be used, instead nCurveV should
            // add random rotation to rotx, and rotate nCurveV about the tree's z-axis too?

            // add random rotation about z-axis
            if (lpar.nCurveV > 0)
            {
                //          if (nsegm==0 && stemlevel==0) { // first_trunk_segment
                //              // random rotation more moderate
                //              delta = (Math.abs(lpar.var(lpar.nCurveV)) -
                //                      Math.abs(lpar.var(lpar.nCurveV)))
                //						/ lpar.nCurveRes;
                //          }	else {
                // full random rotation
                delta = lpar.var(lpar.nCurveV) / lpar.nCurveRes;
                //          }
                // self.DBG("curvV (delta): %s\n" % str(delta))
                double rho = 180 + lpar.var(180);
                trf = trf.rotaxisz(delta, rho);
            }
            //TRF("Stem.new_direction() after curving",trf);

            // attraction up/down
            if (par.AttractionUp != 0 && stemlevel >= 2)
            {
                double declination = Math.Acos(trf.getZ3().Z);

                //          I don't see, why we need orientation here, may be this avoids
                //          attraction of branches with the x-Axis up and thus avoids
                //			twisting (see below), but why branches in one direction should
                //			be attracted, those with another direction not, this is unnaturally:
                //          double orient = Math.acos(trf.getY().getZ());
                //          double curve_up_orig = par.AttractionUp * declination * Math.cos(orient)/lpar.nCurveRes;

                // FIXME: devide by (lpar.nCurveRes-nsegm) if last segment
                // should actually be vertical
                double curve_up = par.AttractionUp *
                                  Math.Abs(declination * Math.Sin(declination)) / lpar.nCurveRes;

                Vector3 z = trf.getZ3();
                // FIXME: the mesh is twisted for high values of AttractionUp
                trf = trf.rotaxis(-curve_up * 180 / Math.PI, new Vector3(-z.Y, z.X, 0));
                // trf = trf.rotx(curve_up*180/Math.PI);
            }
            return(trf);
        }