Example #1
0
        public void GenerateTest()
        {
            var rules = new IRule[]
            {
                new RuleMaker()
                {
                    Before = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "a")
                    },
                    After = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "a"),
                        new CalculateObject(new Vector3(1, 1, 1), Quaternion.identity, "b")
                    }
                }.Convert()
            };
            var objs = new VRiscuitObjectSet(new IVRiscuitObject[]
            {
                new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "a"),
                new CalculateObject(new Vector3(0, 0, 1), Quaternion.identity, "a")
            });
            var manager = new RuleManager(objs, rules);
            int i       = 1;

            manager.ApplyRule();
            Debug.Log(string.Format("{0} times Apply: {1}", i++, manager.CurrentObjectSet.ObjectArray.Aggregate("", (str, obj) => str + obj.Position + " ")));

            Assert.That(manager.CurrentObjectSet.Size, Is.EqualTo(4));
        }
Example #2
0
        /// <summary>
        /// </summary>
        /// <param name="before"></param>
        /// <param name="after"></param>
        public VRiscuitRule(IBeforePattern before, IAfterPattern after, ScoreCoefficient sce, bool isDebug = false)
        {
            BeforePattern    = before;
            AfterPattern     = after;
            _coefficient     = sce;
            _beforeObjectSet = BeforePattern.VRiscuitObjects;
            _afterObjectSet  = AfterPattern.ResultObjectSet;
            _genDelTable     = new Dictionary <string, int>(_afterObjectSet.DistributionTable);
            IsDebug          = isDebug;
            foreach (var kvp in _beforeObjectSet.DistributionTable)
            {
                if (_genDelTable.ContainsKey(kvp.Key))
                {
                    _genDelTable[kvp.Key] -= kvp.Value;
                }
                else
                {
                    _genDelTable.Add(kvp.Key, -kvp.Value);
                }
                if (_genDelTable[kvp.Key] != 0)
                {
                    isGenerateOrDeleteObject = true;
                }
            }
            // alphaの値をルールの動き量で決める
            var afterParam = new VRiscuitObjectSet(_afterObjectSet).ToParameters();
            var beforeSet  = new VRiscuitObjectSet(_beforeObjectSet);

            GenerateOrDeleteObject(beforeSet, null);
            var beforeParam = beforeSet.ToParameters();

            _paramLength = TwoArrayDistance(afterParam, beforeParam);
        }
Example #3
0
        public void ChangeObjectTest()
        {
            var rules = new IRule[]
            {
                new RuleMaker()
                {
                    Before = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "a"),
                    },
                    After = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "b")
                    }
                }.Convert()
            };
            var objs = new VRiscuitObjectSet(new IVRiscuitObject[]
            {
                new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "a"),
            });
            var manager = new RuleManager(objs, rules);
            int i       = 1;

            manager.ApplyRule();
            Debug.Log(string.Format("{0} times Apply: {1}", i++, manager.CurrentObjectSet.ObjectArray.Aggregate("", (str, obj) => str + obj.Position + " ")));
            Assert.That(manager.CurrentObjectSet.Size, Is.EqualTo(1));
            Assert.That(manager.CurrentObjectSet.First().Type, Is.EqualTo("b"));
            Assert.That(manager.CurrentObjectSet.First().Position.x, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
            Assert.That(manager.CurrentObjectSet.First().Position.y, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
            Assert.That(manager.CurrentObjectSet.First().Position.z, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
        }
Example #4
0
        public void RotateScoreTest()
        {
            var zero  = new CalculateObject(new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0), "zero");
            var a     = new CalculateObject(new Vector3(0, 0, 0), Quaternion.Euler(0, 30, 0), "a");
            var ten   = new CalculateObject(new Vector3(0, 0, 0), Quaternion.Euler(0, 1, 0), "ten");
            var xten  = new CalculateObject(new Vector3(0, 0, 0), Quaternion.Euler(10, 0, 0), "xten");
            var zmove = new CalculateObject(new Vector3(0, 0, 1), Quaternion.Euler(0, 0, 0), "zmove");
            var xmove = new CalculateObject(new Vector3(1, 0, 0), Quaternion.Euler(0, 0, 0), "xmove");
            Func <CalculateObject, float> ScoreFunc = obj => NormalizeScore(CalcTwoObjectSimilarity(zero, a, zero, obj));
            var zeroScore  = ScoreFunc(zero);
            var aScore     = ScoreFunc(a);
            var tenScore   = ScoreFunc(ten);
            var zmoveScore = ScoreFunc(zmove);
            var xmoveScore = ScoreFunc(xmove);
            var xtenScore  = ScoreFunc(xten);
            Func <CalculateObject, float[]> ParamFunc = obj => CalcTwoObjectSimilarityparameters(zero, a, zero, obj);

            Debug.Log("zero param:" + ArrayToString(ParamFunc(zero)));
            Debug.Log("a param" + ArrayToString(ParamFunc(a)));
            Debug.Log("ten param" + ArrayToString(ParamFunc(ten)));
            Debug.Log("xten param" + ArrayToString(ParamFunc(xten)));
            Debug.Log("zmove param" + ArrayToString(ParamFunc(zmove)));
            Debug.Log("xmove param" + ArrayToString(ParamFunc(xmove)));
            Debug.Log(Angle(zero, a));
            Debug.Log(Angle(zero, ten));
            Debug.Log(Angle(zero, xten));
            Debug.Log(Quaternion.Angle((a as IVRiscuitObject).Rotation, (ten as IVRiscuitObject).Rotation));
            Debug.Log(Quaternion.Angle((a as IVRiscuitObject).Rotation, (xten as IVRiscuitObject).Rotation));
            Debug.Log(Quaternion.Angle((a as IVRiscuitObject).Rotation, Quaternion.Euler(10, 0, 0)));
            Assert.That(tenScore, Is.GreaterThanOrEqualTo(xtenScore).And.LessThan(aScore));
            var test = GenCalObj(-7.777673f, -7.777673f, -7.777673f, -2.319252f, 26.60387f, -2.319252f, "test");

            Debug.Log("Test: " + ScoreFunc(test));
            Debug.Log("param test" + ArrayToString(ParamFunc(test)));
            var test2 = GenCalObj(-7.777673f, -7.777673f, -7.777673f, -2.319252f, 36.60387f, -2.319252f, "test");

            Debug.Log("Test2: " + ScoreFunc(test2));
            Debug.Log("param test2" + ArrayToString(ParamFunc(test2)));
            Func <IVRiscuitObject, float[]> diffFunc = obj =>
            {
                var objset = new VRiscuitObjectSet(new IVRiscuitObject[] { obj });
                var ps     = objset.ToParameters();
                return(Differential(prms => {
                    var objs = new VRiscuitObjectSet(objset);
                    (objs as IVRiscuitObjectSet).SetParameter(prms);
                    return ScoreFunc(objs.First() as CalculateObject);
                }, ps));
            };
            var diff    = diffFunc(test);
            var diffstr = ArrayToString(diff);

            Debug.Log("diff test" + ArrayToString(diffFunc(test)));
            Debug.Log("diff test2" + ArrayToString(diffFunc(test2)));
        }
Example #5
0
        public void CandScoreTest()
        {
            var zero       = new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "zero");
            var one        = new CalculateObject(new Vector3(1, 0, 0), Quaternion.identity, "one");
            var ruleBefore = new VRiscuitObjectSet(new IVRiscuitObject[] { zero, one });
            var case1      = new VRiscuitObjectSet(new IVRiscuitObject[] { zero, one });
            var case2      = new VRiscuitObjectSet(new IVRiscuitObject[] { one, zero });
            var score1     = CalcScore(ruleBefore, case1, new ScoreCoefficient());
            var score2     = CalcScore(ruleBefore, case2, new ScoreCoefficient());
            Func <CalculateObject, CalculateObject, float[]> ParamFunc = (o1, o2) => CalcTwoObjectSimilarityparameters(zero, one, o1, o2);

            LogArray(ParamFunc(zero, one));
            LogArray(ParamFunc(one, zero));
            Assert.That(score1, Is.EqualTo(score2));
        }
Example #6
0
        public void StraightSimpleTest()
        {
            var rules = new IRule[] {
                new RuleMaker()
                {
                    Before = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "Cube")
                    },
                    After = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 1), Quaternion.identity, "Cube")
                    }
                }.Convert()
            };
            var objs    = new VRiscuitObjectSet(new IVRiscuitObject[] { new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "Cube") });
            var manager = new RuleManager(objs, rules);
            int i       = 1;

            ApplyInSec(() => {
                manager.ApplyRule();
                Debug.Log(string.Format("{0}: pos = {1}, rot = {2}", i++, objs.First().Position, objs.First().Rotation));
            });
            var obj = manager.CurrentObjectSet;

            Assert.AreEqual(obj.Size, 1);
            Assert.AreEqual(obj.First().Type, "Cube");
            Assert.AreEqual(obj.First(), objs.First());
            var pos = obj.First().Position;
            var rot = obj.First().Rotation;

            Debug.Log(pos);
            Debug.Log(pos.x);
            Debug.Log(pos.y);
            Assert.That(pos.x, Is.InRange(-0.1f, 0.1f));
            Assert.That(pos.y, Is.InRange(-0.1f, 0.1f));
            Assert.That(pos.z, Is.InRange(-0.9f, 1.1f));
            Assert.That(rot.x, Is.InRange(-0.1f, 0.1f));
            Assert.That(rot.y, Is.InRange(-0.1f, 0.1f));
            Assert.That(rot.z, Is.InRange(-0.1f, 0.1f));
        }
Example #7
0
        /// <summary>
        /// ルールの適用
        /// </summary>
        /// <param name="objectsTable"></param>
        void IRule.Apply(IVRiscuitObjectSet objectsTable, IVRiscuitObjectSet globalTable)
        {
            var beforeTable = new VRiscuitObjectSet(objectsTable);

            GenerateOrDeleteObject(objectsTable, globalTable);
            DescentMethod(objectsTable, beforeTable, _afterObjectSet, _beforeObjectSet);
            // 追加されたオブジェクトをmanagerのobjectSetに追加
            if (_generatedObjects == null)
            {
                return;
            }
            foreach (var obj in _generatedObjects)
            {
                if (IsDebug)
                {
                    globalTable.Add(obj);
                    continue;
                }
            }
            _generatedObjects = null;
        }
Example #8
0
        public void RotateTest()
        {
            var rules = new IRule[]
            {
                new RuleMaker()
                {
                    Before = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "rotate")
                    },
                    After = new IVRiscuitObject[]
                    {
                        new CalculateObject(new Vector3(0, 0, 0), Quaternion.Euler(0, 30, 0), "rotate")
                    }
                }.Convert()
            };
            var objs = new VRiscuitObjectSet(new IVRiscuitObject[]
            {
                new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "rotate")
            });
            var manager = new RuleManager(objs, rules);
            int i       = 1;

            ApplyInSec(() => {
                manager.ApplyRule();
                Debug.Log(string.Format("{0} times Apply: pos = {1}, rot = {2}", i++, objs.First().Position, objs.First().Rotation.eulerAngles));
            });

            var obj = objs.First();

            Assert.That(obj.Position.x, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
            Assert.That(obj.Position.y, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
            Assert.That(obj.Position.z, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
            Assert.That(obj.Rotation.eulerAngles.x, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
            Assert.That(obj.Rotation.eulerAngles.y, Is.GreaterThan(29.0f).And.LessThan(31.0f));
            Assert.That(obj.Rotation.eulerAngles.z, Is.GreaterThan(-0.1f).And.LessThan(0.1f));
        }
Example #9
0
 public void MultiObjectTest()
 {
     var rules = new IRule[]
     {
         new RuleMaker()
         {
             Before = new IVRiscuitObject[]
             {
                 new CalculateObject(Vector3.zero, Quaternion.identity, "a")
             },
             After = new IVRiscuitObject[]
             {
                 new CalculateObject(new Vector3(0, 0, 1), Quaternion.identity, "a")
             }
         }.Convert(),
         new RuleMaker()
         {
             Before = new IVRiscuitObject[]
             {
                 new CalculateObject(Vector3.zero, Quaternion.identity, "a"),
                 new CalculateObject(Vector3.zero, Quaternion.Euler(0, 180, 0), "a")
             },
             After = new IVRiscuitObject[0]
         }.Convert()
     };
     var objs = new VRiscuitObjectSet(new IVRiscuitObject[] {
         new CalculateObject(new Vector3(0, 0, 0), Quaternion.identity, "a"),
         new CalculateObject(new Vector3(0, 1, 0), Quaternion.identity, "a"),
         new CalculateObject(new Vector3(0, 2, 0), Quaternion.identity, "a"),
         new CalculateObject(new Vector3(0, 0, 0), Quaternion.Euler(0, 180, 0), "a"),
         new CalculateObject(new Vector3(0, 1, 0), Quaternion.Euler(0, 180, 0), "a"),
         new CalculateObject(new Vector3(0, 2, 0), Quaternion.Euler(0, 180, 0), "a"),
     });
     var manager = new RuleManager(objs, rules);
     var cands   = manager.GetApplyCandidates();
 }
Example #10
0
        /// <summary>
        /// 最急降下法で最適な位置を計算する
        /// </summary>
        /// <param name="currentTable"></param>
        /// <param name="beforeRuleTable"></param>
        /// <param name="afterRuleTable"></param>
        /// <param name="changes"></param>
        private void DescentMethod(IVRiscuitObjectSet currentTable, IVRiscuitObjectSet beforeTable, IVRiscuitObjectSet afterRuleTable, IVRiscuitObjectSet beforeRuleTable)
        {
            var limit       = 100;
            var beforeScore = 0.0f;
            var beforec     = new VRiscuitObjectSet(beforeTable);
            var currentc    = new VRiscuitObjectSet(currentTable);
            var parameters  = currentc.ToParameters();
            var firstParam  = currentc.ToParameters();
            var beforeDelta = new float[parameters.Length];

            Func <float[], float> func = delegate(float[] param)
            {
                (currentc as IVRiscuitObjectSet).SetParameter(param);
                var scores = RuleManager.CalcAppliedFieldScore(currentc, beforec, afterRuleTable, beforeRuleTable, (this as IRule).RuleScoreCoefficient);
                return(scores[0] / scores[1]);
            };
            var alpha = _paramLength;

            var f = 0.001; // scoreの変動がこの値以下になったら終わり

            for (int i = 0; i < limit; i++)
            {
                var score = func(parameters);
                // var message = String.Format("{0}: {1}, {2}, {3}, {5}, {6}, {7} => {4} points", i, parameters[0], parameters[1], parameters[2], score, parameters[3], parameters[4], parameters[5]);
                //Debug.Log(message);
                // Debug.Log("alpha = " + alpha);
                if (Mathf.Abs(beforeScore - score) <= f && i != 0)
                {
                    // 終了
                    break;
                }
                beforeScore = score;
                var delta = Differential(func, parameters);
                delta = NormalizeArray(delta);

                // deltaの中に0の要素があったら、beforeDeltaをもとに前回の変更を半分もとに戻す
                // その場合次のbeforeDeltaは
                // 同時にbeforeDeltaの更新
                for (int di = 0; di < delta.Length; di++)
                {
                    if (delta[di] == 0)
                    {
                        delta[di]        = -(beforeDelta[di] / 2);
                        beforeDelta[di] /= 2;
                    }
                    else
                    {
                        beforeDelta[di] = delta[di];
                    }
                }

                // Debug.Log("delta = " + delta.Skip(1).Aggregate(delta[0].ToString(), (acc, next) => acc + ", " + next.ToString()));
                for (int j = 0; j < parameters.Length; j++)
                {
                    parameters[j] += delta[j] * alpha;
                }
                // Debug.Log("parameter = " + parameters.Skip(1).Aggregate(parameters[0].ToString(), (acc, next) => acc + ", " + next.ToString()));
                alpha *= Mathf.Max((float)Math.Exp(-alpha), 0.1f);
            }
            // オブジェクトの生成、削除がある場合には、1fで動かす
            // そうでない場合には、1秒かけて動かすように調整する
            if (!isGenerateOrDeleteObject)
            {
                var len = firstParam.Length;
                var d   = new float[len];
                for (int i = 0; i < len; i++)
                {
                    var di = parameters[i] - firstParam[i];
                    // 細かい部分を四捨五入, 秒間スピードに変更
                    di            = ((float)Math.Round(di, 1)) * Time.deltaTime;
                    parameters[i] = firstParam[i] + di;
                }
            }
            currentTable.SetParameter(parameters);
        }
Example #11
0
        public void OnlyLog()
        {
            var objset = new VRiscuitObjectSet(new IVRiscuitObject[] {
                new CalculateObject(Vector3.zero, Quaternion.identity, "a"),
                new CalculateObject(Vector3.zero, Quaternion.identity, "a"),
                new CalculateObject(Vector3.zero, Quaternion.identity, "a"),
                new CalculateObject(Vector3.zero, Quaternion.identity, "a")
            });
            var objs = (objset as IVRiscuitObjectSet).TypeTable["a"];

            objs.RemoveAt(0);
            objs.RemoveAt(0);
            objs.RemoveAt(0);
            Debug.Log(objs.Count);
            Debug.Log((objset as IVRiscuitObjectSet).TypeTable["a"].Count);
            Debug.Log((objset as IVRiscuitObjectSet).Size);

            var lis = new List <int>()
            {
                1, 2, 3, 4, 5
            };

            LogArray(lis.Skip(0));
            LogArray(lis.Skip(1));
            LogArray(lis.Skip(2));
            LogArray(lis.Skip(3));
            LogArray(lis.Skip(4));

            var             q1   = Quaternion.AngleAxis(30, Vector3.right);
            var             q2   = Quaternion.AngleAxis(-30, Vector3.right);
            IVRiscuitObject zero = new CalculateObject(new Vector3(0, 0, 0), Quaternion.Euler(0, 0, 0), "zero");
            IVRiscuitObject one  = new CalculateObject(new Vector3(0, 0, 1), Quaternion.Euler(0, 0, 0), "one");
            IVRiscuitObject yone = new CalculateObject(new Vector3(0, 1, 0), Quaternion.Euler(0, 0, 0), "yone");
            var             a    = GenCalObj(-0.1470235f, -0.1470365f, 0.9444349f, "sample");
            var             f    = ScoreFun(zero as CalculateObject, one as CalculateObject);

            Debug.Log("Best Score: " + f(one as CalculateObject));
            Debug.Log(String.Format("a Score: {0} => {1}", f(a), ArrayToString(CalcTwoObjectSimilarityparameters(zero, one, zero, a))));
            var b = GenCalObj(-0.1470235f, -0.1470365f, 0.9544349f, "sample");

            Debug.Log(String.Format("a Score: {0} => {1}", f(b), ArrayToString(CalcTwoObjectSimilarityparameters(zero, one, zero, b))));
            Debug.Log(yone.Position - zero.Position);
            Debug.Log(zero.Rotation * Vector3.forward);
            Debug.Log(RuleManager.Rdir(zero, one));
            Debug.Log(Delta(0, 100, 10000));
            Debug.Log(Vector3.Angle(Vector3.forward, new Vector3(0, 0, 0)));
            Debug.Log(Vector3.Angle(Vector3.forward, Vector3.back));
            Debug.Log(Quaternion.Angle(Quaternion.Euler(0, 30, 0), Quaternion.Euler(0, 10, 0)));
            Debug.Log(Quaternion.Angle(Quaternion.Euler(0, 30, 0), Quaternion.Euler(10, 0, 0)));
            for (int i = 0; i < 18; i++)
            {
                Debug.Log(Quaternion.Euler(0, 10 * i, 0));
            }
            var beforeR = Quaternion.Euler(10, 10, 10);
            var afterR  = Quaternion.Euler(20, 20, 20);
            var d1      = Quaternion.Inverse(afterR) * beforeR;
            var d2      = Quaternion.Inverse(beforeR) * afterR;
            var d3      = beforeR * Quaternion.Inverse(afterR);
            var d4      = afterR * Quaternion.Inverse(beforeR);
            var current = Quaternion.Euler(0, 0, 0);

            Debug.Log((current * d1).eulerAngles);
            Debug.Log((d1 * current).eulerAngles);
            Debug.Log((current * d2).eulerAngles);
            Debug.Log((d2 * current).eulerAngles);
            Debug.Log((current * d3).eulerAngles);
            Debug.Log((d3 * current).eulerAngles);
            Debug.Log((current * d4).eulerAngles);
            Debug.Log((d4 * current).eulerAngles);
        }