/// <summary> /// This finds the best point by converting neuron positions/values into a hilly terrain, and taking a contour plot. /// The middle of the biggest polygon is the chosen point. /// </summary> private void Update_Contour() { const double CONTOURHEIGHT = .6667d; #region Set heights double maxHeight = 0; for (int cntr = 0; cntr < _neurons.Length; cntr++) { _terrainPoints[cntr].Z = _neurons[cntr].Value * 100; if (_terrainPoints[cntr].Z > maxHeight) { maxHeight = _terrainPoints[cntr].Z; } } for (int cntr = 0; cntr < _terrainTriangles.Length; cntr++) { _terrainTriangles[cntr].PointsChanged(); } double height = maxHeight * CONTOURHEIGHT; #endregion Triangle plane = new Triangle(new Point3D(-1, 0, height), new Point3D(1, 0, height), new Point3D(0, 1, height)); // normal needs to point up // Get the contour polygons var polys = Math3D.GetIntersection_Mesh_Plane(_terrainTriangles, plane); if (polys == null || polys.Length == 0) { // Nothing, don't move _mousePlate.CurrentPoint2D = new Point(0, 0); return; } else if (polys.Length == 1) { // Just one polygon, no need to take the expense of calculating volume _mousePlate.CurrentPoint2D = Math3D.GetCenter(polys[0].Polygon3D).ToPoint2D(); return; } // Find the polygon with the highest volume var topPoly = polys. Select(o => new { Poly = o, Volume = o.GetVolumeAbove() }). OrderByDescending(o => o.Volume). First(); // Go to the center of this polygon _mousePlate.CurrentPoint2D = Math3D.GetCenter(topPoly.Poly.Polygon3D).ToPoint2D(); }