public static VertexStore TransformToVxs(this Bilinear bilinearTx, VertexStore src, VertexStore vxs) { int count = src.Count; VertexCmd cmd; double x, y; for (int i = 0; i < count; ++i) { cmd = src.GetVertex(i, out x, out y); bilinearTx.Transform(ref x, ref y); vxs.AddVertex(x, y, cmd); } return(vxs); }
public static VertexStore TransformToVxs(this Perspective perspecitveTx, VertexStore src, VertexStore vxs) { VertexCmd cmd; double x, y; int count = src.Count; for (int i = 0; i < count; ++i) { cmd = src.GetVertex(i, out x, out y); perspecitveTx.Transform(ref x, ref y); vxs.AddVertex(x, y, cmd); } return(vxs); }
public static SKPath CreateGraphicsPath(VertexStore vxs) { //render vertice in store int vcount = vxs.Count; double prevX = 0; double prevY = 0; double prevMoveToX = 0; double prevMoveToY = 0; //var brush_path = new System.Drawing.Drawing2D.GraphicsPath(FillMode.Winding);//*** winding for overlapped path var brushPath = new SKPath(); //how to set widening mode for (int i = 0; i < vcount; ++i) { double x, y; PixelFarm.Agg.VertexCmd cmd = vxs.GetVertex(i, out x, out y); switch (cmd) { case PixelFarm.Agg.VertexCmd.MoveTo: prevMoveToX = prevX = x; prevMoveToY = prevY = y; //brush_path.StartFigure(); brushPath.MoveTo((float)x, (float)y); break; case PixelFarm.Agg.VertexCmd.LineTo: //brush_path.AddLine((float)prevX, (float)prevY, (float)x, (float)y); brushPath.LineTo((float)x, (float)y); prevX = x; prevY = y; break; case PixelFarm.Agg.VertexCmd.CloseAndEndFigure: //brush_path.AddLine((float)prevX, (float)prevY, (float)prevMoveToX, (float)prevMoveToY); brushPath.LineTo((float)prevMoveToX, (float)prevMoveToY); prevMoveToX = prevX = x; prevMoveToY = prevY = y; //brush_path.CloseFigure(); brushPath.Close(); break; case PixelFarm.Agg.VertexCmd.EndFigure: break; case PixelFarm.Agg.VertexCmd.Stop: i = vcount + 1;//exit from loop break; default: throw new NotSupportedException(); } } return brushPath; }
public void Generate(VertexStore srcVxs, VertexStore outputVxs) { //read data from src //generate stroke and //write to output //----------- int cmdCount = srcVxs.Count; VertexCmd cmd; double x, y; positiveSideVectors.Clear(); negativeSideVectors.Clear(); bool has_some_results = false; for (int i = 0; i < cmdCount; ++i) { cmd = srcVxs.GetVertex(i, out x, out y); switch (cmd) { case VertexCmd.LineTo: lineGen.LineTo(x, y, positiveSideVectors, negativeSideVectors); has_some_results = true; break; case VertexCmd.MoveTo: //if we have current shape //leave it and start the new shape lineGen.MoveTo(x, y); break; case VertexCmd.Close: case VertexCmd.CloseAndEndFigure: lineGen.Close(positiveSideVectors, negativeSideVectors); WriteOutput(outputVxs, true); has_some_results = false; break; default: break; } } //------------- if (has_some_results) { WriteOutput(outputVxs, false); } }
public static void FlipY(VertexStore vxs, double y1, double y2) { int i; double x, y; int count = vxs.Count; for (i = 0; i < count; ++i) { VertexCmd flags = vxs.GetVertex(i, out x, out y); if (VertexHelper.IsVertextCommand(flags)) { vxs.ReplaceVertex(i, x, y2 - y + y1); } } }
//---------------------------------------------------------- public void AddSubVertices(VertexStore anotherVxs) { int j = anotherVxs.Count; this.HasMoreThanOnePart = true; for (int i = 0; i < j; ++i) { double x, y; VertexCmd cmd = anotherVxs.GetVertex(i, out x, out y); this.AddVertex(x, y, cmd); if (cmd == VertexCmd.Stop) { break; } } }
/// <summary> /// we do NOT store vxs, return original outputVxs /// </summary> /// <param name="src"></param> /// <param name="outputVxs"></param> public static VertexStore TransformToVxs(this Affine aff, VertexStore src, VertexStore outputVxs) { int count = src.Count; VertexCmd cmd; double x, y; for (int i = 0; i < count; ++i) { cmd = src.GetVertex(i, out x, out y); aff.Transform(ref x, ref y); outputVxs.AddVertex(x, y, cmd); } //outputVxs.HasMoreThanOnePart = src.HasMoreThanOnePart; return(outputVxs); }
public void AddPath(VertexStoreSnap snap) { double x = 0; double y = 0; if (m_cellAARas.Sorted) { Reset(); } if (snap.VxsHasMoreThanOnePart) { //**** //render all parts VertexStore vxs = snap.GetInternalVxs(); int j = vxs.Count; for (int i = 0; i < j; ++i) { var cmd = vxs.GetVertex(i, out x, out y); if (cmd != VertexCmd.Stop) { AddVertex(cmd, x, y); } } } else { VertexSnapIter snapIter = snap.GetVertexSnapIter(); VertexCmd cmd; int dbugVertexCount = 0; while ((cmd = snapIter.GetNextVertex(out x, out y)) != VertexCmd.Stop) { dbugVertexCount++; AddVertex(cmd, x, y); } } }
public VertexStore MakeVxs(VertexStore sourceVxs, VertexStore outputVxs) { StrokeGenerator strkgen = _strokeGen; int j = sourceVxs.Count; strkgen.Reset(); VertexCmd cmd; double x = 0, y = 0, startX = 0, startY = 0; for (int i = 0; i < j; ++i) { cmd = sourceVxs.GetVertex(i, out x, out y); switch (cmd) { case VertexCmd.NoMore: break; case VertexCmd.Close: if (i < j) { //close command strkgen.Close(); strkgen.WriteTo(outputVxs); strkgen.Reset(); } else { } break; case VertexCmd.CloseAndEndFigure: if (i < j) { //close command strkgen.Close(); strkgen.WriteTo(outputVxs); strkgen.Reset(); } else { } break; case VertexCmd.LineTo: case VertexCmd.P2c: //user must flatten the curve before do stroke case VertexCmd.P3c: //user must flatten the curve before do stroke strkgen.AddVertex(x, y, cmd); break; case VertexCmd.MoveTo: strkgen.AddVertex(x, y, cmd); startX = x; startY = y; break; default: throw new System.NotSupportedException(); } } strkgen.WriteTo(outputVxs); strkgen.Reset(); return(outputVxs); }
public VertexStore MakeVxs(VertexStore sourceVxs) { StrokeGenerator strkgen = strokeGen; VertexStore vxs = new VertexStore(); int j = sourceVxs.Count; double x, y; strkgen.RemoveAll(); //1st vertex sourceVxs.GetVertex(0, out x, out y); strkgen.AddVertex(x, y, VertexCmd.MoveTo); double startX = x, startY = y; bool hasMoreThanOnePart = false; for (int i = 0; i < j; ++i) { var cmd = sourceVxs.GetVertex(i, out x, out y); switch (cmd) { case VertexCmd.Stop: case VertexCmd.HasMore: { } break; case VertexCmd.EndFigure: case VertexCmd.EndAndCloseFigure: { strkgen.AddVertex(x, y, cmd); if (i < j - 2) { strkgen.AddVertex(startX, startY, VertexCmd.LineTo); strkgen.WriteTo(vxs); strkgen.RemoveAll(); hasMoreThanOnePart = true; } //end this polygon } break; case VertexCmd.LineTo: case VertexCmd.P2c: case VertexCmd.P3c: { strkgen.AddVertex(x, y, cmd); } break; case VertexCmd.MoveTo: { strkgen.AddVertex(x, y, cmd); startX = x; startY = y; } break; default: throw new System.NotSupportedException(); } } strkgen.WriteTo(vxs); strkgen.RemoveAll(); vxs.HasMoreThanOnePart = hasMoreThanOnePart; return(vxs); }
VertexCmd GetNextVertex(out double x, out double y) { x = 0; y = 0; VertexCmd cmd = VertexCmd.LineTo; do { switch (m_status) { case Status.Init: this.Rewind(); goto case Status.Ready; case Status.Ready: if (multipartVertexDistanceList.CurrentRangeLen < 2 + (m_closed ? 1 : 0)) { cmd = VertexCmd.NoMore; break; } m_status = m_closed ? Status.Outline1 : Status.Cap1; cmd = VertexCmd.MoveTo; m_src_vertex = 0; m_out_vertex = 0; break; case Status.CloseFirst: m_status = Status.Outline2; cmd = VertexCmd.MoveTo; goto case Status.Outline2; case Status.Cap1: { Vertex2d v0, v1; multipartVertexDistanceList.GetFirst2(out v0, out v1); m_stroker.CreateCap( m_out_vertices, v0, v1, v0.CalLen(v1)); m_src_vertex = 1; m_prev_status = Status.Outline1; m_status = Status.OutVertices; m_out_vertex = 0; } break; case Status.Cap2: { Vertex2d beforeLast, last; multipartVertexDistanceList.GetLast2(out beforeLast, out last); m_stroker.CreateCap(m_out_vertices, last, beforeLast, beforeLast.CalLen(last)); m_prev_status = Status.Outline2; m_status = Status.OutVertices; m_out_vertex = 0; } break; case Status.Outline1: { if (m_closed) { if (m_src_vertex >= multipartVertexDistanceList.CurrentRangeLen) { m_prev_status = Status.CloseFirst; m_status = Status.EndPoly1; break; } } else { if (m_src_vertex >= multipartVertexDistanceList.CurrentRangeLen - 1) { m_status = Status.Cap2; break; } } Vertex2d prev, cur, next; multipartVertexDistanceList.GetTripleVertices(m_src_vertex, out prev, out cur, out next); //check if we should join or not ? //don't join it m_stroker.CreateJoin(m_out_vertices, prev, cur, next, prev.CalLen(cur), cur.CalLen(next)); ++m_src_vertex; m_prev_status = m_status; m_status = Status.OutVertices; m_out_vertex = 0; } break; case Status.Outline2: { if (m_src_vertex <= (!m_closed ? 1 : 0)) { m_status = Status.EndPoly2; m_prev_status = Status.Stop; break; } --m_src_vertex; Vertex2d prev, cur, next; multipartVertexDistanceList.GetTripleVertices(m_src_vertex, out prev, out cur, out next); m_stroker.CreateJoin(m_out_vertices, next, cur, prev, cur.CalLen(next), prev.CalLen(cur)); m_prev_status = m_status; m_status = Status.OutVertices; m_out_vertex = 0; } break; case Status.OutVertices: if (m_out_vertex >= m_out_vertices.Count) { m_status = m_prev_status; } else { m_out_vertices.GetVertex(m_out_vertex++, out x, out y); return(cmd); } break; case Status.EndPoly1: m_status = m_prev_status; x = (int)EndVertexOrientation.CCW; y = 0; return(VertexCmd.Close); case Status.EndPoly2: m_status = m_prev_status; x = (int)EndVertexOrientation.CW; y = 0; return(VertexCmd.Close); case Status.Stop: cmd = VertexCmd.NoMore; break; } } while (!VertexHelper.IsEmpty(cmd)); return(cmd); }
public VertexCmd GetNextVertex(out double x, out double y) { return(vxs.GetVertex(currentIterIndex++, out x, out y)); }
VertexCmd GetNextVertex(ref double x, ref double y) { VertexCmd cmd = VertexCmd.LineTo; while (!VertexHelper.IsEmpty(cmd)) { switch (m_status) { case StrokeMath.Status.Init: this.Rewind(); goto case StrokeMath.Status.Ready; case StrokeMath.Status.Ready: if (vertexDistanceList.Count < 2 + (m_closed ? 1 : 0)) { cmd = VertexCmd.Stop; break; } m_status = m_closed ? StrokeMath.Status.Outline1 : StrokeMath.Status.Cap1; cmd = VertexCmd.MoveTo; m_src_vertex = 0; m_out_vertex = 0; break; case StrokeMath.Status.Cap1: m_stroker.CreateCap( m_out_vertices, vertexDistanceList[0], vertexDistanceList[1], vertexDistanceList[0].dist); m_src_vertex = 1; m_prev_status = StrokeMath.Status.Outline1; m_status = StrokeMath.Status.OutVertices; m_out_vertex = 0; break; case StrokeMath.Status.Cap2: m_stroker.CreateCap(m_out_vertices, vertexDistanceList[vertexDistanceList.Count - 1], vertexDistanceList[vertexDistanceList.Count - 2], vertexDistanceList[vertexDistanceList.Count - 2].dist); m_prev_status = StrokeMath.Status.Outline2; m_status = StrokeMath.Status.OutVertices; m_out_vertex = 0; break; case StrokeMath.Status.Outline1: if (m_closed) { if (m_src_vertex >= vertexDistanceList.Count) { m_prev_status = StrokeMath.Status.CloseFirst; m_status = StrokeMath.Status.EndPoly1; break; } } else { if (m_src_vertex >= vertexDistanceList.Count - 1) { m_status = StrokeMath.Status.Cap2; break; } } m_stroker.CreateJoin(m_out_vertices, vertexDistanceList.prev(m_src_vertex), vertexDistanceList.curr(m_src_vertex), vertexDistanceList.next(m_src_vertex), vertexDistanceList.prev(m_src_vertex).dist, vertexDistanceList.curr(m_src_vertex).dist); ++m_src_vertex; m_prev_status = m_status; m_status = StrokeMath.Status.OutVertices; m_out_vertex = 0; break; case StrokeMath.Status.CloseFirst: m_status = StrokeMath.Status.Outline2; cmd = VertexCmd.MoveTo; goto case StrokeMath.Status.Outline2; case StrokeMath.Status.Outline2: if (m_src_vertex <= (!m_closed ? 1 : 0)) { m_status = StrokeMath.Status.EndPoly2; m_prev_status = StrokeMath.Status.Stop; break; } --m_src_vertex; m_stroker.CreateJoin(m_out_vertices, vertexDistanceList.next(m_src_vertex), vertexDistanceList.curr(m_src_vertex), vertexDistanceList.prev(m_src_vertex), vertexDistanceList.curr(m_src_vertex).dist, vertexDistanceList.prev(m_src_vertex).dist); m_prev_status = m_status; m_status = StrokeMath.Status.OutVertices; m_out_vertex = 0; break; case StrokeMath.Status.OutVertices: if (m_out_vertex >= m_out_vertices.Count) { m_status = m_prev_status; } else { m_out_vertices.GetVertex(m_out_vertex++, out x, out y); //Vector2 c = m_out_vertices[(int)m_out_vertex++]; //x = c.x; //y = c.y; return(cmd); } break; case StrokeMath.Status.EndPoly1: m_status = m_prev_status; x = (int)EndVertexOrientation.CCW; return(VertexCmd.EndAndCloseFigure); case StrokeMath.Status.EndPoly2: m_status = m_prev_status; x = (int)EndVertexOrientation.CW; return(VertexCmd.EndAndCloseFigure); case StrokeMath.Status.Stop: cmd = VertexCmd.Stop; break; } } return(cmd); }
//======= Crossings Multiply algorithm of InsideTest ======================== // // By Eric Haines, 3D/Eye Inc, [email protected] // // This version is usually somewhat faster than the original published in // Graphics Gems IV; by turning the division for testing the X axis crossing // into a tricky multiplication test this part of the test became faster, // which had the additional effect of making the test for "both to left or // both to right" a bit slower for triangles than simply computing the // intersection each time. The main increase is in triangle testing speed, // which was about 15% faster; all other polygon complexities were pretty much // the same as before. On machines where division is very expensive (not the // case on the HP 9000 series on which I tested) this test should be much // faster overall than the old code. Your mileage may (in fact, will) vary, // depending on the machine and the test data, but in general I believe this // code is both shorter and faster. This test was inspired by unpublished // Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. // Related work by Samosky is in: // // Samosky, Joseph, "SectionView: A system for interactively specifying and // visualizing sections through three-dimensional medical image data", // M.S. Thesis, Department of Electrical Engineering and Computer Science, // Massachusetts Institute of Technology, 1993. // // Shoot a test ray along +X axis. The strategy is to compare vertex Y values // to the testing point's Y and quickly discard edges which are entirely to one // side of the test ray. Note that CONVEX and WINDING code can be added as // for the CrossingsTest() code; it is left out here for clarity. // // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point // _point_, returns 1 if inside, 0 if outside. public static bool IsPointInVxs(VertexStore vxs, double tx, double ty) { int m_num_points = vxs.Count; if (m_num_points < 3) { return(false); } // if (!m_in_polygon_check) return false; int j; bool yflag0, yflag1, inside_flag; double vtx0, vty0, vtx1, vty1; vxs.GetVertex(m_num_points, out vtx0, out vty0); //vtx0 = GetXN(m_num_points - 1); //vty0 = GetYN(m_num_points - 1); // get test bit for above/below X axis yflag0 = (vty0 >= ty); //vtx1 = GetXN(0); //vty1 = GetYN(0); vxs.GetVertex(0, out vtx1, out vty1); inside_flag = false; for (j = 1; j <= m_num_points; ++j) { yflag1 = (vty1 >= ty); // Check if endpoints straddle (are on opposite sides) of X axis // (i.e. the Y's differ); if so, +X ray could intersect this edge. // The old test also checked whether the endpoints are both to the // right or to the left of the test point. However, given the faster // intersection point computation used below, this test was found to // be a break-even proposition for most polygons and a loser for // triangles (where 50% or more of the edges which survive this test // will cross quadrants and so have to have the X intersection computed // anyway). I credit Joseph Samosky with inspiring me to try dropping // the "both left or both right" part of my code. if (yflag0 != yflag1) { // Check intersection of pgon segment with +X ray. // Note if >= point's X; if so, the ray hits it. // The division operation is avoided for the ">=" test by checking // the sign of the first vertex wrto the test point; idea inspired // by Joseph Samosky's and Mark Haigh-Hutchinson's different // polygon inclusion tests. if (((vty1 - ty) * (vtx0 - vtx1) >= (vtx1 - tx) * (vty0 - vty1)) == yflag1) { inside_flag = !inside_flag; } } // Move to the next pair of vertices, retaining info as possible. yflag0 = yflag1; vtx0 = vtx1; vty0 = vty1; int k = (j >= m_num_points) ? j - m_num_points : j; //vtx1 = GetXN(k); //vty1 = GetYN(k); vxs.GetVertex(k, out vtx1, out vty1); } return(inside_flag); }
//---------------------------------- static bool GetBoundingRect(VertexStore vxs, int[] gi, int num, out double x1, out double y1, out double x2, out double y2) { int i; double x = 0; double y = 0; bool first = true; x1 = 1; y1 = 1; x2 = 0; y2 = 0; int iterindex = 0; for (i = 0; i < num; i++) { VertexCmd flags; while ((flags = vxs.GetVertex(iterindex++, out x, out y)) != VertexCmd.Stop) { switch (flags) { //if is vertext cmd case VertexCmd.LineTo: case VertexCmd.MoveTo: case VertexCmd.P2c: case VertexCmd.P3c: { if (first) { x1 = x; y1 = y; x2 = x; y2 = y; first = false; } else { if (x < x1) { x1 = x; } if (y < y1) { y1 = y; } if (x > x2) { x2 = x; } if (y > y2) { y2 = y; } } } break; } } } return(x1 <= x2 && y1 <= y2); }