static void Main(string[] args)
        {
            while (true)
            {
                string str = null;
                str = Console.ReadLine();
                if (str.Length > 50)
                {
                    Console.WriteLine("Ошибка введено более 50 символов");
                }
                else
                {
                    var         math       = new MathCore();
                    IExpression expression = new MxparserExpression(str);

                    if (math.CheckExpression(expression))
                    {
                        Console.WriteLine("Error");
                        return;
                    }

                    var result = math.Calculate(expression);
                    Console.WriteLine(result);
                }
            }
        }
Esempio n. 2
0
        public override void Process(IBattleEntity attacker, IBattleEntity target)
        {
            float hitprobability = MathCore.Sigmoid(attacker.Dexterity - target.Dexterity, 1.1f, GetCenter());

            if (RNG.XORShift64.NextFloat() < hitprobability)
            {
                long playerid = (target as PlayerBattleEntity)?.PlayerID ?? 0;
                int  gold     = Level * 50 + RNG.XORShift64.NextInt(attacker.Level * 15);
                gold = Math.Min(gold, context.GetModule <PlayerModule>().GetPlayerGold(playerid));

                if (gold == 0)
                {
                    context.GetModule <RPGMessageModule>().Create().BattleActor(attacker).Text(" looks at ").BattleActor(target).Text(" unable to grasp how someone can enter a battle without any ").Gold(0).Text(".").Send();
                }
                else
                {
                    context.GetModule <PlayerModule>().UpdateGold(playerid, -gold);
                    context.GetModule <RPGMessageModule>().Create().BattleActor(attacker).Text(" steals ").Gold(gold).Text(" from ").BattleActor(target).Text(", throwing it into the next hole while laughing maniacally.").Send();
                }
            }
            else
            {
                context.GetModule <RPGMessageModule>().Create().BattleActor(attacker).Text(" fails to steal ").Gold(0).Text(" from ").BattleActor(target).Text(".").Send();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Adds thurst in the given direction.
        /// </summary>
        /// <param name="dir">The direction.</param>
        public void Thrust(Vector2 dir)
        {
            // Rotate the direction.
            var rotatedForce = new Vector2(
                dir.X * MathCore.Cos(Body.Rotation) + -dir.Y * MathCore.Sin(Body.Rotation),
                dir.Y * MathCore.Cos(Body.Rotation) + dir.X * MathCore.Sin(Body.Rotation));

            // Add the thrust as acceleration.
            var velocity = Body.LinearVelocity;

            if (velocity != Vector2.Zero)
            {
                var currentSpeed = velocity.Length();

                var velocityDir = Vector2.Normalize(velocity);
                var forceDir    = Vector2.Normalize(rotatedForce);

                float dotProduct;
                Vector2.Dot(ref velocityDir, ref forceDir, out dotProduct);

                var damping = 1.0f - (1.0f / _maxSpeed * currentSpeed) * dotProduct;

                _force += rotatedForce * damping;
            }
            else
            {
                _force += rotatedForce;
            }
        }
Esempio n. 4
0
        public override void init()
        {
            if (!inited)
            {
                if (branchType == BranchType.Trank)
                {
                    radiusRate  *= 1.5f;
                    gravityConst = new float[10] {
                        0.0f, 0.15f, 0.25f, 0.50f, 0.25f, 0.0f, -0.15f, -0.25f, -0.40f, 0.0f
                    };
                    gravityLenthNormalized = 0.25f;
                    branchStart            = (int)(3.0f * this.trunkLen);
                }
                if (branchType == BranchType.Branch)
                {
                    height *= 1.1f;

                    step         = 1;
                    steps        = 5;
                    count        = 1;
                    branchStart  = 2;
                    branchEnd    = (MathCore.RandomRange(random, -1.0f, 1.0f) > 0.0f ? 7 : 8);
                    spread       = 0.05f;
                    stepRand     = 180.0f;
                    overAllRand  = 180.0f;
                    forceOverall = 0.0f;
                    overallRoll  = 90.0f;

                    radStart = 0.6f;
                    radEnd   = 0.8f;

                    heightStart = 1.4f;
                    heightEnd   = 1.5f;

                    tiltStart = 60f;
                    tiltEnd   = 35f;
                }
                if (iterationStep == 2)
                {
                    step        = 1;
                    steps       = 4;
                    count       = 1;
                    branchStart = 6;
                    branchEnd   = 7;
                }
                inited = true;
            }

            //添加样条线节点
            spline.Clear();
            for (int i = 0; i < nodes; i++)
            {
                spline.Add(new TreeSplineNode());
            }

            //处理样条线的形态
            UpdateSpline();
        }
Esempio n. 5
0
        private void GenerateTunnels(Vector2 start, float maxLength = 2000.0f, float turnStrength = 0.2f)
        {
            //1234
            //12345
            //498764867
            //582764
            var         random = new FastRandom(498764867);
            const float step   = 2.0f;

            var terrainHeight = _terrain.TerrainSize.Y / 2.0f;
            var maxSize       = new Vector2(30.0f);

            var currentPosition  = start;
            var currentDirection = Vector2.UnitX;

            var length = 0.0f;

            while (length < maxLength)
            {
                var currentSize = maxSize + new Vector2(Math.Max(0.0f, length + 200.0f - maxLength)) * 1.0f;

                var brushSize = new Vector2(random.NextFloat() * currentSize.X, random.NextFloat() * currentSize.Y);
                var brush     = new CircleBrush(
                    (brushSize.X + brushSize.Y) / 4.0f,
                    currentPosition + new Vector2(random.NextRangedFloat(), random.NextRangedFloat()));

                _terrain.SetQuads(brush, false, true);

                // Add rotation.
                var rotationDir = random.NextRangedFloat();

                // Prevent going outside terrain or going back.
                if (currentPosition.Y > terrainHeight - 200.0f ||
                    (currentDirection.X < 0.0f && currentDirection.Y > 0.0f))
                {
                    rotationDir = (rotationDir - 1.0f) * 0.1f;
                }
                else if (currentPosition.Y < -(terrainHeight + 200.0f) ||
                         (currentDirection.X < 0.0f && currentDirection.Y < 0.0f))
                {
                    rotationDir = (rotationDir + 1.0f) * 0.1f;
                }

                // Apply rotation.
                var rotation = rotationDir * turnStrength;
                currentDirection = new Vector2(
                    currentDirection.X * MathCore.Cos(rotation) + -currentDirection.Y * MathCore.Sin(rotation),
                    currentDirection.Y * MathCore.Cos(rotation) + currentDirection.X * MathCore.Sin(rotation));

                currentPosition += currentDirection * step;
                length          += step;
            }

            _terrain.Refresh();
        }
Esempio n. 6
0
    private void UpdateToOrigin()
    {
        m_t -= DELTA_T;          //Time.smoothDeltaTime;
        float delta_t = DELTA_T; //Time.smoothDeltaTime;

        if (m_t < 0)
        {
            delta_t     += m_t;
            m_t          = 0;
            m_is_arrived = true;
        }

        this.transform.localPosition -= MathCore.DerivSpline(m_t / FACTOR, TAN_ORIGIN, 0.7f) * delta_t * m_translation;
    }
Esempio n. 7
0
    private void UpdateToDestination()
    {
        m_t += DELTA_T;          //Time.smoothDeltaTime;
        float delta_t = DELTA_T; //.smoothDeltaTime;

        if (m_t > FACTOR)
        {
            delta_t     -= m_t - FACTOR;
            m_t          = FACTOR;
            m_is_arrived = true;
        }

        this.transform.localPosition += MathCore.DerivSpline(m_t / FACTOR, TAN_ORIGIN, 0.7f) * delta_t * m_translation;
    }
Esempio n. 8
0
        public override void Process(IBattleEntity attacker, IBattleEntity target)
        {
            float hitprobability = MathCore.Sigmoid(GetModifiedDexterity(attacker) - target.Dexterity, 1.1f, 0.7f);

            context.GetModule <RPGMessageModule>().Create().BattleActor(attacker).Text(" tries to bite ").BattleActor(target).Text(".").Send();

            if (RNG.XORShift64.NextFloat() < hitprobability)
            {
                target.AddEffect(new PoisonEffect(target, context.GetModule <AdventureModule>(), context.GetModule <RPGMessageModule>())
                {
                    Level = Level,
                    Time  = 30.0 + 160.0 * Level
                });
            }
        }
Esempio n. 9
0
        public override void Process(IBattleEntity attacker, IBattleEntity target)
        {
            float             hitprobability = MathCore.Sigmoid(GetModifiedDexterity(attacker) - target.Dexterity, 1.1f, 0.68f);
            RPGMessageBuilder message        = context.GetModule <RPGMessageModule>().Create().BattleActor(attacker).Text(" tries to bite ").BattleActor(target);

            if (RNG.XORShift64.NextFloat() < hitprobability)
            {
                int hp = Math.Min(target.HP, (int)(target.MaxHP * (0.1 + 0.05 * Level)));
                message.Text(", sucks on him and heals").Health(attacker.Heal(hp)).Text(".");
                target.Hit(hp);
            }
            else
            {
                message.Text(" but fails miserably.");
            }
            message.Send();
        }
Esempio n. 10
0
 public void ClassInitialize()
 {
     mc = new MathCore();
 }
Esempio n. 11
0
        public void UpdateSpline()
        {
            int i = 0;

            float startRadius, endRadius;

            startRadius = radiusRate * growRate;

            if (branchType == BranchType.Leaves)
            {
                return;
            }
            if (branchType == BranchType.Trank)
            {
                endRadius = startRadius * 0.15f;
            }
            else
            {
                endRadius = startRadius * 0.02f;
            }

            Vector3    startPos = centerPos;
            Quaternion q        = rotation;

            lengthStep = height * growRate / (spline.Count);

            /*
             * 在样条线上加一个PerlinNoise,两层(一层是幅度一层是相位)
             * 转轴旋转平面垂直于上一个节点的生长方向,从0开始旋转noiseP度;
             * 然后绕转轴旋转noiseA度。
             */

            int   noiseStep = spline.Count / 4;
            float noiseAmpl = 8;//(height * growRate) / 6.0;

            float[] noiseA = MathCore.PerlinNoise(spline.Count, noiseStep, noiseAmpl, null);
            float[] noiseP = MathCore.PerlinNoise(spline.Count, noiseStep, 180, null);//相位先设定为2pi

            //重力
            float[] gravityFactor        = MathCore.PerlinNoise(spline.Count, noiseStep, 0.1f, gravityConst);
            float   gravityInfectionStep = gravityLenthNormalized / nodes;

            //向心旋转(它的主要组成就是perlinNoise)
            float[] gnarlFactor        = MathCore.PerlinNoise(spline.Count, noiseStep, 0.4f, gnarlConst);
            float   gnarlInfectionStep = gnarlLenthNormalized / nodes;

            //样条线
            //第一个点和当前node的数据一致
            spline[i].position       = centerPos;
            spline[i].rotationGlobal = rotation;
            spline[i].tangentGlobal  = (rotation * new Vector3(1, 0, 0));//假定切线在x轴
            spline[i].radius         = startRadius;

            //如果是主干,根部加粗
            if (branchType == BranchType.Trank)
            {
                spline[i].radius *= 2.0f;
            }

            for (i = 1; i < spline.Count; i++)
            {
                //位置是由上一个node的生长方向决定的
                spline[i].position = spline[i - 1].position + spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0);

                //先让这个节点的方向和上一个节点的方向保持一致
                spline[i].rotationGlobal = spline[i - 1].rotationGlobal;
                spline[i].tangentGlobal  = spline[i - 1].tangentGlobal;

                //当前生长方向
                Vector3 dirc = spline[i].rotationGlobal * Vector3.up;

                ////////////////////
                //处理重力
                ////////////////////

                /*
                 * 重力直接作用于生长方向上。
                 * 相加,规范化,乘以步长。
                 */
                dirc += gravityInfectionStep * gravityFactor[i] * gravityAxis;
                dirc.Normalize();

                ////////////////////
                //处理旋力
                ////////////////////

                /*
                 * 为了处理“旋力”,我们需要求出在以主干为圆心,过当前点的切线向量。
                 * 并将这个向量和当前的生长方向相加,规范化,乘以步长。
                 * 最后根据它求得这一段的rotation。
                 */

                //先拿到当前点相对父树枝原点的位置
                Vector3 posLocal = spline[i].position - parentCenterPos;
                //把这个相对位置绕父树枝的方向旋转2度,与原向量相减规范化得到近似的切线朝向
                Vector3 tang = Quaternion.AngleAxis(1.0f, parentAxis) * posLocal - posLocal;
                tang.Normalize();

                dirc += tang * gnarlInfectionStep;
                dirc.Normalize();

                ////////////////////
                //计算rotation
                ////////////////////

                spline[i].rotationLocal = Quaternion.FromToRotation(spline[i - 1].rotationGlobal * Vector3.up, dirc);

                ////////////////////
                //处理噪声
                ////////////////////

                //当前旋转方向由噪声决定
                //处理旋转
                //转轴
                Vector3 rotateAxis = Quaternion.AngleAxis(noiseP[i], spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0)) * spline[i - 1].tangentGlobal;
                rotateAxis.Normalize();

                //旋转,并保存一个相对与上一个节点的旋转( rotationLocal )
                spline[i].rotationLocal = Quaternion.AngleAxis(noiseA[i], rotateAxis) * spline[i].rotationLocal;

                //更新global
                spline[i].rotationGlobal = spline[i].rotationLocal * spline[i].rotationGlobal;
                spline[i].tangentGlobal  = spline[i].rotationLocal * spline[i].tangentGlobal;

                //处理当前结点截面的大小
                spline[i].radius = ((endRadius - startRadius) * (i / ((float)spline.Count)) + startRadius) * Random.Range(0.9f, 1.1f);
            }

            rotation = spline[i - 1].rotationGlobal;
        }
Esempio n. 12
0
        public void UpdateSpline()
        {
            int i = 0;

            float startRadius, endRadius;

            startRadius = radiusRate * growRate;

            if (branchType == BranchType.Leaves)
            {
                return;
            }
            if (branchType == BranchType.Trank)
            {
                endRadius = startRadius * 0.15f;
            }
            else
            {
                endRadius = startRadius * 0.02f;
            }

            Vector3    startPos   = centerPos;
            Quaternion q          = rotation;
            float      lengthStep = height * growRate / (spline.Count);

            /*
             * 在样条线上加一个PerlinNoise,两层(一层是幅度一层是相位)
             *
             * 转轴旋转平面垂直于上一个节点的生长方向,从0开始旋转noiseP度;
             * 然后绕转轴旋转noiseA度。
             */

            int   noiseStep = spline.Count / 4;
            float noiseAmpl = 8;//(height * growRate) / 6.0;

            float[] noiseA = MathCore.PerlinNoise(spline.Count, noiseStep, noiseAmpl, null);
            float[] noiseP = MathCore.PerlinNoise(spline.Count, noiseStep, 180, null);//相位先设定为2pi

            //样条线
            //第一个点和当前node的数据一致
            spline[i].position       = centerPos;
            spline[i].rotationGlobal = rotation;
            spline[i].tangentGlobal  = (rotation * new Vector3(1, 0, 0));//假定切线在x轴
            spline[i].radius         = startRadius;

            //如果是主干,根部加粗
            if (branchType == BranchType.Trank)
            {
                spline[i].radius *= 2.0f;
            }

            for (i = 1; i < spline.Count; i++)
            {
                //位置是由上一个node的生长方向决定的
                spline[i].position = spline[i - 1].position + spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0);

                //当前旋转方向由噪声决定
                //先让这个节点的方向和上一个节点的方向保持一致
                spline[i].rotationGlobal = spline[i - 1].rotationGlobal;
                spline[i].tangentGlobal  = spline[i - 1].tangentGlobal;

                //再处理旋转
                //转轴
                Vector3 rotateAxis = Quaternion.AngleAxis(noiseP[i], spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0)) * spline[i - 1].tangentGlobal;
                rotateAxis.Normalize();

                //旋转
                Quaternion quaternion = Quaternion.AngleAxis(noiseA[i], rotateAxis);
                spline[i].rotationGlobal = quaternion * spline[i].rotationGlobal;
                spline[i].tangentGlobal  = quaternion * spline[i].tangentGlobal;

                //处理当前结点截面的大小
                spline[i].radius = ((endRadius - startRadius) * (i / ((float)spline.Count)) + startRadius) * Random.Range(0.9f, 1.1f);
            }
        }
Esempio n. 13
0
        public AdventureStatus ProcessPlayer(long playerid)
        {
            IBattleEntity attacker;
            IBattleEntity target;

            lock (actors) {
                if (actors.Count < 2)
                {
                    return(AdventureStatus.Exploration);
                }

                foreach (IBattleEntity entity in actors)
                {
                    entity.Refresh();
                }


                attacker = actors[actor];
                actor    = (actor + 1) % actors.Count;
                target   = actors[actor];
            }

            RPGMessageBuilder message = messages?.Create();

            foreach (IBattleEffect effect in attacker.Effects.Where(t => t is IBattleEffect && ((IBattleEffect)t).Type == BattleEffectType.Persistent).Cast <IBattleEffect>())
            {
                EffectResult result = effect.ProcessEffect(attacker, target);
                if (result.Type == EffectResultType.CancelAttack)
                {
                    return(AdventureStatus.MonsterBattle);
                }

                AdventureStatus status = ProcessEffectResult(result, attacker, target, message);
                if (status != AdventureStatus.MonsterBattle)
                {
                    message?.Send();
                    attacker.CleanUp();
                    target.CleanUp();
                    return(status);
                }
            }

            MonsterSkill skill = (attacker as MonsterBattleEntity)?.DetermineSkill();

            if (skill != null)
            {
                skill.Process(attacker, target);
                AdventureStatus status = CheckStatus(attacker, target, message);
                message?.Send();
                return(status);
            }

            float           hitprobability = MathCore.Sigmoid(attacker.Dexterity - target.Dexterity, 1.1f, 0.7f);
            float           dice           = RNG.XORShift64.NextFloat();
            AdventureStatus returnstatus   = AdventureStatus.MonsterBattle;

            if (dice < hitprobability)
            {
                bool hit = true;
                foreach (IBattleEffect effect in target.Effects.Where(t => (t as IBattleEffect)?.Type == BattleEffectType.Defense).Cast <IBattleEffect>())
                {
                    if (effect.ProcessEffect(attacker, target).Type == EffectResultType.CancelAttack)
                    {
                        hit = false;
                        break;
                    }
                }

                if (hit)
                {
                    bool damagecritical = attacker.WeaponOptimum > 0 && RNG.XORShift64.NextFloat() < (float)attacker.Luck / attacker.WeaponOptimum;
                    bool armorcritical  = target.ArmorOptimum > 0 && RNG.XORShift64.NextFloat() < (float)target.Luck / target.ArmorOptimum;

                    int power = damagecritical ? attacker.Power * 2 : attacker.Power;
                    int armor = armorcritical ? target.Defense * 2 : target.Defense;

                    int damage = (int)Math.Max(0, (power - armor) * (0.5f + 0.5f * dice / hitprobability));
                    if (damage <= 0)
                    {
                        message?.BattleActor(target);
                        if (armorcritical)
                        {
                            message?.Bold();
                        }

                        message?.Text(" deflects ").Reset().BattleActor(attacker).Text("'s attack.");
                        target.Hit(0);
                    }
                    else
                    {
                        message?.BattleActor(attacker);
                        if (damagecritical)
                        {
                            message?.Bold();
                        }

                        message?.Text(armorcritical ? " clashes with " : " hits ");
                        message?.Reset().BattleActor(target).Text(" for ").Damage(damage).Text(".");

                        IBattleEffect effect = attacker.Effects.FirstOrDefault(e => e is ShittyWeaponEffect) as IBattleEffect;
                        ProcessEffectResult(effect?.ProcessEffect(attacker, target), attacker, target, message);

                        target.Hit(damage);
                        returnstatus = CheckStatus(attacker, target, message);
                        if (returnstatus == AdventureStatus.MonsterBattle)
                        {
                            if (target is PlayerBattleEntity)
                            {
                                message?.Text(" ").BattleActor(target).Text(" has ").Health(target.HP).Text(" left.");
                            }
                        }
                        else
                        {
                            attacker.CleanUp();
                            target.CleanUp();
                        }
                    }
                }
            }
            else
            {
                message?.BattleActor(attacker).Text(" attacks ").BattleActor(target).Text(" but ").Color(AdventureColors.Miss).Text("misses").Reset().Text(".");
            }

            message?.Send();
            return(returnstatus);
        }
Esempio n. 14
0
        public override void generateChildren()
        {
            float dAngle = 360.0f / count;

            if (count == 1)
            {
                dAngle = 0f;
            }

            float overallAngle = overallRoll, stepAngle = 0f;

            int i, j, stepCount = 0;

            for (i = branchStart; i <= branchEnd; i += step)
            {
                stepCount++;
                stepAngle = overallAngle;
                for (j = 0; j < count; j++)
                {
                    //创建树枝
                    TreeVer4_Ultra branch = new TreeVer4_Ultra(random);

                    if (iterationStep == 2)
                    {
                        if (MathCore.RandomRange(random, 0, 10) < 10)
                        {
                            //这是一片叶子
                            branch.branchType = BranchType.Leaves;

                            //这片叶子的旋转
                            float tilt = MathCore.RandomRange(random, -tiltRand, tiltRand) -
                                         (tiltStart - tiltEnd) * ((stepCount - 1) / (float)(steps - 1)) + tiltStart;

                            branch.rotation = Quaternion.AngleAxis(tilt,
                                                                   Quaternion.AngleAxis(stepAngle, Vector3.up) * Vector3.forward) * spline[i].rotationGlobal;

                            //这个树枝的起始位置
                            float spreadF = MathCore.RandomRange(random, -spread, spread);

                            if (spreadF > 0.0f || i == 0)
                            {
                                branch.centerPos = spline[i].position + spline[i].rotationGlobal * Vector3.up *
                                                   spreadF * height * growRate;
                            }
                            else
                            {
                                branch.centerPos = spline[i].position - spline[i - 1].rotationGlobal * Vector3.up *
                                                   (-spreadF) * height * growRate;
                            }

                            //树叶偏离树枝一点
                            branch.centerPos += branch.rotation * (Vector3.up * 0.7f);

                            //这个树枝的生长率(长度与粗细)
                            float radius = spline[i].radius * (((radEnd - radStart) * ((stepCount - 1) / (float)(steps - 1)) + radStart) + MathCore.RandomRange(random, -radRand, radRand));
                            branch.growRate = radius / branch.radiusRate * crownWidth;

                            //下一个树叶要旋转一下
                            stepAngle += dAngle + MathCore.RandomRange(random, -stepRand, stepRand);
                        }
                    }
                    else
                    {
                        //这是一个树枝
                        branch.branchType = BranchType.Branch;

                        //这个树枝依附于当前结点
                        branch.parentCenterPos = spline[i].position;
                        branch.parentAxis      = spline[i].rotationGlobal * Vector3.up;

                        //这个树枝的起始位置
                        float spreadF = MathCore.RandomRange(random, -spread, spread);

                        //hotfix:如果已经在顶上就往下走
                        if (i == (nodes - 1))
                        {
                            spreadF = MathCore.RandomRange(random, spread - 0.05f, -0.05f);
                        }

                        if (spreadF > 0.0f || i == 0)
                        {
                            branch.centerPos = spline[i].position + spline[i].rotationGlobal * Vector3.up *
                                               spreadF * height * growRate;
                        }
                        else
                        {
                            branch.centerPos = spline[i].position - spline[i - 1].rotationGlobal * Vector3.up *
                                               (-spreadF) * height * growRate;
                        }

                        //这个树枝的旋转
                        float tilt = MathCore.RandomRange(random, -tiltRand, tiltRand) -
                                     (tiltStart - tiltEnd) * ((stepCount - 1) / (float)(steps - 1)) + tiltStart;

                        if (branchType == BranchType.Branch)
                        {
                            stepAngle = stepAngle % 360f;
                            if (stepAngle < 90f || stepAngle > 270f)
                            {
                                stepAngle += 90.0f;
                                stepAngle  = stepAngle % 360.0f;

                                stepAngle  = (stepAngle - 90f) * 0.3f + 90f;
                                stepAngle -= 90.0f;
                            }
                            else
                            {
                                stepAngle = (stepAngle - 180f) * 0.3f + 180f;
                            }
                        }

                        branch.rotation = Quaternion.AngleAxis(tilt,
                                                               Quaternion.AngleAxis(stepAngle, Vector3.up) * Vector3.forward) * spline[i].rotationGlobal;

                        //这个树枝的生长率(长度与粗细)
                        float radius = spline[i].radius * (((radEnd - radStart) * ((stepCount - 1) / (float)(steps - 1)) + radStart) + MathCore.RandomRange(random, -radRand, radRand));
                        branch.growRate = radius / branch.radiusRate * crownWidth;

                        //这个树枝会越来越“细长”
                        branch.height *= ((heightEnd - heightStart) * ((stepCount - 1) / (float)(steps - 1)) + heightStart);

                        //下一个树枝要旋转一下
                        stepAngle += dAngle + MathCore.RandomRange(random, -stepRand, stepRand);

                        if (branchType == BranchType.Branch)
                        {
                            //除了第一级枝干,之后的每一级重力常数都要减小
                            branch.gravityLenthNormalized *= 0.7f;
                            branch.gnarlLenthNormalized    = 6.0f;
                        }
                    }

                    //Check iteration steps
                    branch.iterationStep = iterationStep + 1;
                    branch.startGrowRate = startGrowRate;

                    branch.init();

                    child.Add(branch);
                }

                //交错分布
                overallAngle += (dAngle / 2f) + MathCore.RandomRange(random, -overAllRand, overAllRand) + forceOverall;
            }
        }
Esempio n. 15
0
        public override void Express(
            World world,
            ref FractalRenderState state
            )
        {
            /////////////////////
            //树叶的情况
            /////////////////////

            float leaveRadius = 4.0f * startGrowRate / 24.0f;

            uint blk = branchBlock;

            if (branchType == BranchType.Leaves)
            {
                TestTree.FillLeaf(world, leafRenderingSetup, state.position + state.scale * centerPos, state.scale * Mathf.Min(growRate * 0.31f, 3.0f) * MathCore.RandomRange(random, 3.0f, 5.0f));
                //Debug.Log(growRate);
                //Debug.Log("Using green branch as leaves");
            }
            else
            {
                /////////////////////
                //树枝的情况
                /////////////////////

                /*
                 * 按圆柱表面坐标系上点的坐标给点标号。圆为横轴,高为纵轴。
                 * 顶点(x,y)坐标:
                 *  rad = x * (2f * Mathf.PI / circleFragments);
                 * Vertex =        (cos(rad) * radius, y * heightStep, sin(rad) * radius);
                 * 顶点(x,y)法线:
                 *  rad = x * (2f * Mathf.PI / circleFragments);
                 * Normal =        (cos(rad), 0, sin(rad))
                 * 构成整个子结构的面:
                 *  for(x = 0; x < circleFragments - 1; x++)
                 *      for(y = 0; y < heightFragments - 1; y++)
                 * Indices =               ( x, y ) ( x + 1, y + 1 ) ( x + 1, y ); ( x, y ) ( x , y + 1 ) ( x + 1, y + 1 )
                 *
                 *  不封口。反正也看不见(
                 */

                //绘制
                int   vert = 0, x, index;
                float rad, radiusReal;

                for (index = 0; index < (spline.Count - 1); index++)
                {
                    TestTree.FillCyclinder(
                        world,
                        blk,
                        (state.rotation * (state.scale * spline[index].position)) + state.position,
                        (state.rotation * (state.scale * spline[index + 1].position)) + state.position,
                        state.scale * spline[index].radius,
                        state.scale * spline[index + 1].radius,
                        state.rotation * (spline[index].rotationGlobal * Vector3.up),
                        state.rotation * (spline[index + 1].rotationGlobal * Vector3.up)
                        );
                    //break;
                }
            }

            //state.centerPos = Vector3.zero;
            //state.rotation = Quaternion.identity;
        }
        private async void SubmitData()
        {
            double from, to, approx, divRate = 1;

            if (!double.TryParse(FromXValueBind, out from) || !double.TryParse(ToXValueBind, out to) ||
                !double.TryParse(ApproxValueBind, out approx))
            {
                MessageBox.Show(Locale["#ValuesParseException"], Locale["#RecommendDiffrentArgs"], MessageBoxButton.OK,
                                MessageBoxImage.Error);
                return;
            }
            if (from >= to)
            {
                MessageBox.Show(Locale["#IntervalEndpointsException"], Locale["#RecommendDiffrentArgs"],
                                MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (IsIntervalDivisionEnabled && !double.TryParse(DivisionRateBind, out divRate))
            {
                MessageBox.Show(Locale["#IntervalDivParseException"], Locale["#RecommendDiffrentArgs"],
                                MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            ProgressBarVisibility = (int)divRate != 1 ? Visibility.Visible : Visibility.Collapsed;
            _fromX = from;
            _toX   = to;

            //Add results to the list.
            int noRootsCounter = 0, maxIterCounter = 0, divisionsSuccesses = 0;
            var intervalStep = Math.Abs(from - to) / divRate;
            var roots        = await Task.Run(() =>
            {
                List <FunctionRoot> output = new List <FunctionRoot>();
                for (var i = from; i < to; i += intervalStep)
                {
                    //Prepare argument.
                    var arg = new GetFunctionRootArgs
                    {
                        FromX         = i,
                        ToX           = i + intervalStep,
                        Approx        = approx,
                        MaxIterations = _maxIterations
                    };
                    try
                    {
                        output.Add(MathCore.GetFunctionRootBi(FunctionSelectorSelectedItem, arg));
                        divisionsSuccesses++;
                    }
                    catch (Exception e)
                    {
                        //if this function return true , it means that values on the interval's borders are of the same sign
                        if (CatchFunction(e, ref maxIterCounter, ref noRootsCounter, "Bi"))
                        {
                            continue;
                        }
                    }
                    try
                    {
                        output.Add(MathCore.GetFunctionRootFalsi(FunctionSelectorSelectedItem, arg));
                        divisionsSuccesses++;
                    }
                    catch (Exception e)
                    {
                        CatchFunction(e, ref maxIterCounter, ref noRootsCounter, "Falsi");
                    }
                }
                return(output);
            });

            foreach (var functionRoot in roots)
            {
                RootsCollection.Add(functionRoot);
            }



            if (maxIterCounter > 0 || noRootsCounter > 0)
            {
                MessageBox.Show(Locale["#DividedIntervalRaport"]
                                .Replace("&s1;", divisionsSuccesses.ToString())
                                .Replace("&s2;", maxIterCounter.ToString())
                                .Replace("&s3;", noRootsCounter.ToString()),
                                Locale["#DividedIntervalRaport1"], MessageBoxButton.OK, MessageBoxImage.Information);
            }


            //Update DataGrid's groups definitions.
            RootsView = new ListCollectionView(RootsCollection);

            //Once we are done we can render the chart.
            UpdateChart();
        }