示例#1
0
        private Thing MostLikelyPoint(PointPlus p1, ColorInt theColor)
        {
            Thing retVal = null;

            if (UKSPoints == null)
            {
                return(null);
            }
            Angle closestTheta = Rad(180);

            foreach (Thing t in UKSPoints)
            {
                if (t.ReferencedBy.Count > 0)
                {
                    Segment s = SegmentFromUKSThing(t.ReferencedBy[0].T);
                    if (s == null)
                    {
                        continue;
                    }
                    if (s.theColor == theColor)
                    {
                        if (t.V is PointPlus p)
                        {
                            Angle deltaAngle = Abs(p.Theta - p1.Theta);
                            if (deltaAngle < closestTheta)
                            {
                                closestTheta = deltaAngle;
                                retVal       = t;
                            }
                        }
                    }
                }
            }
            return(retVal);
        }
示例#2
0
        //this is asking can the entity directly see a target object or are there obstacles
        public PointPlus CanISGoStraightTo(PointPlus midPoint, out Segment obstacle)
        {
            obstacle = null;
            float      closestDistance = 100;
            ModuleUKSN UKS             = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            if (UKS == null)
            {
                return(null);
            }
            bool ok = true;

            foreach (Thing t in UKSSegments)
            {
                Segment s = SegmentFromUKSThing(t);
                Utils.FindIntersection(new Point(0, 0), midPoint.P, s.P1.P, s.P2.P,
                                       out bool lines_intersect, out bool segments_intersect,
                                       out Point intersection, out Point close_p1, out Point closep2, out double collisionAngle);
                if (segments_intersect)
                {
                    ok = false;
                    Utils.FindDistanceToSegment(new Point(0, 0), s.P1.P, s.P1.P, out Point closest);
                    if (((Vector)closest).Length < closestDistance)
                    {
                        closestDistance = (float)((Vector)closest).Length;
                        obstacle        = s;
                    }
                }
            }
            if (ok)
            {
                return(midPoint);
            }
            return(null);
        }
示例#3
0
        private void CorrectModelPosition(Module2DModel nmModel, ModuleBehavior nmBehavior, Thing best, List <Thing> near)
        {
            //locations are not very accurate and accumulate errors
            //whenever we encounter a landmark, we update the orientation/location of the model to correct errors
            Segment s2 = Module2DModel.SegmentFromUKSThing(near[0]);
            Segment s1 = null;

            foreach (Link l in best.References)
            {
                Segment s = Module2DModel.SegmentFromUKSThing(l.T);
                if (s.theColor == s2.theColor)
                {
                    s1 = s; break;
                }
            }
            if (s1 != null)
            {
                PointPlus m1     = s1.MidPoint;
                PointPlus m2     = s2.MidPoint;
                float     deltaX = m1.X - m2.X;
                float     deltaY = m1.Y - m2.Y;
                PointPlus a1     = new PointPlus()
                {
                    P = (Point)(s1.P1.V - s1.P2.V)
                };
                PointPlus a2 = new PointPlus()
                {
                    P = (Point)(s2.P1.V - s2.P2.V)
                };
                Angle deltaTheta = a1.Theta - a2.Theta;
                nmModel.Move(-deltaX, -deltaY);
                nmBehavior.TurnTo(deltaTheta);
            }
        }
示例#4
0
        //TODO add more properties to Stroke
        public Thing AddStrokeToUKS(PointPlus P1, PointPlus P2)
        {
            ModuleUKS uks = (ModuleUKS)FindModuleByType(typeof(ModuleUKS));

            if (uks is ModuleUKS UKS)
            {
                if (uks.Labeled("AbsStroke") == null)
                {
                    uks.AddThing("AbsStroke", "Visual");
                }
                Thing t1 = uks.Valued(P1);
                if (t1 == null)
                {
                    t1 = UKS.AddThing("p" + pCount++, new Thing[] { UKS.Labeled("Point") }, P1);
                }
                Thing t2 = uks.Valued(P2);
                if (t2 == null)
                {
                    t2 = UKS.AddThing("p" + pCount++, new Thing[] { UKS.Labeled("Point") }, P2);
                }
                Thing newThing = UKS.AddThing("s" + strokeCount++, new Thing[] { UKS.Labeled("AbsStroke") }, null, new Thing[] { t1, t2 });
                return(newThing);
            }
            return(null);
        }
示例#5
0
        //for debugging it is handy to bypass the exploration to establish the internal model...just set it
        public void SetModel()
        {
            MainWindow.SuspendEngine();
            Initialize();
            Module2DModel nmModel = (Module2DModel)FindModuleByType(typeof(Module2DModel));

            if (nmModel == null)
            {
                return;
            }
            //clear out any existing
            nmModel.Initialize();

            for (int i = 0; i < objects.Count; i++)
            {
                PointPlus P1 = new PointPlus()
                {
                    P = objects[i].P1
                };
                PointPlus P2 = new PointPlus()
                {
                    P = objects[i].P2
                };
                int theColor = Utils.ColorToInt(objects[i].theColor);
                nmModel.AddSegmentFromVision(P1, P2, theColor, false);
            }
            MainWindow.ResumeEngine();
        }
示例#6
0
        private void FindBinocularBoundaries()
        {
            boundaries.Clear();
            int start = 0;

            for (int i = 0; i < LBoundaries.Count; i++)
            {
                for (int j = start; j < RBoundaries.Count; j++)
                {
                    ColorInt cLL = LBoundaries[i].colorL;
                    ColorInt cLR = LBoundaries[i].colorR;
                    ColorInt cRL = RBoundaries[j].colorL;
                    ColorInt cRR = RBoundaries[j].colorR;
                    if (cLL == cRL || cLR == cRR)
                    {
                        //find distance and error
                        int       l1             = LBoundaries[i].direction;
                        int       r1             = RBoundaries[j].direction;
                        PointPlus leftPoint      = FindDepth(l1, r1);
                        PointPlus leftPointError = FindDepth(l1 - 1, r1);
                        float     error          = leftPointError.R - leftPoint.R;
                        if (error < 0)
                        {
                            break;
                        }
                        leftPoint.Conf = error;

                        PointPlus pp = new PointPlus()
                        {
                            R = leftPoint.R, Theta = leftPoint.Theta, Conf = leftPoint.Conf
                        };
                        //if both sides of the point match...this creates two boundaries, one for each color
                        if (cLL == cRL)
                        {
                            BinocularBoundary bb = new BinocularBoundary()
                            {
                                p        = leftPoint,
                                theColor = cLL,
                                changed  = LBoundaries[i].changed,
                            };
                            boundaries.Add(bb);
                        }
                        if (cLR == cRR)
                        {
                            BinocularBoundary bb = new BinocularBoundary()
                            {
                                p        = pp,
                                theColor = cLR,
                                changed  = LBoundaries[i].changed,
                            };
                            boundaries.Add(bb);
                        }
                        start = j;
                        break;
                    }
                }
            }
        }
        void MoveTo(PointPlus target, float offset)
        {
            ModuleBehavior mBehavior = (ModuleBehavior)FindModleu(typeof(ModuleBehavior));

            target.X -= offset; //body radius
            mBehavior.TurnTo(-target.Theta);
            mBehavior.MoveTo(target.R);
            mBehavior.TurnTo(target.Theta); //return to previous orientation
        }
        void DoFaceSegment(Segment s)
        {
            ModuleBehavior mBehavior = (ModuleBehavior)FindModleu(typeof(ModuleBehavior));

            Utils.FindDistanceToSegment(s, out Point closest);
            PointPlus closestPP = new PointPlus {
                P = closest
            };

            mBehavior.TurnTo(-closestPP.Theta);
        }
        void Push(Segment s)
        {
            ModuleBehavior mBehavior = (ModuleBehavior)FindModleu(typeof(ModuleBehavior));
            float          dist      = (float)Utils.FindDistanceToSegment(s, out Point closest);
            PointPlus      closestPP = new PointPlus {
                P = closest
            };

            mBehavior.TurnTo(-closestPP.Theta);
            mBehavior.MoveTo(closestPP.R - .1f);
        }
示例#10
0
        //maintain a list of objects in the current visual field
        public void FireVisibleObjects()
        {
            ModuleView naUKS = theNeuronArray.FindAreaByLabel("Module2DUKS");

            if (naUKS == null)
            {
                return;
            }
            ModuleUKSN UKS = (ModuleUKSN)naUKS.TheModule;

            if (UKSSegments == null)
            {
                return;
            }
            //Thing tVisible = UKS.Labeled("Visible");

            //clear all visiblility references
            //for (int i = 0; i < UKSSegments.Count; i++)
            //    UKSSegments[i].RemoveReference(tVisible);

            ModuleView naVision = theNeuronArray.FindAreaByLabel("Module2DVision");

            if (naVision == null)
            {
                return;
            }
            int   possibleViewAngles = naVision.Width;
            float deltaTheta         = Module2DVision.fieldOfView / possibleViewAngles;

            for (int i = 0; i < possibleViewAngles; i++)
            {
                float     theta = (float)-Module2DVision.fieldOfView / 2 + (i * deltaTheta);
                PointPlus P     = new PointPlus {
                    R = 10, Theta = theta
                };
                foreach (Thing t in UKSSegments)
                {
                    Segment s = SegmentFromUKSThing(t);
                    if (s == null)
                    {
                        continue;
                    }
                    Utils.FindIntersection(new Point(0, 0), P.P, s.P1.P, s.P2.P,
                                           out bool lines_intersect, out bool segments_intersect,
                                           out Point intersection, out Point close_p1, out Point closep2, out double collisionAngle);
                    if (segments_intersect)
                    {
                        //TODO...only fire the closest at each point
                        UKS.Fire(t);
                        //                        t.AddReference(tVisible);
                    }
                }
            }
        }
示例#11
0
        void DoBackOff(Segment s)
        {
            ModuleBehavior mBehavior = (ModuleBehavior)FindModleu(typeof(ModuleBehavior));
            PointPlus      target    = new PointPlus(s.MidPoint + new PointPlus {
                R = 2f, Theta = s.Angle - PI / 2
            });

            mBehavior.TurnTo(-target.Theta);
            mBehavior.MoveTo(target.R);
            mBehavior.TurnTo(target.Theta); //return to previous orientation
        }
示例#12
0
        private PointPlus FindDepth(int l, int r)
        {
            //calculation using trig
            Angle thetaA = GetDirectionFromNeuron(r - 0.5f, na.Width);

            thetaA = PI / 2 - thetaA; //get angle to axis
            Angle thetaB = GetDirectionFromNeuron(l - 0.5f, na.Width);

            thetaB = PI / 2 - thetaB;
            thetaB = PI - thetaB; //to get an inside angle
            Angle  thetaC = PI - thetaA - thetaB;
            double A      = Sin(thetaA) * (2 * eyeOffset) / Sin(thetaC);

            thetaA -= PI / 2;
            PointPlus P = new PointPlus {
                Theta = (float)-thetaA, R = (float)A
            };                //relative to left eye

            P.Y -= eyeOffset; //correct to be centered between eyes

            //alternate using vectors
            PointPlus p1L = new PointPlus()
            {
                Y = -eyeOffset, X = 0
            };
            PointPlus p1R = new PointPlus()
            {
                Y = +eyeOffset, X = 0
            };
            Angle     thetaL = (float)GetDirectionFromNeuron(r, na.Width);
            PointPlus p2L    = new PointPlus()
            {
                R = 20, Theta = thetaL
            };

            p2L.P = p2L.P + (Vector)p1L.P;

            Angle     thetaR = (float)GetDirectionFromNeuron(l, na.Width);
            PointPlus p2R    = new PointPlus()
            {
                R = 20, Theta = thetaR
            };

            p2R.P = p2R.P + (Vector)p1R.P;

            Utils.FindIntersection(p1L.P, p2L.P, p1R.P, p2R.P, out bool lines_intersect, out bool segments_intersect, out Point intersection, out Point clost_p1, out Point close_p2, out double collisionAngle);
            PointPlus retVal = new PointPlus()
            {
                P = intersection
            };

            return(retVal);
        }
示例#13
0
        private bool InRange(PointPlus p, float rangeAhead)
        {
            bool retVal = false;

            if (p.X <= 0)
            {
                return(retVal);
            }
            if (p.Y > -rangeAhead && p.Y < rangeAhead)
            {
                retVal = true;
            }
            return(retVal);
        }
示例#14
0
        void GoToLandmark(Thing landmark, Segment s)
        {
            Segment s1 = Module2DModel.SegmentFromUKSThing(landmark.References[0].T);

            Module2DModel.OrderSegment(s1);
            float     ratio  = s1.P1.R / (s1.Length);
            PointPlus target = new PointPlus
            {
                X = s.P1.X + (s.P2.X - s.P1.X) * ratio,
                Y = s.P1.Y + (s.P2.Y - s.P1.Y) * ratio,
            };

            MoveTo(target, .2f);
        }
示例#15
0
        private void Explore(Segment s)
        {
            switch (state)
            {
            case 0:     //go to midpoint
            {
                PointPlus target = s.MidPoint;
                MoveTo(target, .2f);
                doPush    = 2;
                doBackOff = true;
                state++;
                break;
            }

            case 1:     //goto 1st turnpoint
            {
                Point     p1     = s.MidPoint.P;
                Point     p2     = s.P1.P;
                PointPlus target = new PointPlus {
                    X = (float)(p1.X + p2.X) / 2, Y = (float)(p1.Y + p2.Y) / 2
                };
                MoveTo(target, .2f);
                doPush    = 2;
                doBackOff = true;
                state++;
                break;
            }

            case 2:     //goto second turnpoint
            {
                Point     p1      = s.MidPoint.P;
                Point     p2      = s.P2.P;
                PointPlus target2 = new PointPlus {
                    X = (float)(p1.X + p2.X) / 2, Y = (float)(p1.Y + p2.Y) / 2
                };
                MoveTo(target2, .22f);
                doPush    = 2;
                doBackOff = true;
                state++;
                break;
            }

            case 3:    //face midpoint
            {
                FaceMidPoint(s);
                state++;
                break;
            }
            }
        }
示例#16
0
 public void ImagineStart(PointPlus offset, float direction)
 {
     imagining = true;
     if (imaginationOffset != null)
     {
         ImagineEnd();
     }
     imagining            = true;
     imaginationOffset    = offset;
     imaginationDirection = direction;
     Rotate((float)-offset.Theta);
     Move((float)offset.R);
     Rotate((float)(direction - offset.Theta));
     UpdateDialog();
 }
示例#17
0
 public void ImagineEnd()
 {
     if (!imagining)
     {
         return;
     }
     ClearImagination();
     Rotate((float)(-imaginationDirection + imaginationOffset.Theta));
     Move((float)-imaginationOffset.R);
     Rotate((float)imaginationOffset.Theta);
     imaginationDirection = 0;
     imaginationOffset    = null;
     imagining            = false;
     UpdateDialog();
 }
示例#18
0
        private static void MovePhysObject(physObject ph, Point closest, PointPlus motion)
        {
            ph.P1 = ph.P1 + motion.V;
            ph.P2 = ph.P2 + motion.V;

            //handle rotation if object not hit in the middle
            //we know that our point "closest" moves with "motion"...rotation should be about "closest"
            Segment s = new Segment
            {
                P1 = new PointPlus()
                {
                    P = ph.P1
                },
                P2 = new PointPlus()
                {
                    P = ph.P2
                }
            };
            PointPlus contactPoint = new PointPlus()
            {
                P = closest
            };
            PointPlus offset = new PointPlus()
            {
                P = (Point)(contactPoint.V - s.MidPoint.V)
            };

            double cross = Vector.CrossProduct(offset.V, motion.V);

            float rotation = 10 * Sign(cross);

            float rotationRatio = (float)(offset.V.Length / s.Length * 2);

            PointPlus V1 = new PointPlus()
            {
                P = (Point)(s.P1.P - contactPoint.P)
            };
            PointPlus V2 = new PointPlus()
            {
                P = (Point)(s.P2.P - contactPoint.P)
            };

            V1.Theta += Rad(rotation * rotationRatio);
            V2.Theta += Rad(rotation * rotationRatio);

            ph.P1 = (Point)V1.V + contactPoint.V;
            ph.P2 = (Point)V2.V + contactPoint.V;
        }
示例#19
0
        public void UpdateEndpointFromVision(PointPlus P1, ColorInt theColor, bool moved)
        {
            //Debug.WriteLine("UpdatePoint: " + P1 + theColor);
            Thing match = MostLikelyPoint(P1, theColor);

            if (match != null)
            {
                if (match.V is PointPlus p)
                {
                    if (P1.Conf < p.Conf || moved)
                    {
                        match.V = P1;
                    }
                }
                UpdateDialog();
            }
        }
示例#20
0
 public static void OrderSegment(object x)
 {
     if (x is Thing t)
     {
         if (((PointPlus)t.References[0].T.V).Theta > ((PointPlus)t.References[1].T.V).Theta)
         {
             Link temp = t.References[0]; t.References[0] = t.References[1]; t.References[1] = temp;
         }
     }
     if (x is Segment s)
     {
         if (s.P1.Theta > s.P2.Theta)
         {
             PointPlus temp = s.P1; s.P1 = s.P2; s.P2 = temp;
         }
     }
 }
示例#21
0
        //not used but may be useful elsewhere.
        Segment NextPosition(Segment s, Motion m)
        {
            PointPlus oldMidPoint = s.MidPoint;
            PointPlus newMidPoint = oldMidPoint + m;
            PointPlus dP1         = s.P1 - oldMidPoint;
            PointPlus dP2         = s.P2 - oldMidPoint;

            dP1.Theta += m.rotation;
            dP2.Theta += m.rotation;
            Segment retVal = new Segment()
            {
                P1       = newMidPoint + dP1,
                P2       = newMidPoint + dP2,
                theColor = s.theColor,
            };

            return(retVal);
        }
示例#22
0
 //touch is the intersection of an arm with an obstacle
 public void HandleTouch()
 {
     //arm[0] is left [1] is right
     armActual = new Point[armRelative.Length];
     //is there an object intersecting the arm?
     for (int i = 0; i < armRelative.Length; i++)
     {
         PointPlus pv = new PointPlus {
             P = (Point)armRelative[i]
         };
         pv.Theta = entityDirection1 + pv.Theta;
         Point armPositionAbs = entityPosition + (Vector)pv.P;
         HandleTouch(armPositionAbs, i);
     }
     motion = new PointPlus()
     {
         R = 0, Theta = 0
     };
 }
示例#23
0
        private void CreateCenteredStroke(Segment0 s1, Segment0 s2)
        {
            PointPlus p1 = new PointPlus(s1.p1);
            PointPlus p2 = new PointPlus(s1.p2);
            PointPlus p3 = new PointPlus(s2.p1);
            PointPlus p4 = new PointPlus(s2.p2);

            //transfer first point to origin
            PointPlus p10 = p1 - p1;
            PointPlus p20 = p2 - p1;
            PointPlus p30 = p3 - p1;
            PointPlus p40 = p4 - p1;

            //rotate so both segments are horizontal.
            Angle     a    = p20.Theta;
            PointPlus p10r = p10; p10r.Theta -= a;
            PointPlus p20r = p20; p20r.Theta -= a;
            PointPlus p30r = p30; p30r.Theta -= a;
            PointPlus p40r = p40; p40r.Theta -= a;
            double    minX = Min(new double[] { p10r.X, p20r.X, p30r.X, p40r.X });
            double    maxX = Max(new double[] { p10r.X, p20r.X, p30r.X, p40r.X });
            double    y    = (p30r.Y + p40r.Y) / 2;
            PointPlus pa   = new PointPlus((float)minX, (float)y / 2);
            PointPlus pb   = new PointPlus((float)maxX, (float)y / 2);

            pa.Theta += a;
            pb.Theta += a;
            pa        = pa + p1;
            pb        = pb + p1;

            Stroke theStroke = new Stroke
            {
                width = (float)y,
                p1    = pa.P,
                p2    = pb.P,
            };

            strokes.Add(theStroke);
        }
示例#24
0
        private void TheCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            Module2DSim parent = (Module2DSim)base.ParentModule;

            Point windowSize   = new Point(theCanvas.ActualWidth, theCanvas.ActualHeight);
            Point windowCenter = new Point(windowSize.X / 2, windowSize.Y / 2);
            float scale        = (float)Math.Min(windowSize.X, windowSize.Y) / 12;


            Point position = e.GetPosition(theCanvas);

            PointPlus v = new PointPlus {
                P = (Point)(position - parent.entityPosition)
            };
            float      dist       = (float)v.R;
            double     angle      = (float)v.Theta;
            double     deltaAngle = angle - parent.entityDirection1;
            ModuleView naGoToDest = MainWindow.theNeuronArray.FindAreaByLabel("ModuleGoToDest");

            if (naGoToDest != null)
            {
                naGoToDest.GetNeuronAt("Go").SetValue(1);
                naGoToDest.GetNeuronAt("Theta").SetValue((float)deltaAngle);
                naGoToDest.GetNeuronAt("R").SetValue(dist);
            }
            else
            {
                ModuleView naBehavior = MainWindow.theNeuronArray.FindAreaByLabel("ModuleBehavior");
                if (naBehavior != null)
                {
                    naBehavior.GetNeuronAt("TurnTo").SetValue(1);
                    naBehavior.GetNeuronAt("Theta").SetValue((float)-deltaAngle);
                    naBehavior.GetNeuronAt("MoveTo").SetValue(1);
                    naBehavior.GetNeuronAt("R").SetValue(dist);
                }
            }
        }
示例#25
0
        public Thing AddSegmentToUKS(PointPlus P1, PointPlus P2, int theColor, PointPlus motion = null, bool addToModel = true)
        {
            ModuleUKS nmUKS = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            if (nmUKS is ModuleUKS UKS)
            {
                Thing t1, t2;
                Thing t3 = null;
                t1 = UKS.AddThing("p" + pCount++, new Thing[] { UKS.Labeled("Point") }, P1);
                t2 = UKS.AddThing("p" + pCount++, new Thing[] { UKS.Labeled("Point") }, P2);
                if (addToModel)
                {
                    t1.AddParent(UKS.Labeled("ModelThing"));
                    t2.AddParent(UKS.Labeled("ModelThing"));
                }
                if (motion != null)
                {
                    t3 = UKS.AddThing("m" + mCount++, new Thing[] { UKS.Labeled("Motion") }, motion);
                }
                Thing color = UKS.Valued(theColor);
                if (color == null)
                {
                    color = UKS.AddThing("c" + cCount++, new Thing[] { UKS.Labeled("Color") }, theColor);
                }
                Thing newThing = null;
                if (motion != null)
                {
                    newThing = UKS.AddThing("s" + sCount++, new Thing[] { UKS.Labeled("Segment") }, null, new Thing[] { t1, t2, color, t3 });
                }
                else
                {
                    newThing = UKS.AddThing("s" + sCount++, new Thing[] { UKS.Labeled("Segment") }, null, new Thing[] { t1, t2, color });
                }
                return(newThing);
            }
            return(null);
        }
示例#26
0
        List <PointPlus> GetListFromShape(Thing theShape)
        {
            List <PointPlus> retVal = new List <PointPlus>();

            if (!theShape.Label.Contains("Shape"))
            {
                return(retVal);
            }
            if (theShape.Children.Count == 0)
            {
                return(retVal);
            }

            Thing firstCorner = theShape.Children[0];
            Thing curCorner   = theShape.Children[0];

            do
            { //TODO what if the references are out of order?
                Thing theAngle = curCorner.References[0].T;

                Link l = curCorner.References[1];
                if (l is Relationship r)
                {
                    Thing theLength = r.relationshipType;
                    float.TryParse(theAngle.Label.Substring(3), out float theAngle1);
                    float.TryParse(theLength.Label.Substring(3), out float theLength1);

                    PointPlus pp = new PointPlus {
                        R = theLength1, Theta = Angle.FromDegrees(theAngle1)
                    };
                    retVal.Add(pp);
                }
                curCorner = curCorner.References[1].T;
            } while (curCorner != firstCorner);

            return(retVal);
        }
示例#27
0
        public Thing GetNearestThing(Angle theta, out float dist)
        {
            Thing nearest = null;

            dist = float.MaxValue;
            Segment s = null;

            foreach (Thing t in UKSSegments)
            {
                s = SegmentFromUKSThing(t);
                //OrderSegment(s);

                //does this object cross the given visual angle?
                PointPlus pv = new PointPlus {
                    R = 10, Theta = theta
                };
                Utils.FindIntersection(new Point(-.2, 0), pv.P, s.P1.P, s.P2.P,
                                       out bool lines_intersect, out bool segments_intersect, out Point intersection, out Point clos_p1, out Point close_p2, out double collisionAngle);
                if (!segments_intersect)
                {
                    continue;
                }
                //and is it the nearest?
                Vector v = (Vector)intersection;
                if (v.Length < dist)
                {
                    nearest = t;
                    dist    = (float)v.Length;
                }
            }
            if (nearest != null)
            {
                return(nearest);
            }
            return(null);
        }
示例#28
0
        public override void Fire()
        {
            Init();  //be sure to leave this here to enable use of the na variable
            Module2DModel naModel = (Module2DModel)FindModuleByType(typeof(Module2DModel));

            if (naModel == null)
            {
                return;
            }

            for (int i = 0; i < na.Height; i++)
            {
                //neurons:  0:touch   1:antAngle  2:antDistance 3: sensedLineAngle 4: conf1 5: len1 6: conf2 7: len2 8: touch-ended 9: modelchanged
                if (na.GetNeuronAt(0, i).CurrentCharge == 0)
                {
                    continue;
                }
                float antDist   = na.GetNeuronAt(1, i).CurrentCharge;
                float antAngle  = na.GetNeuronAt(2, i).CurrentCharge;
                float lineAngle = na.GetNeuronAt(3, i).CurrentCharge;
                float p1IsEndpt = na.GetNeuronAt(4, i).CurrentCharge;
                float l1        = na.GetNeuronAt(5, i).CurrentCharge;
                float p2IsEndpt = na.GetNeuronAt(6, i).CurrentCharge;
                float l2        = na.GetNeuronAt(7, i).CurrentCharge;
                float mR        = na.GetNeuronAt(9, i).CurrentCharge;
                float mTheta    = na.GetNeuronAt(10, i).CurrentCharge;
                float mPhi      = na.GetNeuronAt(11, i).CurrentCharge;

                PointPlus motion = new PointPlus()
                {
                    R = mR, Theta = mTheta, Conf = mPhi
                };
                //create the line segment (all coordinates relative to self)
                PointPlus antennaPos = new PointPlus()
                {
                    R = antDist, Theta = antAngle
                };

                float lineAngleAbs = antAngle - lineAngle;

                PointPlus pv1 = new PointPlus()
                {
                    R = l1, Theta = (float)Math.PI + lineAngleAbs
                };
                PointPlus pv2 = new PointPlus()
                {
                    R = l2, Theta = lineAngleAbs
                };

                Point     P1  = antennaPos.P + pv1.V;
                Point     P2  = antennaPos.P + pv2.V;
                PointPlus P1P = new PointPlus()
                {
                    P = P1, Conf = 1 - p1IsEndpt
                };
                PointPlus P2P = new PointPlus()
                {
                    P = P2, Conf = 1 - p2IsEndpt
                };

                bool modelChanged = naModel.AddSegmentFromTouch(P1P, P2P, motion, i);
            }
        }
示例#29
0
        //TODO: rewrite again
        public Thing AddSegmentFromVision(PointPlus P1, PointPlus P2, ColorInt theColor, bool moved)
        {
            Thing retVal = null;

            Debug.WriteLine("AddSegment: " + P1 + P2 + theColor);
            //determine if the segment is already in the UKS.
            //Correct it if it is there, add it if it is not.
            //FUTURE: detect motion
            if (theColor == 0)
            {
                return(null);
            }
            Segment newSegment = new Segment()
            {
                P1 = P1, P2 = P2, theColor = theColor
            };
            ModuleUKSN UKS = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            GetSegmentsFromUKS();
            if (UKS != null)
            {
                //it's easier if we sort by theta
                OrderSegment(newSegment);
                retVal = MostLikelySegment(newSegment);
                if (retVal != null)
                {
                    //UKS.Fire(match);
                    //OrderSegment(match);
                    //Segment s = SegmentFromUKSThing(match);
                    //float newVisualWidth = newSegment.VisualWidth();
                    //float matchVisualWidth = s.VisualWidth();
                    ////if the newVisualWidth is bigger, an adjustment is needed
                    ////this happens if the initial view was occluded but now it is less
                    //Thing match1 = MostLikelyPoint(newSegment.P1, newSegment.theColor);
                    //Thing match2 = MostLikelyPoint(newSegment.P2, newSegment.theColor);
                    //if (match1 != null && match2 != null)
                    //{
                    //    if (newSegment.P1.Conf < s.P1.Conf)
                    //    {
                    //        s.P1.Conf = newSegment.P1.Conf;
                    //        s.P1.R = newSegment.P1.R;
                    //        s.P1.Theta = newSegment.P1.Theta;
                    //    }
                    //    if (newSegment.P2.Conf < s
                    //        .P2.Conf)
                    //    {
                    //        s.P2.Conf = newSegment.P2.Conf;
                    //        s.P2.R = newSegment.P2.R;
                    //        s.P2.Theta = newSegment.P2.Theta;
                    //    }
                    //}

                    ////there is a significant point mismatch...
                    //else
                    //{
                    //    if (match1 == null && newSegment.P1.R > s.P1.R)
                    //    {
                    //        s.P1.Conf = newSegment.P1.Conf;
                    //        s.P1.R = newSegment.P1.R;
                    //        s.P1.Theta = newSegment.P1.Theta;
                    //    }
                    //    if (match2 == null && newSegment.P2.R > s.P2.R)
                    //    {
                    //        s.P2.Conf = newSegment.P2.Conf;
                    //        s.P2.R = newSegment.P2.R;
                    //        s.P2.Theta = newSegment.P2.Theta;
                    //    }
                    //}
                }
                else
                {
                    retVal = AddSegmentToUKS(P1, P2, theColor);
                    UKS.Fire(retVal);
                }
                UpdateDialog();
            }
            return(retVal);
        }
示例#30
0
        //get input from touch... accurate locations, no color
        public bool AddSegmentFromTouch(PointPlus P1, PointPlus P2, PointPlus motion, int arm)
        {
            //if conf=0, it's a known endpoint. conf=1, not an endpoint
            ModuleUKSN UKS = (ModuleUKSN)FindModuleByType(typeof(ModuleUKSN));

            if (UKS is null)
            {
                return(false);
            }
            if (UKSSegments is null)
            {
                return(false);
            }
            if (imagining)
            {
                return(false);
            }

            ColorInt theColor   = Utils.ColorToInt(Colors.Wheat);
            Segment  newSegment = new Segment()
            {
                P1 = P1, P2 = P2, theColor = theColor
            };
            //OrderSegment(newSegment);

            Thing t1 = GetNearestThing(newSegment.MidPoint.Theta, out float dist1);

            //TODO: for motion testing
            t1 = UKS.Labeled("s0");
            if (t1 == null)
            {
                //TODO: merge mutliple segments
                //                AddSegmentToUKS(P1, P2, theColor, motion); //don't store motion with the segment (yet)
                AddSegmentToUKS(P1, P2, theColor);
            }

            else if (dist1 < 1)
            {
                Segment   prevSegment  = SegmentFromUKSThing(t1);
                PointPlus prevMidpoint = prevSegment.MidPoint;
                Angle     oldM         = prevSegment.Angle;
                Angle     newM         = newSegment.Angle;
                PointPlus offset       = new PointPlus()
                {
                    R = prevSegment.Length, Theta = newM
                };
                if (P1.Conf == 0 && P2.Conf == 0) //we're given both endpoints
                {
                    prevSegment.P1.P = P1.P; prevSegment.P1.Conf = 0;
                    prevSegment.P2.P = P2.P; prevSegment.P2.Conf = 0;
                }
                else if (P1.Conf == 0)
                {
                    prevSegment.P1.P = P1.P; prevSegment.P1.Conf = 0;
                    prevSegment.P2.P = P1.P - offset.V;
                }
                else if (P2.Conf == 0)
                {
                    prevSegment.P1.P = P2.P; prevSegment.P2.Conf = 0;
                    prevSegment.P2.P = P2.P + offset.V;
                }
                else
                {
                    //we're not near an endpoint--match the modpoint as close as possible & preserve length
                    //make the segment match the two points
                    PointPlus newMidpoint1 = new PointPlus()
                    {
                        P = (Point)GetClosestPointOnLine(P1.V, P2.V, prevMidpoint.V),
                    };
                    //offset is the dietance from the midpoint to each end
                    offset.R = offset.R / 2;
                    PointPlus newP1 = new PointPlus()
                    {
                        P = newMidpoint1.P + offset.V
                    };
                    PointPlus newP2 = new PointPlus()
                    {
                        P = newMidpoint1.P - offset.V
                    };
                    prevSegment.P1.R = newP1.R; prevSegment.P1.Theta = newP1.Theta;
                    prevSegment.P2.R = newP2.R; prevSegment.P2.Theta = newP2.Theta;
                }
                PointPlus newMidpoint = prevSegment.MidPoint;
                newMidpoint.P = newMidpoint.P - prevMidpoint.V;
                if (newMidpoint.R > 0.01 && motion.R != 0)
                {
                    if (prevSegment.Motion == null)
                    {
                        prevSegment.Motion = new PointPlus();
                        Thing tMotion = UKS.AddThing("m" + mCount++, UKS.Labeled("Point"));
                        tMotion.V = prevSegment.Motion;
                        t1.AddReference(tMotion);
                    }
                    prevSegment.Motion.R     = motion.R;
                    prevSegment.Motion.Theta = motion.Theta;
                    prevSegment.Motion.Conf  = newM - oldM;
                }
            }

            UpdateDialog();
            return(false);
        }