/// <summary> /// Create a point in the polar coordinate system from the provided Cartesian coordinates. /// </summary> public static PolarPoint FromCartesian(IntPoint p) { double r = Math.Sqrt((p._x * p._x) + (p._y * p._y)); double t = Math.Atan2(p._x, p._y); if(t<0.0) { t += 2*Math.PI; } return new PolarPoint(r, t); }
/// <summary> /// Rotates the currrent point around another point at a given angle from the origin. /// </summary> /// <param name="angle">The angle from the origin.</param> /// <param name="point">The point about which to rotate.</param> public void RotatePoint(double angle, IntPoint point) { // Decrement this point by the given point about which to rotate this -= point; // Perform the actual rotation X = (int) Math.Cos(angle)*X - (int) Math.Sin(angle)*Y; Y = (int) Math.Sin(angle)*X + (int) Math.Cos(angle)*Y; // Add the coordinates that had been offset back in this += point; }
private void PaintView(IBlackBox box) { if(_initializing) { return; } Graphics g = Graphics.FromImage(_image); g.FillRectangle(_brushBackground, 0, 0, _image.Width, _image.Height); g.SmoothingMode = SmoothingMode.AntiAlias; // Get control width and height. int width = Width; int height = Height; // Determine smallest dimension. Use that as the edge length of the square grid. width = height = Math.Min(width, height); // Pixel size is calculated using integer division to produce cleaner lines when drawing. // The inherent rounding down may produce a grid 1 pixel smaller then the determined edge length. // Also make room for a combo box above the grid. This will be used allow the user to change the grid resolution. int visualFieldPixelSize = (height-GridTop) / _visualFieldResolution; width = height = visualFieldPixelSize * _visualFieldResolution; // Paint pixel outline grid. // Vertical lines. int x = GridLeft; for(int i=0; i<=_visualFieldResolution; i++, x+=visualFieldPixelSize) { g.DrawLine(__penGrey, x, GridTop, x, GridTop+height); } // Horizontal lines. int y = GridTop; for(int i=0; i<=_visualFieldResolution; i++, y+=visualFieldPixelSize) { g.DrawLine(__penGrey, GridLeft, y, GridLeft+width, y); } // Apply test case to black box's visual field sensor inputs. BoxesVisualDiscriminationEvaluator.ApplyVisualFieldToBlackBox(_testCaseField, box, _visualFieldResolution, _visualOriginPixelXY, _visualPixelSize); // Activate the black box. box.ResetState(); box.Activate(); // Read output responses and paint them to the pixel grid. // Also, we determine the range of values so that we can normalize the range of pixel shades used. double low, high; low = high = box.OutputSignalArray[0]; for(int i=1; i<box.OutputSignalArray.Length; i++) { double val = box.OutputSignalArray[i]; if(val > high) { high = val; } else if(val <low) { low = val; } } double colorScaleFactor; if(0.0 == (high-low)) { colorScaleFactor = 1.0; } else { colorScaleFactor = 1.0 / (high-low); } IntPoint maxActivationPoint = new IntPoint(0,0); double maxActivation = -1.0; int outputIdx = 0; y = GridTop; for(int i=0; i<_visualFieldResolution; i++, y+=visualFieldPixelSize) { x = GridLeft; for(int j=0; j<_visualFieldResolution; j++, x+=visualFieldPixelSize, outputIdx++) { double output = box.OutputSignalArray[outputIdx]; if(output > maxActivation) { maxActivation = output; maxActivationPoint._x = j; maxActivationPoint._y = i; } Color color = GetResponseColor((output-low)*colorScaleFactor); Brush brush = new SolidBrush(color); g.FillRectangle(brush, x+1, y+1, visualFieldPixelSize-2, visualFieldPixelSize-2); } } // Paint lines around the small and large test case boxes to highlight them. // Small box. int testFieldPixelSize = (_visualFieldResolution / TestCaseField.TestFieldResolution) * visualFieldPixelSize; g.DrawRectangle(__penBoxOutline, GridLeft + (_testCaseField.SmallBoxTopLeft._x * testFieldPixelSize), GridTop + (_testCaseField.SmallBoxTopLeft._y * testFieldPixelSize), testFieldPixelSize, testFieldPixelSize); // Large box. g.DrawRectangle(__penBoxOutline, GridLeft + (_testCaseField.LargeBoxTopLeft._x * testFieldPixelSize), GridTop + (_testCaseField.LargeBoxTopLeft._y * testFieldPixelSize), testFieldPixelSize*3, testFieldPixelSize*3); // Draw red line around pixel with highest activation. g.DrawRectangle(__penSelectedPixel, GridLeft + (maxActivationPoint._x * visualFieldPixelSize), GridTop + (maxActivationPoint._y * visualFieldPixelSize), visualFieldPixelSize, visualFieldPixelSize); Refresh(); }
/// <summary> /// Calculate Manhattan distance between a point and x and y coordinates in two-dimensional space. /// </summary> /// <param name="a">The point in two-dimensional space.</param> /// <param name="x">The x-coordinate in two-dimensiona space.</param> /// <param name="y">The y-coordinate in two-dimensiona space.</param> /// <returns>The manhattan distance.</returns> public static double CalculateManhattanDistance(IntPoint a, int x, int y) { double xDelta = Math.Abs(a.X - x); double yDelta = Math.Abs(a.Y - y); return xDelta + yDelta; }
/// <summary> /// Calculate Euclidean distance between two points. /// <param name="a">The point in two-dimensional space.</param> /// <param name="x">The x-coordinate in two-dimensiona space.</param> /// <param name="y">The y-coordinate in two-dimensiona space.</param> /// <returns>The Euclidean distance.</returns> /// </summary> public static double CalculateEuclideanDistance(IntPoint a, int x, int y) { double xDelta = (a.X - x); double yDelta = (a.Y - y); return Math.Sqrt(xDelta*xDelta + yDelta*yDelta); }
/// <summary> /// Calculate Manhattan distance between two points in two-dimensional space. /// </summary> /// <param name="a">The first point in two-dimensional space.</param> /// <param name="b">The second point in two-dimensional space.</param> /// <returns>The manhattan distance.</returns> public static double CalculateManhattanDistance(IntPoint a, IntPoint b) { double xDelta = Math.Abs(a.X - b.X); double yDelta = Math.Abs(a.Y - b.Y); return xDelta + yDelta; }
/// <summary> /// Calculate the squared distance between two points. /// </summary> /// <param name="a">The first point in two-dimensional space.</param> /// <param name="b">The second point in two-dimensional space.</param> /// <returns>The squared distance.</returns> public static int CalculateSquaredDistance(IntPoint a, IntPoint b) { var xDelta = a.X - b.X; var yDelta = a.Y - b.Y; return xDelta*xDelta + yDelta*yDelta; }
/// <summary> /// Calculate Euclidean distance between two points. /// </summary> /// <param name="a">The first point in two-dimensional space.</param> /// <param name="b">The second point in two-dimensional space.</param> /// <returns>The Euclidean distance.</returns> public static double CalculateEuclideanDistance(IntPoint a, IntPoint b) { double xDelta = (a.X - b.X); double yDelta = (a.Y - b.Y); return Math.Sqrt(xDelta*xDelta + yDelta*yDelta); }
#pragma warning restore 1591 #region Static Methods /// <summary> /// Calculate Euclidean distance between two points. /// </summary> public static double CalculateDistance(IntPoint a, IntPoint b) { double x = (a._x - b._x); double y = (a._y - b._y); return Math.Sqrt(x*x + y*y); }
#pragma warning restore 1591 #region Static Methods /// <summary> /// Calculates the angle that the given point makes with the origin in radians. /// </summary> /// <param name="a">The point whose position to compare with the origin.</param> /// <returns>The angle (in radians) that the given point makes with the origin.</returns> public static double CalculateAngleFromOrigin(IntPoint a) { // If we're both X and Y are zero, the point is at the origin, but consider // this to be 90 degrees (pi/2 radians) if (a.X == 0) { if (a.Y == 0) { return Math.PI/2; } // If only X is 0 but Y isn't, we still can't calculate the slope so // consider this to be 270 degrees (3pi/2 radians) return (Math.PI*3)/2; } // Calculate the slope (this would just be Y/X since it's compared to the // origin) and take the arc tangent (which yields the angle in radians) var angle = Math.Atan(a.Y/a.X); // If the X coordinate is positive, just return the calculated angle if (a.X > 0) return angle; // Otherwise, return the angle plus 180 degrees (pi radians) return angle + Math.PI; }
/// <summary> /// Calculate Euclidean distance between two points. /// </summary> public static double CalculateDistance(IntPoint a, int x, int y) { double xdelta = (a._x - x); double ydelta = (a._y - y); return Math.Sqrt(xdelta*xdelta + ydelta*ydelta); }
/// <summary> /// Construct line segment with the specified start and end points. /// </summary> /// <param name="startPoint">The start point.</param> /// <param name="endPoint">The end point.</param> public IntLine(IntPoint startPoint, IntPoint endPoint) { Start = startPoint; End = endPoint; }
/// <summary> /// Calculates the euclidean shortest distance between a line segment and point. /// </summary> /// <param name="line">The line segment involved in the calculation.</param> /// <param name="point">The point involved in the calculation.</param> /// <returns>The shortest euclidean distance between the given line segment and point.</returns> public static double CalculateEuclideanDistanceFromLineToPoint(IntLine line, IntPoint point) { return Math.Sqrt(CalculateSquaredDistanceFromLineToPoint(line, point)); }
/// <summary> /// Calculates the squared shortest distance between a line segment and point. /// </summary> /// <param name="line">The line segment involved in the calculation.</param> /// <param name="point">The point involved in the calculation.</param> /// <returns>The shortest squared distance between the given line segment and point.</returns> public static int CalculateSquaredDistanceFromLineToPoint(IntLine line, IntPoint point) { // Calculate the projection of the given point onto the given line var numerator = (point.X - line.Start.X)*(line.End.X - line.Start.X) + (point.Y - line.Start.Y)*(line.End.Y - line.Start.Y); var denominator = IntPoint.CalculateSquaredDistance(line.Start, line.End); double projection = numerator/denominator; // If the projection is beyond the segment, return the distance to // either the start or end point on the line segment (whichever // happens to be the shortest) if (projection < 0 || projection > 1) { var distanceToStart = IntPoint.CalculateSquaredDistance(line.Start, point); var distanceToEnd = IntPoint.CalculateSquaredDistance(line.End, point); return distanceToStart < distanceToEnd ? distanceToStart : distanceToEnd; } // Create a point on the line segment from which to measure the distance to the given point var segmentPoint = new IntPoint(line.Start.X + (int) projection*(line.End.X - line.Start.X), line.Start.Y + (int) projection*(line.End.Y - line.Start.Y)); // Measure the distance from this point on the segment to the given point return IntPoint.CalculateSquaredDistance(segmentPoint, point); }
private void PaintView(IBlackBox box) { if (_initializing) { return; } Graphics g = Graphics.FromImage(_image); g.FillRectangle(_brushBackground, 0, 0, _image.Width, _image.Height); g.SmoothingMode = SmoothingMode.AntiAlias; // Get control width and height. int width = Width; int height = Height; // Determine smallest dimension. Use that as the edge length of the square grid. width = height = Math.Min(width, height); // Pixel size is calculated using integer division to produce cleaner lines when drawing. // The inherent rounding down may produce a grid 1 pixel smaller then the determined edge length. // Also make room for a combo box above the grid. This will be used allow the user to change the grid resolution. int visualFieldPixelSize = (height - GridTop) / _visualFieldResolution; width = height = visualFieldPixelSize * _visualFieldResolution; // Paint pixel outline grid. // Vertical lines. int x = GridLeft; for (int i = 0; i <= _visualFieldResolution; i++, x += visualFieldPixelSize) { g.DrawLine(__penGrey, x, GridTop, x, GridTop + height); } // Horizontal lines. int y = GridTop; for (int i = 0; i <= _visualFieldResolution; i++, y += visualFieldPixelSize) { g.DrawLine(__penGrey, GridLeft, y, GridLeft + width, y); } // Apply test case to black box's visual field sensor inputs. BoxesVisualDiscriminationEvaluator.ApplyVisualFieldToBlackBox(_testCaseField, box, _visualFieldResolution, _visualOriginPixelXY, _visualPixelSize); // Activate the black box. box.ResetState(); box.Activate(); // Read output responses and paint them to the pixel grid. // Also, we determine the range of values so that we can normalize the range of pixel shades used. double low, high; low = high = box.OutputSignalArray[0]; for (int i = 1; i < box.OutputSignalArray.Length; i++) { double val = box.OutputSignalArray[i]; if (val > high) { high = val; } else if (val < low) { low = val; } } double colorScaleFactor; if (0.0 == (high - low)) { colorScaleFactor = 1.0; } else { colorScaleFactor = 1.0 / (high - low); } IntPoint maxActivationPoint = new IntPoint(0, 0); double maxActivation = -1.0; int outputIdx = 0; y = GridTop; for (int i = 0; i < _visualFieldResolution; i++, y += visualFieldPixelSize) { x = GridLeft; for (int j = 0; j < _visualFieldResolution; j++, x += visualFieldPixelSize, outputIdx++) { double output = box.OutputSignalArray[outputIdx]; if (output > maxActivation) { maxActivation = output; maxActivationPoint._x = j; maxActivationPoint._y = i; } Color color = GetResponseColor((output - low) * colorScaleFactor); Brush brush = new SolidBrush(color); g.FillRectangle(brush, x + 1, y + 1, visualFieldPixelSize - 2, visualFieldPixelSize - 2); } } // Paint lines around the small and large test case boxes to highlight them. // Small box. int testFieldPixelSize = (_visualFieldResolution / TestCaseField.TestFieldResolution) * visualFieldPixelSize; g.DrawRectangle(__penBoxOutline, GridLeft + (_testCaseField.SmallBoxTopLeft._x * testFieldPixelSize), GridTop + (_testCaseField.SmallBoxTopLeft._y * testFieldPixelSize), testFieldPixelSize, testFieldPixelSize); // Large box. g.DrawRectangle(__penBoxOutline, GridLeft + (_testCaseField.LargeBoxTopLeft._x * testFieldPixelSize), GridTop + (_testCaseField.LargeBoxTopLeft._y * testFieldPixelSize), testFieldPixelSize * 3, testFieldPixelSize * 3); // Draw red line around pixel with highest activation. g.DrawRectangle(__penSelectedPixel, GridLeft + (maxActivationPoint._x * visualFieldPixelSize), GridTop + (maxActivationPoint._y * visualFieldPixelSize), visualFieldPixelSize, visualFieldPixelSize); Refresh(); }