public double CalcShift(Rect face) { var centre = new Point(face.X + face.Width / 2f, face.Y + face.Height / 2f); var decal = LastCentre.DistanceTo(centre); LastCentre = centre; return(decal); }
/// <summary> /// Returns points in the order /// top left /// top right /// bottom right /// bottom left /// Updated to fixed version of the order points method /// http://www.pyimagesearch.com/2016/03/21/ordering-coordinates-clockwise-with-python-and-opencv/ /// </summary> /// <param name="pts"></param> /// <returns></returns> private static Tuple <Point2f, Point2f, Point2f, Point2f> OrderPoints(Mat pts) { //TODO: This is begging for C#7 tuples //TODO: Error handling //Extract points Point p1 = pts.Get <Point>(0); Point p2 = pts.Get <Point>(1); Point p3 = pts.Get <Point>(2); Point p4 = pts.Get <Point>(3); Point2f[] points = { new Point2f(p1.X, p1.Y), new Point2f(p2.X, p2.Y), new Point2f(p3.X, p3.Y), new Point2f(p4.X, p4.Y) }; //sort the points based on their x-coordinates Point2f[] xSorted = points.OrderBy(pt => pt.X).ToArray(); //grab the left-most and right-most points from the sorted //x-roodinate points Point2f[] leftMost = xSorted.Take(2).ToArray(); Point2f[] rightMost = xSorted.Skip(2).ToArray(); //now, sort the left-most coordinates according to their //y-coordinates so we can grab the top-left and bottom-left //points, respectively Point2f tl = leftMost.OrderBy(pt => pt.Y).First(); Point2f bl = xSorted.OrderBy(pt => pt.Y).Last(); //now that we have the top-left coordinate, use it as an //anchor to calculate the Euclidean distance between the //top-left and right-most points; by the Pythagorean //theorem, the point with the largest distance will be //our bottom-right point Point2f[] d = rightMost.OrderBy(pt => tl.DistanceTo(pt)).ToArray(); Point2f tr = d.First(); Point2f br = d.Last(); //return the coordinates in top-left, top-right, //bottom-right, and bottom-left order return(Tuple.Create(tl, tr, br, bl)); }
/// <summary> /// rendering pass for a node /// </summary> /// <param name="FOV"></param> /// <param name="near"></param> /// <param name="far"></param> /// <param name="eyeVector"></param> /// <param name="position"></param> /// <param name="renderOverride">flag that prevents node to be rendered even if in view field, if its too far down the hierarchy</param> internal void RenderingPass(float FOV, float near, float far, Vector3f eyeVector, Point2f position, bool renderOverride) { //new algo: test if three points forming a view triangle lie within the box or only a part if current node pointsInsideFOV.Reset(); pointsInsideFOV.Start(); int pointsInside = NumberOfPointsInsideFOV(false, far, eyeVector, position); pointsInsideFOV.Stop(); LasMetrics.GetInstance().pointsInsideViewMilis += pointsInsideFOV.Elapsed; LasMetrics.GetInstance().pointsInsideViewCounted++; //if render override flag was not set to false, check if it can be set here //renderOverride set to false prevents node or leaf to be rendered if too far away, //although it can still be loaded into memory. This prevents far away regions to be //drawn in too much detail that isn't even visible if (QTreeNode.PerNodeLOD && renderOverride && !boundingBox.contains(position)) { float closestCorner = position.DistanceTo(boundingBox.Center); //check if nearest corner is close enough to warant rendering this level for (int i = 0; i < 4; i++) { float distToPosition = position.DistanceTo(boundingBox.Corners[i]); if (closestCorner > distToPosition) { closestCorner = distToPosition; } } //calculate distance relative to the far point. determines which nodes will be drawn and which not float relativeDistance = 1.0f - closestCorner / far; if (relativeDistance < nodeHierarchyLevel) { renderOverride = false; } } if (pointsInside == 3) { //all points are seen - contents of the node should immediately be drawn without further checks if (renderOverride) { RenderVisible(); } } else if (pointsInside > 0) { //if only some of the points are inside, checks should be performed in children if (renderOverride) { Render(); } if (leaf != null) { //if only a part is inside, render it anyway. leaf.Render(renderOverride); } else { //render also this node. parts of this node that are visible will be already loaded and therefore visible nodes[NE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); nodes[NW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); nodes[SE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); nodes[SW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); } } else { //no points are inside //count number of buffered corners. if: //- all buffered - place leaf in buffer // -some buffered - delve further //- none buffered - cascadeInvisibility //new values for buffered checks + values are modified with Buffered values int bufferedPointsInside = NumberOfPointsInsideFOV( true, far + LasDataManager.BufferedDistance, eyeVector, position - new Point2f(eyeVector.x, eyeVector.z) * LasDataManager.BufferedPositionRadius); if (bufferedPointsInside == 3) { //all points are within buffer range- buffer all lower nodes and leafs if (leaf != null) { leaf.BufferLeaf(); } else { CascadeBuffering(); } } else if (bufferedPointsInside > 0) { //if only some of the points are inside, checks should be performed in children if (leaf != null) { //if 2 or more points are inside buffered area buffer it anyways if (bufferedPointsInside > 1) { leaf.BufferLeaf(); } } else { nodes[NE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); nodes[NW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); nodes[SE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); nodes[SW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride); } } else { //none are buffered - remove if in buffer CascadeInvisibility(); } } }