public void RecalcPrimaryDependant(Canguro.View.GraphicView activeView, PointMagnet primaryPoint, LineMagnet[] globalAxes) { if (primaryPoint != null) { // Move area to lay on the primaryPoint and to set its direction any canonic // plane (X=x, Y=y or Z=z) which is the most paralell to the screen plane position = primaryPoint.Position; // Get screen plane normal Vector3 s0 = screenNormal[0], s1 = screenNormal[1], sNormal; activeView.Unproject(ref s0); activeView.Unproject(ref s1); sNormal = s0 - s1; // Assign the area normal to the most paralell canonical plane // (giving priority to the Z plane) int maxCosIndex = 2; float cosX, cosY, cosZ; cosX = Vector3.Dot(sNormal, globalAxes[0].Direction); cosY = Vector3.Dot(sNormal, globalAxes[1].Direction); cosZ = Vector3.Dot(sNormal, globalAxes[2].Direction); if (Math.Abs(cosZ) < minZPlaneAngle) { maxCosIndex = (cosX >= cosY) ? ((cosX > cosZ) ? 0 : 2) : ((cosY > cosZ) ? 1 : 2); } normal = globalAxes[maxCosIndex].Direction; } else { position = Vector3.Empty; normal = globalAxes[2].Direction; } }
public void RecalcPrimaryDependant(Canguro.View.GraphicView activeView, PointMagnet primaryPoint) { if (primaryPoint != null) { resetGlobalAxes(primaryPoint.Position); } }
public void RecalcPrimaryDependant(Canguro.View.GraphicView activeView, PointMagnet primaryPoint, LineMagnet[] globalAxes) { if (primaryPoint != null) { // Move area to lay on the primaryPoint and to set its direction any canonic // plane (X=x, Y=y or Z=z) which is the most paralell to the screen plane position = primaryPoint.Position; // Get screen plane normal Vector3 s0 = screenNormal[0], s1 = screenNormal[1], sNormal; activeView.Unproject(ref s0); activeView.Unproject(ref s1); sNormal = s0 - s1; // Assign the area normal to the most paralell canonical plane // (giving priority to the Z plane) int maxCosIndex = 2; float cosX, cosY, cosZ; cosX = Vector3.Dot(sNormal, globalAxes[0].Direction); cosY = Vector3.Dot(sNormal, globalAxes[1].Direction); cosZ = Vector3.Dot(sNormal, globalAxes[2].Direction); if (Math.Abs(cosZ) < minZPlaneAngle) maxCosIndex = (cosX >= cosY) ? ((cosX > cosZ) ? 0 : 2) : ((cosY > cosZ) ? 1 : 2); normal = globalAxes[maxCosIndex].Direction; } else { position = Vector3.Empty; normal = globalAxes[2].Direction; } }
public override object Clone() { PointMagnet pm = new PointMagnet(); copyToMagnet(pm); pm.type = type; pm.joint = joint; return pm; }
public override object Clone() { PointMagnet pm = new PointMagnet(); copyToMagnet(pm); pm.type = type; pm.joint = joint; return(pm); }
/// <summary> /// Calculate the intersection point of two coplanar lines /// Source: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/ /// </summary> /// <param name="l1">First LineMagnet</param> /// <param name="l2">Second LineMagnet</param> /// <returns>The intersection point magnet or null if none found</returns> private PointMagnet createIntersection(LineMagnet l1, LineMagnet l2, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { if (l1 != null && l2 != null) { float numer, denom; float d1, d2, d3, d4, d5; Vector3 p13 = l1.Position - l2.Position; Vector3 p21 = l1.Direction; Vector3 p43 = l2.Direction; d1 = p13.X * p43.X + p13.Y * p43.Y + p13.Z * p43.Z; d2 = p43.X * p21.X + p43.Y * p21.Y + p43.Z * p21.Z; d3 = p13.X * p21.X + p13.Y * p21.Y + p13.Z * p21.Z; d4 = p43.X * p43.X + p43.Y * p43.Y + p43.Z * p43.Z; d5 = p21.X * p21.X + p21.Y * p21.Y + p21.Z * p21.Z; denom = d5 * d4 - d2 * d2; if (Math.Abs(denom) < float.Epsilon) { return(null); } numer = d1 * d2 - d3 * d4; float r = numer / denom; float s = (d1 + d2 * r) / d4; Vector3 pa = l1.Position + Vector3.Scale(p21, r); Vector3 pb = l2.Position + Vector3.Scale(p43, s); if ((pa - pb).Length() > 0.0001) { return(null); } // Create magnet PointMagnet intPtMagnet = new PointMagnet(pa, PointMagnetType.Intersection); if (intPtMagnet.Snap(activeView, e.Location) < SnapViewDistance) { intPtMagnet.RelatedMagnets.Add(l1); intPtMagnet.RelatedMagnets.Add(l2); return(intPtMagnet); } } return(null); }
/// <summary> /// Method to add a perpendicular point magnet if the mouse is close to where it is /// </summary> private PointMagnet addPerpendicularMagnet(LineMagnet lm, PointMagnet pm, float lmDot, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { float r = Vector3.Dot(lm.Direction, pm.Position - lm.Position) / lmDot; PointMagnet perpPtMagnet = new PointMagnet(lm.Position + Vector3.Scale(lm.Direction, r), PointMagnetType.Perpendicular); if (perpPtMagnet.Snap(activeView, e.Location) < SnapViewDistance) { perpPtMagnet.RelatedMagnets.Add(pm); perpPtMagnet.RelatedMagnets.Add(lm); points.Add(perpPtMagnet); return(perpPtMagnet); } return(null); }
/// <summary> /// This method returns a Magnet whose SnapPoint property has the point obtained either typed or clicked. /// </summary> /// <param name="prompt">The instruction text that appears at the SmallPanel.</param> /// <returns>The Magnet whose SnapPoint was found.</returns> public Snap.Magnet GetPoint(string prompt) { controller.MainFrm.SmallPanel.Start(controller.ModelCommand.Title, prompt, 10, "1,2,3 " + Culture.Get("or") + " @1,2,3"); wait(WaitingFor.Point, true); Snap.Magnet m = waitingObj as Snap.Magnet; if (m == null) { return(null); } lastPoint = m.SnapPosition; SnapPrimaryPoint = new Snap.PointMagnet(m.SnapPositionInt, Snap.PointMagnetType.SimplePoint); return(m); }
/// <summary> /// This method requests a point and returns a joint. If a joint is found, the method gets it. If not, then creates one and if the created joint lies on a line, /// then the command splits the line and adds the new line to the newLines list. /// </summary> /// <param name="newLines"> List of new lines created by this method while creating new joints </param> /// <returns> The created or found joint </returns> public Model.Joint GetJoint(IList <Model.LineElement> newLines) { Model.Joint joint; Canguro.Controller.Snap.Magnet magnet = GetPoint(); if (magnet == null) { return(null); } if (magnet is Canguro.Controller.Snap.PointMagnet && ((Canguro.Controller.Snap.PointMagnet)magnet).Joint != null) { joint = ((Canguro.Controller.Snap.PointMagnet)magnet).Joint; } else { Microsoft.DirectX.Vector3 v = magnet.SnapPosition; joint = new Canguro.Model.Joint(v.X, v.Y, v.Z); Model.JointList.Add(joint); if (magnet is Canguro.Controller.Snap.PointMagnet) { Canguro.Controller.Snap.PointMagnet pmag = (Canguro.Controller.Snap.PointMagnet)magnet; if (pmag.RelatedMagnets != null && pmag.RelatedMagnets.Count > 0) { for (int i = 0; i < pmag.RelatedMagnets.Count; i++) { if (pmag.RelatedMagnets[i] is Canguro.Controller.Snap.LineMagnet && ((Canguro.Controller.Snap.LineMagnet)pmag.RelatedMagnets[i]).Line != null) { Canguro.Commands.Model.SplitCmd.Split(((Canguro.Controller.Snap.LineMagnet)pmag.RelatedMagnets[i]).Line, joint, Model); } } } } else if (magnet is Canguro.Controller.Snap.LineMagnet) { Canguro.Controller.Snap.LineMagnet lmag = (Canguro.Controller.Snap.LineMagnet)magnet; if (lmag.Line != null) { Canguro.Commands.Model.SplitCmd.Split(((Canguro.Controller.Snap.LineMagnet)magnet).Line, joint, Model); } } } SnapPrimaryPoint = new Canguro.Controller.Snap.PointMagnet(joint); return(joint); }
/// <summary> /// Gets an interesting point by following the line in reverse (as a mirror) and trying /// to find Joints at the same distance from the LineMagnet's position /// </summary> /// <param name="lm">The Line Magnet being followed</param> /// <param name="activeView">The view in which the snap is taking place</param> /// <param name="e">The MouseEventArgs of the last MouseMove event</param> /// <returns>A point magnet with the interesting point or null if none found</returns> private PointMagnet createInterestingDistance(LineMagnet lm, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { if (lm == null) { return(null); } Vector3 pos = lm.Position; activeView.Project(ref pos); Vector3 reversePickPos = pos + pos - new Vector3(e.X, e.Y, 0f); List <Item> pickedItems = Canguro.View.GraphicViewManager.Instance.PickItem((int)reversePickPos.X, (int)reversePickPos.Y); if (pickedItems == null) { return(null); } foreach (Item item in pickedItems) { Joint j; // Check if Joint si over line lm if ((j = item as Joint) != null) { Vector3 ptInLine = Vector3.Cross(lm.Direction, j.Position - lm.Position); if (Vector3.Dot(ptInLine, ptInLine) < float.Epsilon) { PointMagnet distMagnet = new PointMagnet(lm.Position + lm.Position - j.Position, PointMagnetType.SimplePoint); distMagnet.RelatedMagnets.Add(new PointMagnet(j)); points.Add(distMagnet); return(distMagnet); } } } return(null); }
/// <summary> /// Method to try to create a midpoint magnet if the mouse is close to one /// </summary> /// <param name="lm">The Line Magnet being followed</param> /// <param name="activeView">The view in which the snap is taking place</param> /// <param name="e">The MouseEventArgs of the last MouseMove event</param> /// <returns>The MidPoint magnet or null if none found</returns> private PointMagnet createMidPoint(LineMagnet lm, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { if (lm == null) { return(null); } LineElement l; if ((l = lm.Line) != null) { PointMagnet midPtMagnet = new PointMagnet(Vector3.Scale(l.I.Position + l.J.Position, 0.5f), PointMagnetType.MidPoint); if (midPtMagnet.Snap(activeView, e.Location) < SnapViewDistance) { midPtMagnet.RelatedMagnets.Add(lm); points.Add(midPtMagnet); return(midPtMagnet); } } return(null); }
/// <summary> /// Returns a perpendicular point magnet P if there's a point X and a line L which can be united /// by a perpendicular line: /// /// L /// | /// | /// X - - - - - - - - P /// | /// | /// /// </summary> /// <param name="lm">The Line Magnet being followed</param> /// <param name="activeView">The view in which the snap is taking place</param> /// <param name="e">The MouseEventArgs of the last MouseMove event</param> /// <returns>The perpendicular point magnet or null if none found</returns> private PointMagnet createPerpendicularMagnet(LineMagnet lm, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { if (lm == null) { return(null); } float lmDot = Vector3.Dot(lm.Direction, lm.Direction); if (points.PrimaryPoint != null) { PointMagnet perp = addPerpendicularMagnet(lm, points.PrimaryPoint, lmDot, activeView, e); if (perp != null) { return(perp); } } if (points.LastPoint != null) { return(addPerpendicularMagnet(lm, points.LastPoint, lmDot, activeView, e)); } return(null); }
/// <summary> /// This method returns a vector (displacement) obtained by user input, /// either from clicking or typing. The input works by asking for a /// basepoint and then for a second point, which can be typed with absolute /// or relative coordinates. The difference between the 2 points is returned. /// </summary> /// <param name="v">The vector (diplacement) to be returned or Vector3.Empty if /// no vector could be obtained.</param> /// <returns>True if a valid vector (displacement) could be obtained, false otherwise.</returns> public bool GetVector(out Microsoft.DirectX.Vector3 v) { Snap.Magnet m1, m2; // Ask for 1st point if ((m1 = GetPoint(Culture.Get("getVector1"))) == null) { v = Microsoft.DirectX.Vector3.Empty; return(false); } // Activate vector Tracking Tracking.TrackingService ts = TrackingService; TrackingService = Tracking.VectorTrackingService.Instance; Microsoft.DirectX.Vector3 origin = m1.SnapPositionInt; TrackingService.SetPoint(origin); SnapPrimaryPoint = new Canguro.Controller.Snap.PointMagnet(origin, Canguro.Controller.Snap.PointMagnetType.SimplePoint); // Ask for 2nd point if ((m2 = GetPoint(Culture.Get("getVector2"))) == null) { v = Microsoft.DirectX.Vector3.Empty; TrackingService = ts; return(false); } SnapPrimaryPoint = new Canguro.Controller.Snap.PointMagnet(m2.SnapPositionInt, Canguro.Controller.Snap.PointMagnetType.SimplePoint); // Calculate and return difference v = m2.SnapPositionInt - origin; Model.UnitSystem.UnitSystem us = Canguro.Model.UnitSystem.UnitSystemsManager.Instance.CurrentSystem; v.X = us.FromInternational(v.X, Canguro.Model.UnitSystem.Units.Distance); v.Y = us.FromInternational(v.Y, Canguro.Model.UnitSystem.Units.Distance); v.Z = us.FromInternational(v.Z, Canguro.Model.UnitSystem.Units.Distance); TrackingService = ts; return(true); }
/// <summary> /// Method that responds to the EnterData event of SmallPanel. /// The text input by the user on the SmallPanel's TextBox (data) is /// parsed here. If the input is successfull locks are released and /// execution continues normally, i.e.: waitingObj is assigned to the /// refered object and the selectionFilter is set to None. Otherwise, /// the input is rejected. /// </summary> /// <param name="sender">Usually, the SmallPanel in MainFrm</param> /// <param name="e">Event args with the user input</param> void onEnterData(object sender, Canguro.View.EnterDataEventArgs e) { char[] charSeparators = new char[] {',', ';', ' ', '\t', '@'}; waitingObj = null; switch (selectionFilter) { case WaitingFor.Point: if (!string.IsNullOrEmpty(e.Data)) { bool relativePt = false; string trimmedPt = e.Data.Trim(); if (trimmedPt.Length > 0 && trimmedPt[0] == '@') relativePt = true; string[] pt = trimmedPt.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); Microsoft.DirectX.Vector3 v; try { if (pt.Length != 3) throw new FormatException(); v = new Microsoft.DirectX.Vector3( float.Parse(pt[0]), float.Parse(pt[1]), float.Parse(pt[2])); if (relativePt) v += lastPoint; } catch (FormatException) { System.Windows.Forms.MessageBox.Show( Culture.Get("enterDataError") + "'" + Culture.Get("enterDataPoint") + "'", Culture.Get("enterDataErrorTitle"), System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return; } waitingObj = new Snap.PointMagnet(v); } selectionFilter = WaitingFor.None; break; case WaitingFor.Joint: parseItem(e.Data, Canguro.Model.Model.Instance.JointList, Culture.Get("enterDataJoint")); break; case WaitingFor.Line: parseItem(e.Data, Canguro.Model.Model.Instance.LineList, Culture.Get("enterDataLine")); break; case WaitingFor.Area: parseItem(e.Data, Canguro.Model.Model.Instance.AreaList, Culture.Get("enterDataArea")); break; case WaitingFor.Text: waitingObj = e.Data; selectionFilter = WaitingFor.None; break; case WaitingFor.SimpleValue: try { waitingObj = float.Parse(e.Data); selectionFilter = WaitingFor.None; } catch (FormatException) { System.Windows.Forms.MessageBox.Show( Culture.Get("enterDataError") + "'" + Culture.Get("enterDataSimpleValue") + "'", Culture.Get("enterDataErrorTitle"), System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return; } break; case WaitingFor.Any: case WaitingFor.Many: case WaitingFor.None: break; default: throw new NotImplementedException("CommandServices.onEnterData"); } }
/// <summary> /// This method returns a Magnet whose SnapPoint property has the point obtained either typed or clicked. /// </summary> /// <param name="prompt">The instruction text that appears at the SmallPanel.</param> /// <returns>The Magnet whose SnapPoint was found.</returns> public Snap.Magnet GetPoint(string prompt) { controller.MainFrm.SmallPanel.Start(controller.ModelCommand.Title, prompt, 10, "1,2,3 " + Culture.Get("or") + " @1,2,3"); wait(WaitingFor.Point, true); Snap.Magnet m = waitingObj as Snap.Magnet; if (m == null) return null; lastPoint = m.SnapPosition; SnapPrimaryPoint = new Snap.PointMagnet(m.SnapPositionInt, Snap.PointMagnetType.SimplePoint); return m; }
/// <summary> /// Method to perform calculations based on the user interaction by /// moving the mouse /// </summary> /// <param name="sender">The object calling this method</param> /// <param name="e">The Mouse event args</param> /// <returns>A boolean indicating whether a repaint is necessary</returns> public bool MouseMove(GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { bool ret = true; paintMagnets.Clear(); pickItems(e); recalcPrimaryDependant(activeView); // Check snap to acquired magnets points.Snap(activeView, e); lines.Snap(activeView, e); // Get max snap Magnet (the one closer to the mouse position) Magnet bestMagnet; float snap, bestSnap, bestPointSnap = points.GetBestSnap(out bestMagnet); if (bestMagnet == null) { bestSnap = lines.GetBestSnap(out bestMagnet); } else { bestSnap = bestPointSnap; } // Update CurrentLine's positions if mouse moved over any of it's joints (if LineMagnet has a Line) if (lines.CurrentLine != null && bestMagnet != null && bestMagnet is PointMagnet && lines.CurrentLine.Line != null && ((PointMagnet)bestMagnet).Joint != null) { Joint newJoint = ((PointMagnet)bestMagnet).Joint; if (newJoint == lines.CurrentLine.Line.I || newJoint == lines.CurrentLine.Line.J) { lines.CurrentLine.Position = newJoint.Position; } } #region Intersection // Check intersections between LineMagnets. If any, create corresponding Magnet if (lines.CurrentLine != null && bestMagnet is LineMagnet && bestMagnet != lines.CurrentLine) { PointMagnet intersectionMagnet = createIntersection(lines.CurrentLine, bestMagnet as LineMagnet, activeView, e); if (intersectionMagnet != null) { snap = intersectionMagnet.Snap(activeView, e.Location) + SnapEpsilon; if (snap < SnapViewDistance) { // Paint helper line paintMagnets.Add(bestMagnet); // Paint intersection paintMagnets.Add(intersectionMagnet); } if (snap < bestPointSnap && snap < EffectiveSnapDistance) { bestSnap = snap; bestMagnet = intersectionMagnet; } } } #endregion #region Midpoint // Create midpoint magnet (if mouse is close to a Line) foreach (Magnet m in lines) { PointMagnet midMagnet = createMidPoint(m as LineMagnet, activeView, e); if (midMagnet != null) { snap = midMagnet.Snap(activeView, e.Location) + SnapEpsilon; if (snap < bestPointSnap && snap < EffectiveSnapDistance) { bestSnap = snap; bestMagnet = midMagnet; } } } #endregion #region Perpendicular point // Create perpendicular magnets (if mouse is close to a line) PointMagnet perpMagnet = createPerpendicularMagnet(bestMagnet as LineMagnet, activeView, e); if (perpMagnet != null) { snap = perpMagnet.Snap(activeView, e.Location) + SnapEpsilon; if (snap < (bestPointSnap - SnapEpsilon) && snap < EffectiveSnapDistance) { bestSnap = snap; bestMagnet = perpMagnet; } } #endregion #region Interesting Distance // If following a LineMagnet, then set next interesting distance as a PointMagnet PointMagnet distMagnet = createInterestingDistance(bestMagnet as LineMagnet, activeView, e); if (distMagnet != null) { snap = distMagnet.Snap(activeView, e.Location) + SnapEpsilon; if (snap < bestPointSnap) { bestSnap = snap; bestMagnet = distMagnet; } } #endregion // Choose magnets to paint if ((bestMagnet is LineMagnet) && (lines.CurrentLine == null)) { lines.CurrentLine = (LineMagnet)bestMagnet; } else if ((bestMagnet != null) && !bestMagnet.Equals(lines.CurrentLine)) { paintMagnets.Add(bestMagnet); } // Set the Magnet to snap to if the user clicks the mouse snapMagnet = null; if (bestMagnet != null) { if (bestMagnet is PointMagnet && bestMagnet.LastSnapFitness < EffectiveSnapDistance) { snapMagnet = bestMagnet; } else if (lines.CurrentLine != null) { snapMagnet = lines.CurrentLine; } else if (bestMagnet is LineMagnet) { snapMagnet = bestMagnet; } } else { area.Snap(activeView, e.Location); snapMagnet = (Magnet)area.Clone(); } // TODO: Probably change the IsActive property to some enum, so as to activate snapping to // specific objects only (i.e. Joint snapping when CommandServices.GetJoint() is working) return(ret); }
/// <summary> /// Method to try to create a midpoint magnet if the mouse is close to one /// </summary> /// <param name="lm">The Line Magnet being followed</param> /// <param name="activeView">The view in which the snap is taking place</param> /// <param name="e">The MouseEventArgs of the last MouseMove event</param> /// <returns>The MidPoint magnet or null if none found</returns> private PointMagnet createMidPoint(LineMagnet lm, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { if (lm == null) return null; LineElement l; if ((l = lm.Line) != null) { PointMagnet midPtMagnet = new PointMagnet(Vector3.Scale(l.I.Position + l.J.Position, 0.5f), PointMagnetType.MidPoint); if (midPtMagnet.Snap(activeView, e.Location) < SnapViewDistance) { midPtMagnet.RelatedMagnets.Add(lm); points.Add(midPtMagnet); return midPtMagnet; } } return null; }
/// <summary> /// Calculate the intersection point of two coplanar lines /// Source: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/ /// </summary> /// <param name="l1">First LineMagnet</param> /// <param name="l2">Second LineMagnet</param> /// <returns>The intersection point magnet or null if none found</returns> private PointMagnet createIntersection(LineMagnet l1, LineMagnet l2, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { if (l1 != null && l2 != null) { float numer, denom; float d1, d2, d3, d4, d5; Vector3 p13 = l1.Position - l2.Position; Vector3 p21 = l1.Direction; Vector3 p43 = l2.Direction; d1 = p13.X * p43.X + p13.Y * p43.Y + p13.Z * p43.Z; d2 = p43.X * p21.X + p43.Y * p21.Y + p43.Z * p21.Z; d3 = p13.X * p21.X + p13.Y * p21.Y + p13.Z * p21.Z; d4 = p43.X * p43.X + p43.Y * p43.Y + p43.Z * p43.Z; d5 = p21.X * p21.X + p21.Y * p21.Y + p21.Z * p21.Z; denom = d5 * d4 - d2 * d2; if (Math.Abs(denom) < float.Epsilon) return null; numer = d1 * d2 - d3 * d4; float r = numer / denom; float s = (d1 + d2 * r) / d4; Vector3 pa = l1.Position + Vector3.Scale(p21, r); Vector3 pb = l2.Position + Vector3.Scale(p43, s); if ((pa - pb).Length() > 0.0001) return null; // Create magnet PointMagnet intPtMagnet = new PointMagnet(pa, PointMagnetType.Intersection); if (intPtMagnet.Snap(activeView, e.Location) < SnapViewDistance) { intPtMagnet.RelatedMagnets.Add(l1); intPtMagnet.RelatedMagnets.Add(l2); return intPtMagnet; } } return null; }
/// <summary> /// Gets an interesting point by following the line in reverse (as a mirror) and trying /// to find Joints at the same distance from the LineMagnet's position /// </summary> /// <param name="lm">The Line Magnet being followed</param> /// <param name="activeView">The view in which the snap is taking place</param> /// <param name="e">The MouseEventArgs of the last MouseMove event</param> /// <returns>A point magnet with the interesting point or null if none found</returns> private PointMagnet createInterestingDistance(LineMagnet lm, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { if (lm == null) return null; Vector3 pos = lm.Position; activeView.Project(ref pos); Vector3 reversePickPos = pos + pos - new Vector3(e.X, e.Y, 0f); List<Item> pickedItems = Canguro.View.GraphicViewManager.Instance.PickItem((int)reversePickPos.X, (int)reversePickPos.Y); if (pickedItems == null) return null; foreach (Item item in pickedItems) { Joint j; // Check if Joint si over line lm if ((j = item as Joint) != null) { Vector3 ptInLine = Vector3.Cross(lm.Direction, j.Position - lm.Position); if (Vector3.Dot(ptInLine, ptInLine) < float.Epsilon) { PointMagnet distMagnet = new PointMagnet(lm.Position + lm.Position - j.Position, PointMagnetType.SimplePoint); distMagnet.RelatedMagnets.Add(new PointMagnet(j)); points.Add(distMagnet); return distMagnet; } } } return null; }
/// <summary> /// Method to add a perpendicular point magnet if the mouse is close to where it is /// </summary> private PointMagnet addPerpendicularMagnet(LineMagnet lm, PointMagnet pm, float lmDot, GraphicView activeView, System.Windows.Forms.MouseEventArgs e) { float r = Vector3.Dot(lm.Direction, pm.Position - lm.Position) / lmDot; PointMagnet perpPtMagnet = new PointMagnet(lm.Position + Vector3.Scale(lm.Direction, r), PointMagnetType.Perpendicular); if (perpPtMagnet.Snap(activeView, e.Location) < SnapViewDistance) { perpPtMagnet.RelatedMagnets.Add(pm); perpPtMagnet.RelatedMagnets.Add(lm); points.Add(perpPtMagnet); return perpPtMagnet; } return null; }