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 bool Equals(object obj) { LineMagnet lm = obj as LineMagnet; if (lm != null) { if (line == null && lm.line == null) { if (direction == lm.direction) { return(true); } else { return(false); } } else if ((line != null && lm.line == null) || (line == null && lm.line != null)) { return(false); } else if (line != null && lm.line != null) { return(line == lm.line); } } return(line == obj); }
public override object Clone() { LineMagnet lm = new LineMagnet(); copyToMagnet(lm); lm.direction = direction; lm.line = line; lm.snapPosition = snapPosition; lm.type = type; return lm; }
public override object Clone() { LineMagnet lm = new LineMagnet(); copyToMagnet(lm); lm.direction = direction; lm.line = line; lm.snapPosition = snapPosition; lm.type = type; return(lm); }
/// <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> /// 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> /// 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> /// 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> /// 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; }