/// <summary> /// Determines whether the object represented by the OverlayShape item can be /// given a reference to. This is the case, e.g., for standard coordinates. It is /// however not the case for the coordinates in a smooth curve. /// </summary> /// <param name="item"></param> /// <returns></returns> protected bool IsReferenceable(OverlayShape item) { if (!(item is OverlayNode)) { return(false); } Tikz_XYItem it = (item as OverlayNode).tikzitem; // check whether item occurs in smooth curve // we check whether the parent's parent has the word "coordinates" preceding the parent (this is a bit of a hack) if (it is Tikz_Coord && (it.parent.parent is Tikz_Path)) { Tikz_Path grandpa = it.parent.parent as Tikz_Path; for (int i = grandpa.Children.IndexOf(it.parent) - 1; i > 0; i--) { if (!(grandpa.Children[i] is Tikz_Something)) { break; } if (grandpa.Children[i].text.ToLower().Contains("coordinates")) { return(false); } } } return(true); }
/// <summary> /// Tries to find the referencable node (with a name) corresponding to a given coordinate. /// If no such node exists, null is returned. /// </summary> /// <param name="item"></param> /// <returns></returns> public static Tikz_Node GetReferenceableNode(Tikz_XYItem item, Tikz_Picture tpict) { if (item == null || tpict == null) { return(null); } if (item is Tikz_Node) { Tikz_Node n = item as Tikz_Node; if (n.name == null || n.name.Trim() == "") { return(null); } else { return(n); } } else if (item is Tikz_Coord || item is Tikz_Arc) { // find the next node for (int i = item.parent.Children.IndexOf(item) + 1; i < item.parent.Children.Count; i++) { if (item.parent.Children[i] is Tikz_Node) { Tikz_Node n = item.parent.Children[i] as Tikz_Node; // check if the node is really at the same position as the coordinate item if (n.coord == null) { if (n.name != null && n.name.Trim() != "") { return(n); } continue; } else { return(null); } } if (!(item.parent.Children[i] is Tikz_Something)) { break; } } // if we get here, nothing was found return(null); } else { return(null); //throw new NotImplementedException("MakeReferenceableNode not implemented for this type"); } }
/// <summary> /// Takes an XYItem (like (2,2) or a node) and tries to make it into a referenceable node /// (i.e, one with a name) /// /// Concretely, the routine does the following: /// - if item is a named node, return item. /// - if item is an unnamed node, give it a unique name and return item. /// - if item is a coordinate, see if there is a node at this coordinate /// (algorithm: see if next non-tikz_something item is a node) /// - if yes, start anew with item=this node /// - if no, add a named node at the specified coordinate /// </summary> /// <param name="item"></param> /// <returns></returns> protected Tikz_Node MakeReferenceableNode(Tikz_XYItem item) { Tikz_Picture tpict = overlay.ParseTree.GetTikzPicture(); if (item is Tikz_Node) { Tikz_Node n = item as Tikz_Node; if (n.name == "") { n.SetName(tpict.GetUniqueName()); n.UpdateText(); } return(n); } else if (item is Tikz_Coord) { // find the next node for (int i = item.parent.Children.IndexOf(item) + 1; i < item.parent.Children.Count; i++) { if (item.parent.Children[i] is Tikz_Node) { // check if the node is really at the same position as the coordinate item if ((item.parent.Children[i] as Tikz_Node).coord == null) { return(MakeReferenceableNode(item.parent.Children[i] as Tikz_Node)); } else { break; } } if (!(item.parent.Children[i] is Tikz_Something)) { break; } } // if we get here, nothing was found => add a new node Tikz_Something ws = new Tikz_Something(" "); Tikz_Node n = new Tikz_Node(); n.coord = null; item.parent.InsertChildAt(ws, item.parent.Children.IndexOf(item) + 1); item.parent.InsertChildAt(n, item.parent.Children.IndexOf(item) + 2); n.SetName(tpict.GetUniqueName()); n.UpdateText(); return(n); } else { throw new NotImplementedException("MakeReferenceableNode not implemented for this type"); } }
bool FillNodesOnArc() { TikzContainerParseItem pa = curDragged.item.parent; if (!(curDragged.item is Tikz_XYItem)) { return(false); } Tikz_XYItem cur = curDragged.item as Tikz_XYItem; nodesOnArc.Clear(); nodesOnArc.Add(cur); // find all arcs to the right for (int i = pa.Children.IndexOf(cur) + 1; i < pa.Children.Count; i++) { if (pa.Children[i] is Tikz_Arc) { nodesOnArc.Add(pa.Children[i] as Tikz_Arc); } else if (pa.Children[i].ChangesCurPoint()) { break; } } // find all arcs to left, including startpoint if (cur is Tikz_Arc) { for (int i = pa.Children.IndexOf(cur) - 1; i >= 0; i--) { if (pa.Children[i] is Tikz_Arc) { nodesOnArc.Insert(0, pa.Children[i] as Tikz_Arc); } else if (pa.Children[i].ChangesCurPoint()) { if (pa.Children[i] is Tikz_XYItem) { nodesOnArc.Insert(0, pa.Children[i] as Tikz_XYItem); } break; } } } // todo: no startpoint present... if (nodesOnArc.First() is Tikz_Arc) { } // compute radius and center // in absolute tikz coordinates Point center, p; double R; Tikz_Arc ta; if (cur is Tikz_Arc) { ta = cur as Tikz_Arc; } else if (nodesOnArc.Count > 1 && nodesOnArc[1] is Tikz_Arc) { ta = nodesOnArc[1] as Tikz_Arc; } else { return(false); } if (!ta.GetArcCenterAbs(out center) || !ta.GetAbsPos(out p)) { throw new Exception("ArcEditTool: Invalid coordinate discovered."); } R = (p - center).Length; // throw out all items with non-fitting parameters for (int i = nodesOnArc.Count - 1; i >= 0; i--) { if (nodesOnArc[i] is Tikz_Arc) { Point cc, pp; double RR; if (!(nodesOnArc[i] as Tikz_Arc).GetArcCenterAbs(out cc) || !nodesOnArc[i].GetAbsPos(out pp)) { throw new Exception("ArcEditTool: Invalid coordinate discovered."); } RR = (cc - pp).Length; if ((cc - center).Length > 1e-3 || Math.Abs(RR - R) > 1e-3) { nodesOnArc.RemoveAt(i); } } else // other Tikz_XYItem, namely startpoint { Point pp; if (!nodesOnArc[i].GetAbsPos(out pp)) { throw new Exception("ArcEditTool: Invalid coordinate discovered."); } // check if pooint lies on circle if (Math.Abs(R - (pp - center).Length) > 1e-3) { nodesOnArc.RemoveAt(i); } } } curDraggedInd = nodesOnArc.IndexOf(cur); PreviewArc.Center = overlay.TikzToScreen(center, true); center_tikz = center; // Fill the PreviewArcs Spokes array List <double> spokes = new List <double>(); for (int i = 0; i < nodesOnArc.Count; i++) { if (nodesOnArc[i] is Tikz_Arc) { Tikz_Arc tia = nodesOnArc[i] as Tikz_Arc; double a1 = tia.phi1.GetInCM() * Math.PI / 180, a2 = tia.phi2.GetInCM() * Math.PI / 180; //if (!(spokes.Count > 0 && spokes.Last() == a1)) // spokes.Add(a1); spokes.Add(a2); //Point pp; //if (!nodesOnArc[i].GetAbsPos(out pp)) // throw new Exception("ArcEditTool: Invalid coordinate discovered."); //Vector v = pp - center; } else { // should go here at most for the first item in list double a1 = (nodesOnArc[1] as Tikz_Arc).phi1.GetInCM() * Math.PI / 180; spokes.Add(a1); } } PreviewArc.Spokes = spokes; return(true); }
public void SetCorrectRaster(TikzParseItem tpi, bool IsParent = false) { if (ParseTree == null) { return; } if (tpi == null) { Tikz_Picture tp = ParseTree.GetTikzPicture(); if (tp != null) { TikzMatrix M; if (!tp.GetCurrentTransformAt(null, out M)) { Rasterizer.View.CoordinateTransform = new TikzMatrix(); // if the program gets here, the global coord. transformation could not be understood->ovelay should display nothing } else { Rasterizer.View.CoordinateTransform = M; } //rasterizer.RasterOrigin = M.Transform(new Point(0, 0)); //rasterizer.RasterScale = M.m[1, 1]; Rasterizer.View.IsCartesian = !UsePolarCoordinates; } } else if (tpi is Tikz_Scope) { Tikz_Scope ts = tpi as Tikz_Scope; TikzMatrix M; if (IsParent) { if (!ts.GetCurrentTransformAt(null, out M)) // todo { M = new TikzMatrix(); // broken coords-> take unity as backup } } else { //if (!ts.parent.GetCurrentTransformAt(ts, out M)) // M = new TikzMatrix(); if (!ts.GetRasterTransform(out M)) { M = new TikzMatrix(); } } Rasterizer.View.CoordinateTransform = M; //rasterizer.RasterOrigin = M.Transform(new Point(0, 0)); //rasterizer.RasterScale = M.m[1, 1]; Rasterizer.View.IsCartesian = !IsParent || !UsePolarCoordinates; } else if (tpi is Tikz_XYItem) { Tikz_XYItem t = tpi as Tikz_XYItem; Point offset; if (t.GetAbsPos(out offset, true)) { TikzMatrix M; if (!t.parent.GetCurrentTransformAt(t, out M)) //.CloneIt(); { M = new TikzMatrix(); } M.m[0, 2] = offset.X; M.m[1, 2] = offset.Y; //rasterizer.RasterScale = M.m[1, 1]; Rasterizer.View.CoordinateTransform = M; Rasterizer.View.IsCartesian = !(t.IsPolar()); } else { throw new Exception("In PdfOverlay: Encountered drawn item without valid coordinates"); } } else if (tpi is Tikz_Path) { Tikz_Path ts = tpi as Tikz_Path; TikzMatrix M; if (IsParent) { Point curPointAtEnd; if (!ts.GetCurrentTransformAt(null, out M)) // todo { M = new TikzMatrix(); // broken coords-> take unity as backup } if (ts.GetAbsOffset(out curPointAtEnd, null)) { M.m[0, 2] = curPointAtEnd.X; M.m[1, 2] = curPointAtEnd.Y; } } else { if (!ts.parent.GetCurrentTransformAt(ts, out M)) { M = new TikzMatrix(); } //if (!ts.GetRasterTransform(out M)) // M = new TikzMatrix(); } Rasterizer.View.CoordinateTransform = M; //rasterizer.RasterOrigin = M.Transform(new Point(0, 0)); //rasterizer.RasterScale = M.m[1, 1]; Rasterizer.View.IsCartesian = !IsParent || !UsePolarCoordinates; } else { Debug.WriteLine("Error in SetCorrectRaster: unsupported type");//Rasterizer.IsCartesian = true; // should not get here } }