public static void ConvexHull() { int[] testSizes = new int[] { 12345, 100, 316, 1000, 3160, 10000, 31600, 100000, 316000, 1000000, 3160000, 10000000 }; for (int iter = 0; iter < testSizes.Length; iter++) { Random r = new Random(); List <PointD> points = new List <PointD>(testSizes[iter]); for (int i = 0; i < points.Capacity; i++) { double size = r.NextDouble(); double ang = r.NextDouble() * (Math.PI * 2); points.Add(new PointD(size * Math.Cos(ang), size * Math.Sin(ang))); } // Plus: test sorting time to learn how much of the time is spent sorting var points2 = new List <PointD>(points); EzStopwatch timer = new EzStopwatch(true); points2.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : (a.X < b.X ? -1 : 1)); Stopwatch timer2 = new Stopwatch(); timer2.Start(); int sortTime = timer.Restart(); IListSource <Point <double> > output = PointMath.ComputeConvexHull(points, true); int hullTime = timer.Millisec; Console.WriteLine("{0:c} (ticks:{1,10} freq:{2})", timer2.Elapsed, timer2.ElapsedTicks, Stopwatch.Frequency); if (iter == 0) { continue; // first iteration primes the JIT/caches } Console.WriteLine("Convex hull of {0,8} points took {1} ms ({2} ms for sorting step). Output has {3} points.", testSizes[iter], hullTime, sortTime, output.Count); } }
private Image RotateImage(Image inputImg, double degreeAngle) { //Corners of the image PointF[] rotationPoints = { new PointF(0, 0), new PointF(inputImg.Width, 0), new PointF(0, inputImg.Height), new PointF(inputImg.Width, inputImg.Height) }; //Rotate the corners PointMath.RotatePoints(rotationPoints, new PointF(inputImg.Width / 2.0f, inputImg.Height / 2.0f), degreeAngle); //Get the new bounds given from the rotation of the corners //(avoid clipping of the image) Rectangle bounds = PointMath.GetBounds(rotationPoints); //An empy bitmap to draw the rotated image Bitmap rotatedBitmap = new Bitmap(bounds.Width, bounds.Height); using (Graphics g = Graphics.FromImage(rotatedBitmap)) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; //Transformation matrix Matrix m = new Matrix(); m.RotateAt((float)degreeAngle, new PointF(inputImg.Width / 2.0f, inputImg.Height / 2.0f)); m.Translate(-bounds.Left, -bounds.Top, MatrixOrder.Append); //shift to compensate for the rotation g.Transform = m; g.DrawImage(inputImg, 0, 0); } return((Image)rotatedBitmap); }
private static void WriteFunctionValue(Node function, double[] values) { PointMath math = new PointMath(); double value = function.Apply(math, values[0], values[1], values[2], values[3]); Console.WriteLine(string.Format("f({0}, {1}, {2}, {3}) = {4}\n", values[0], values[1], values[2], values[3], value)); }
private static void WritePartialDerivativeValue(Node[] partialDerivative, double[] values) { PointMath math = new PointMath(); Console.WriteLine(string.Format("grad f({0}, {1}, {2}, {3}) = ({4}, {5}, {6}, {7})\n", values[0], values[1], values[2], values[3], partialDerivative[0].Apply(math, values[0], values[1], values[2], values[3]), partialDerivative[1].Apply(math, values[0], values[1], values[2], values[3]), partialDerivative[2].Apply(math, values[0], values[1], values[2], values[3]), partialDerivative[3].Apply(math, values[0], values[1], values[2], values[3]))); }
private void drawRotatedArrow(GraphicsPlus graphics) { Debug.WriteLine("drawRotatedArrow: " + this.rotationAngle, this.ToString()); Point center = new Point(this.Width / 2, this.Height / 2); int arWidthHalf = ARROW_WIDTH / 2; //int arHeightHalf = ARROW_HEIGHT / 2; Point[] arrowPoints = { new Point(center.X, center.Y - arWidthHalf), new Point(center.X - 2 * arWidthHalf / 3, center.Y + arWidthHalf), new Point(center.X + 2 * arWidthHalf / 3, center.Y + arWidthHalf), new Point(center.X, center.Y + arWidthHalf / 2) }; Debug.WriteLine("drawRotatedArrow: points " + PointUtil.pointsStr(arrowPoints), this.ToString()); PointMath.RotatePoints(arrowPoints, center, this.rotationAngle); Debug.WriteLine("drawRotatedArrow: points " + PointUtil.pointsStr(arrowPoints), this.ToString()); graphics.SetSmoothingMode(SmoothingMode.SmoothingModeAntiAlias); PenPlus pen = new PenPlus(ARROW_COLOR, 3); pen.SetEndCap(LineCap.LineCapRound); pen.SetStartCap(LineCap.LineCapRound); graphics.DrawLine(pen, new GpPoint(arrowPoints[0].X, arrowPoints[0].Y), new GpPoint(arrowPoints[1].X, arrowPoints[1].Y)); graphics.DrawLine(pen, new GpPoint(arrowPoints[1].X, arrowPoints[1].Y), new GpPoint(arrowPoints[3].X, arrowPoints[3].Y)); graphics.DrawLine(pen, new GpPoint(arrowPoints[3].X, arrowPoints[3].Y), new GpPoint(arrowPoints[2].X, arrowPoints[2].Y)); graphics.DrawLine(pen, new GpPoint(arrowPoints[2].X, arrowPoints[2].Y), new GpPoint(arrowPoints[0].X, arrowPoints[0].Y)); pen.Dispose(); }
public void ComputeVertices() { ////use convex hull to find vertices planeVertices.Clear(); List <Point <double> > points2 = new List <Point <double> >(); foreach (MyVector3 p in planePoints) { Point <double> pt = new Point <double>(p.x, p.y); points2.Add(pt); } List <Point <double> > convex_hull = PointMath.ComputeConvexHull(points2, false).ToList(); foreach (Point <double> point in convex_hull) { MyVector3 u = new MyVector3(point.X, point.Y, ComputeZ(point.X, point.Y)); planeVertices.Add(u); } ProjectVerticesTo2d(); //ComputePlaneArea(); }
// To recognize a scribble we require the simplified line to reverse // direction at least three times. There are separate criteria for // erasing a shape currently being drawn and for erasing existing // shapes. // // The key difference between an "erase scribble" and a "cancel // scribble" is that an erase scribble starts out as such, while // a cancel scribble indicates that the user changed his mind, so // the line will not appear to be a scribble at the beginning. // The difference is detected by timestamps. For example, the // following diagram represents an "erase" operation and a "cancel" // operation. Assume the input points are evenly spaced in time, // and that the dots represent points where the input reversed // direction. // // Input points .......................... // Reversals (erase) . . . . . . // Reversals (cancel) . . . . // // So, a scribble is considered an erasure if it satisfies t0 < t1, // where t0 is the time between mouse-down and the first reversal, // and t1 is the time between the first and third reversals. A cancel // operation satisfies t0 > t1 instead. // // Both kinds of scribble need to satisfy the formula LL*c > CHA, // where c is a constant factor in pixels, LL is the drawn line // length and CHA is the area of the Convex Hull that outlines the // drawn figure. This formula basically detects that the user // is convering the same ground repeatedly; if the pen reverses // direction repeatedly but goes to new places each time, it's not // considered an erasure scribble. For a cancel scribble, LL is // computed starting from the first reversal. IEnumerable <Shape> RecognizeScribbleForEraseOrCancel(DragState state, out bool cancel, out List <PointT> simplifiedSS) { cancel = false; simplifiedSS = null; var tolerance = state._inputTransform.Transform(new VectorT(0, 10)).Length(); var simplifiedMP = LineMath.SimplifyPolyline( state.UnfilteredMousePoints.Select(p => p.Point), tolerance); List <int> reversals = FindReversals(simplifiedMP, 3); if (reversals.Count >= 3) { simplifiedSS = simplifiedMP.Select(p => state._inputTransform.Transform(p)).ToList(); // 3 reversals confirmed. Now decide: erase or cancel? int[] timeStampsMs = FindTimeStamps(state.UnfilteredMousePoints, simplifiedMP); int t0 = timeStampsMs[reversals[0]], t1 = timeStampsMs[reversals[2]] - t0; cancel = t0 > t1 + 500; // Now test the formula LL*c > CHA as explained above IListSource <PointT> simplifiedMP_ = cancel ? simplifiedMP.Slice(reversals[0]) : simplifiedMP.AsListSource(); float LL = simplifiedMP_.AdjacentPairs().Sum(pair => pair.A.Sub(pair.B).Length()); var hull = PointMath.ComputeConvexHull(simplifiedMP); float CHA = PolygonMath.PolygonArea(hull); if (LL * EraseNubWidth > CHA) { // Erasure confirmed. if (cancel) { return(EmptyList <Shape> .Value); } // Figure out which shapes to erase. To do this, we compute for // each shape the amount of the scribble that overlaps that shape. var simplifiedSS_ = simplifiedSS; return(_doc.Shapes.Where(s => ShouldErase(s, simplifiedSS_)).ToList()); } } return(null); }
public Connector FindNearestConnector(Netron.Shape shape, PointF p) { Connector best = null; double distBest = double.MaxValue; double dist; foreach (Connector c in shape.Connectors) { dist = PointMath.SqrDistance(shape.ConnectionPoint(c), p); if (dist < distBest) { distBest = dist; best = c; } } if (best == null) { throw new Exception("could not find port"); } return(best); }
public JsonResult ConvexHull(int Id, int Forecast) { if (Forecast > 0) { using (MeteoDataEntities me = new MeteoDataEntities()) { var asciiResult = me.IndexMaps.Where(x => x.Id == Id).Select(x => x.IndexMapZipAscii).First(); Byte[] ascii = ex.Uncompress(asciiResult); //System.IO.File.WriteAllBytes(@"C:\Static\test.asc", ascii); #region Read ascii List <AsciiValues> listasp = new List <AsciiValues>(); int counter = 0; string line; int ncols = 0; int nrows = 0; int xllcorner = 0; int yllcorner = 0; int cellsize = 0; int NODATA_value = 0; using (MemoryStream memoryStream = new MemoryStream(ascii)) { using (StreamReader st = new StreamReader(memoryStream)) { while ((line = st.ReadLine()) != null) { //System.Console.WriteLine(line); if (!string.IsNullOrWhiteSpace(line)) { counter++; #region ASC Details if (counter < 7) { string[] result = line.Split(' '); if (result[0].Contains("ncols")) { for (int i = 1; i < result.Length; i++) { if (!String.IsNullOrWhiteSpace(result[i])) { int number; if (int.TryParse(result[i], out number)) { ncols = number; } } } } if (result[0].Contains("nrows")) { for (int i = 1; i < result.Length; i++) { if (!String.IsNullOrWhiteSpace(result[i])) { int number; if (int.TryParse(result[i], out number)) { nrows = number; } } } } if (result[0].Contains("xllcorner")) { for (int i = 1; i < result.Length; i++) { if (!String.IsNullOrWhiteSpace(result[i])) { int number; if (int.TryParse(result[i], out number)) { xllcorner = number; } } } } if (result[0].Contains("yllcorner")) { for (int i = 1; i < result.Length; i++) { if (!String.IsNullOrWhiteSpace(result[i])) { int number; if (int.TryParse(result[i], out number)) { yllcorner = number; } } } } if (result[0].Contains("cellsize")) { for (int i = 1; i < result.Length; i++) { if (!String.IsNullOrWhiteSpace(result[i])) { int number; if (int.TryParse(result[i], out number)) { cellsize = number; } } } } if (result[0].Contains("NODATA_value")) { for (int i = 1; i < result.Length; i++) { if (!String.IsNullOrWhiteSpace(result[i])) { int number; if (int.TryParse(result[i], out number)) { NODATA_value = number; } } } } } #endregion ASC Details else { string[] result = line.Split(' '); for (int i = 0; i < result.Length; i++) { int number; if (int.TryParse(result[i], out number)) { AsciiValues aspul = new AsciiValues() { X = xllcorner + (i * cellsize), Y = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)), Value = number }; AsciiValues aspur = new AsciiValues() { X = xllcorner + (i * cellsize) + cellsize, Y = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)), Value = number }; AsciiValues aspdl = new AsciiValues() { X = xllcorner + (i * cellsize), Y = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)) - cellsize, Value = number }; AsciiValues aspdr = new AsciiValues() { X = xllcorner + (i * cellsize) + cellsize, Y = (yllcorner + (nrows * cellsize)) - (cellsize * (counter - 7)) - cellsize, Value = number }; listasp.Add(aspul); listasp.Add(aspur); listasp.Add(aspdl); listasp.Add(aspdr); } } } } } counter.ToString(); } } #endregion Read ascii var points = listasp.Where(x => x.Value <= Forecast && x.Value > 0); var finalpoints = points.Select(x => new Point <double>() { X = x.X, Y = x.Y }).ToList(); var ConvexHullresult = PointMath.ComputeConvexHull(finalpoints, true); return(this.Json(ConvexHullresult, JsonRequestBehavior.AllowGet)); } } else { return(this.Json(null, JsonRequestBehavior.AllowGet)); } }
// TODO: this method is too big public void createNew() { Debug.WriteLine("----- createCurrentView -----", ToString()); // container to keep map parts which create current map view Hashtable viewParts = new Hashtable(); // get current gps coordinates double latitude = this.currentGpsLocation.getLatitude(); double longitude = this.currentGpsLocation.getLongitude(); //Debug.WriteLine("latitude: " + latitude + ", longitude: " + longitude, this.ToString()); // get point which indicates part image for the location Point partPoint = this.currentMapPkg.getPartPoint(latitude, longitude); Debug.WriteLine("partPoint: " + PointUtil.pointStr(partPoint), ToString()); // get location (pixel coordinates) inside part image Point insidePartPosition = this.currentMapPkg.getInsidePartPosition(latitude, longitude); //Debug.WriteLine("insidePartPosition: (" + insidePartPosition.X + "; " + insidePartPosition.Y + ")", this.ToString()); // add center MapView point Point centerViewPoint = new Point(1, 1); viewParts[centerViewPoint] = this.currentMapPkg.getPart(partPoint); // map view has only sense when there is center map part if (viewParts[centerViewPoint] == null) { Debug.WriteLine("Can't get center part! viewParts[centerViewPoint] is null - skipping.", this.ToString()); // return when center part is null this.currentMapVeiw = null; return; } // add neighbours of center point foreach (DictionaryEntry entry in this.pointSurroundings) { Point directionPoint = (Point)entry.Value; Debug.WriteLine("directionPoint: " + PointUtil.pointStr(directionPoint), ToString()); Point viewNeighbour = PointMath.addPoints(centerViewPoint, directionPoint); Point mapNeighbour = PointMath.addPoints(partPoint, directionPoint); try { viewParts[viewNeighbour] = this.currentMapPkg.getPart(mapNeighbour); if (viewParts[viewNeighbour] == null) { Debug.WriteLine("looking for view neighbour:", this.ToString()); MapPackage neighbourPkg = null; int neighbourDirectionX = 0; if (mapNeighbour.X > this.currentMapPkg.getMaxX()) { neighbourDirectionX = 1; } if (mapNeighbour.X < 0) { neighbourDirectionX = -1; } int neighbourDirectionY = 0; if (mapNeighbour.Y > this.currentMapPkg.getMaxY()) { neighbourDirectionY = 1; } if (mapNeighbour.Y < 0) { neighbourDirectionY = -1; } Point neighbourDirection = new Point(neighbourDirectionX, neighbourDirectionY); try { Debug.WriteLine(" trying to get neighbour pkg for neighbour point: " + PointUtil.pointStr(neighbourDirection), ToString()); // get neighbour map package neighbourPkg = this.mapPkgRepository.getNeighbourMapPkg(this.currentMapPkg, neighbourDirection, this.currentZoom); } catch (MapNotFoundException e) { Debug.WriteLine(" Can't get neighbour pkg for: " + this.currentMapPkg + ", dircetion: (" + directionPoint.X + "; " + directionPoint.Y + "), ERROR: " + e.Message, this.ToString()); } if (neighbourPkg != null) { if (mapNeighbour.X > this.currentMapPkg.getMaxX()) { mapNeighbour.X = 0; } if (mapNeighbour.X < 0) { mapNeighbour.X = neighbourPkg.getMaxX(); } if (mapNeighbour.Y > this.currentMapPkg.getMaxY()) { mapNeighbour.Y = 0; } if (mapNeighbour.Y < 0) { mapNeighbour.Y = neighbourPkg.getMaxY(); } Debug.WriteLine(" getting map part from neighbour pkg for point: " + PointUtil.pointStr(mapNeighbour), this.ToString()); viewParts[viewNeighbour] = neighbourPkg.getPart(mapNeighbour); } } else { Debug.WriteLine("view neighbour ok", this.ToString()); } } catch (Exception e) { Debug.WriteLine("Can't get neighbour(" + entry.Key + ")! ERROR: " + e.Message, this.ToString()); } } // create map view MapView mapView = new MapView(this.currentGpsLocation, insidePartPosition, viewParts, this.orderingPoints); mapView.setLatitudePerPixel(this.currentMapPkg.getLatitudePerPixel()); mapView.setLongitudePerPixel(this.currentMapPkg.getLongitudePerPixel()); Area mapViewArea = createMapViewArea(mapView); Area centerImgArea = createMapViewAreaForCenterImg(mapView); mapView.setArea(mapViewArea); mapView.setCenterImgArea(centerImgArea); Debug.WriteLine("-----------------------------\n", ToString()); this.currentMapVeiw = mapView; }