コード例 #1
0
        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;
            }
        }
コード例 #2
0
 public void RecalcPrimaryDependant(Canguro.View.GraphicView activeView, PointMagnet primaryPoint)
 {
     if (primaryPoint != null)
     {
         resetGlobalAxes(primaryPoint.Position);
     }
 }
コード例 #3
0
        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;
            }
        }
コード例 #4
0
        public override object Clone()
        {
            PointMagnet pm = new PointMagnet();
            copyToMagnet(pm);
            pm.type = type;
            pm.joint = joint;

            return pm;
        }
コード例 #5
0
        public override object Clone()
        {
            PointMagnet pm = new PointMagnet();

            copyToMagnet(pm);
            pm.type  = type;
            pm.joint = joint;

            return(pm);
        }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        /// <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);
        }
コード例 #13
0
        /// <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);
        }
コード例 #14
0
        /// <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");
            }
        }
コード例 #15
0
        /// <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;
        }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
        /// <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;
        }
コード例 #18
0
        /// <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;
        }
コード例 #19
0
        /// <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;
        }
コード例 #20
0
        /// <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;
        }