Canguro.Controller.Snap.AreaMagnet.Snap C# (CSharp) Метод

Snap() публичный Метод

public Snap ( Canguro activeView, Point mousePoint ) : float
activeView Canguro
mousePoint Point
Результат float
        public override float Snap(Canguro.View.GraphicView activeView, Point mousePoint)
        {
            // Get ray from mouse position
            Vector3 rayP1 = new Vector3(mousePoint.X, mousePoint.Y, 1f);
            Vector3 rayP2 = new Vector3(mousePoint.X, mousePoint.Y, 0f);
            activeView.Unproject(ref rayP1);
            activeView.Unproject(ref rayP2);
            Vector3 ray = rayP2 - rayP1;
            ray.Normalize();

            // Check best plane angle
            Vector3 normalTmp = normal;
            float cosAngle = Math.Abs(Vector3.Dot(ray, normal));
            if (cosAngle < 0.03f)
            {
                float xCosAngle = Math.Abs(Vector3.Dot(ray, CommonAxes.GlobalAxes[0]));
                float yCosAngle = Math.Abs(Vector3.Dot(ray, CommonAxes.GlobalAxes[1]));
                float zCosAngle = Math.Abs(Vector3.Dot(ray, CommonAxes.GlobalAxes[2]));

                if (xCosAngle >= yCosAngle)
                {
                    if (xCosAngle > zCosAngle)
                        normalTmp = CommonAxes.GlobalAxes[0];   // YZ Plane
                    else
                        normalTmp = CommonAxes.GlobalAxes[2];   // XY Plane
                }
                else if (yCosAngle > zCosAngle)
                    normalTmp = CommonAxes.GlobalAxes[1];   // XZ Plane
                else
                    normalTmp = CommonAxes.GlobalAxes[2];   // XY Plane
            }

            float r = Vector3.Dot(position - rayP1, normalTmp) / Vector3.Dot(ray, normalTmp);
            snapPosition = rayP1 + Vector3.Scale(ray, r);

            return lastSnapFitness = 0f;
        }

Usage Example

Пример #1
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);
        }