/// <summary> /// Constructs a new Wall object by copying an existing Wall. /// </summary> public Wall(Wall otherWall) { Name = otherWall.Name; Colored = false; Line = new Line2D(otherWall.Line); //set center point Location = Line.midpoint(); Dynamic = false; Visible = otherWall.Visible; }
/// <summary> /// Constructs a new Wall object from scratch /// </summary> /// <param name="nx1">X component of endpoint 1</param> /// <param name="ny1">Y component of endpoint 1</param> /// <param name="nx2">X component of endpoint 2</param> /// <param name="ny2">Y component of endpoint 2</param> /// <param name="vis">Is the wall visible?</param> /// <param name="n">Wall name</param> public Wall(double nx1, double ny1, double nx2, double ny2, bool vis, string n) { Name = n; Colored = false; Point2D p1 = new Point2D(nx1, ny1); Point2D p2 = new Point2D(nx2, ny2); Line = new Line2D(p1, p2); //set center point Location = Line.midpoint(); Dynamic = false; Visible = vis; }
/// <summary> /// Casts a ray from the robot's center point according to the specified Angle and returns the Distance to the closest object. /// </summary> /// <param name="Angle">Angle of sensor, in radians. Also see the "absolute" parameter.</param> /// <param name="maxRange">Max Distance that the robot can see in front of itself.</param> /// <param name="point">2D location of the robot's center.</param> /// <param name="Owner">The currently active robot.</param> /// <param name="hit">** Output variable ** - true if another object intersects the cast ray, false otherwise.</param> /// <param name="absolute">If false, the Angle parameter is relative to the agent's Heading. Otherwise it follows the standard unit AreaOfImpact.</param> /// <returns></returns> public override double raycast (double angle, double maxRange, Point2D point, Robot owner, out SimulatorObject hit, bool absolute = false) { hit=null; Point2D casted = new Point2D(point); double distance = maxRange; // Cast point casted out from the robot's center point along the sensor direction if (!absolute) { casted.X += Math.Cos(angle + owner.Heading) * distance; casted.Y += Math.Sin(angle + owner.Heading) * distance; } else { casted.X += Math.Cos(angle) * distance; casted.Y += Math.Sin(angle) * distance; } // Create line segment from robot's center to casted point Line2D cast = new Line2D(point, casted); // Now do naive detection of collision of casted rays with objects // First for all walls foreach (Wall wall in Domain.walls) { if (!wall.Visible) continue; bool found = false; Point2D intersection = wall.Line.intersection(cast, out found); if (found) { double new_distance = intersection.distance(point); if (new_distance < distance) { distance = new_distance; hit=wall; } } } // Then for all robots if(!AgentVisible) return distance; foreach (Robot robot2 in Robots) { bool found = false; if (robot2 == owner) continue; double new_distance = cast.nearestIntersection(robot2.AreaOfImpact, out found); if (found) { if (new_distance < distance) { distance = new_distance; hit=robot2; } } } return distance; }
/// <summary> /// Calculates the point of intersection between two line segments /// </summary> /// <param name="L">Second line segment that is supposed to intersect with this line segment.</param> /// <param name="found">**Output parameter**, will return false if no intersection exists.</param> public Point2D intersection(Line2D line,out bool found) { Point2D pt = new Point2D(0.0,0.0); Point2D A = Endpoint1; Point2D B = Endpoint2; Point2D C = line.Endpoint1; Point2D D = line.Endpoint2; double rTop = (A.Y-C.Y)*(D.X-C.X)-(A.X-C.X)*(D.Y-C.Y); double rBot = (B.X-A.X)*(D.Y-C.Y)-(B.Y-A.Y)*(D.X-C.X); double sTop = (A.Y-C.Y)*(B.X-A.X)-(A.X-C.X)*(B.Y-A.Y); double sBot = (B.X-A.X)*(D.Y-C.Y)-(B.Y-A.Y)*(D.X-C.X); if ((rBot == 0 || sBot == 0)) { found = false; return pt; } double r = rTop/rBot; double s = sTop/sBot; if( (r>0) && (r<1) && (s>0) && (s<1)) { pt.X = A.X + r * (B.X-A.X); pt.Y = A.Y + r * (B.Y - A.Y); found=true; return pt; } else { found = false; return pt; } }
/// <summary> /// Creates a new Line2D object by copying another Line2D. /// </summary> public Line2D(Line2D otherLine2D) { Endpoint1=otherLine2D.Endpoint1; Endpoint2=otherLine2D.Endpoint2; }
/// <summary> /// Casts a ray from the robot's center point according to the specified Angle and returns the Distance to the closest object. /// </summary> /// <param name="Angle">Angle of sensor, in radians. Also see the "absolute" parameter.</param> /// <param name="maxRange">Max Distance that the robot can see in front of itself.</param> /// <param name="point">2D location of the robot's center.</param> /// <param name="Owner">The currently active robot.</param> /// <param name="hit">** Output variable ** - true if another object intersects the cast ray, false otherwise.</param> /// <param name="absolute">If false, the Angle parameter is relative to the agent's Heading. Otherwise it follows the standard unit AreaOfImpact.</param> /// <returns></returns> public override double raycast(double angle, double maxRange, Point2D point, Robot owner, out SimulatorObject hit, bool absolute = false) { hit = null; Point2D casted = new Point2D(point); double distance = maxRange; // Cast point casted out from the robot's center point along the sensor direction if (!absolute) { casted.X += Math.Cos(angle + owner.Heading) * distance; casted.Y += Math.Sin(angle + owner.Heading) * distance; } else { casted.X += Math.Cos(angle) * distance; casted.Y += Math.Sin(angle) * distance; } // Create line segment from robot's center to casted point Line2D cast = new Line2D(point, casted); // Now do naive detection of collision of casted rays with objects // First for all walls foreach (Wall wall in Domain.walls) { if (!wall.Visible) { continue; } bool found = false; Point2D intersection = wall.Line.intersection(cast, out found); if (found) { double new_distance = intersection.distance(point); if (new_distance < distance) { distance = new_distance; hit = wall; } } } // Then for all robots if (!AgentVisible) { return(distance); } foreach (Robot robot2 in Robots) { bool found = false; if (robot2 == owner) { continue; } double new_distance = cast.nearestIntersection(robot2.AreaOfImpact, out found); if (found) { if (new_distance < distance) { distance = new_distance; hit = robot2; } } } return(distance); }