Esempio n. 1
0
        public virtual Angle SmallestAngleBetween(ILinear line)
        {
            var angle      = this.NormalVector.SmallestAngleBetween(line);
            var complement = Unit.RightAngle - angle;

            return(complement.ProperAngle());
        }
Esempio n. 2
0
        /// <summary>
        /// Projects the point onto the line.
        /// </summary>
        public Point ProjectOntoLine(ILinear projectOnto)
        {
            var vector           = this - projectOnto.BasePoint;
            var scalarProjection = vector.ScalarProjection(projectOnto.Direction);

            return(projectOnto.GetPointAlongLine(scalarProjection));
        }
Esempio n. 3
0
        private static double[,] GetMatrix(ILinear axis, Angle angle)
        {
            var rotationUnitVector = axis.Direction;

            double unitX = rotationUnitVector.X;
            double unitY = rotationUnitVector.Y;
            double unitZ = rotationUnitVector.Z;
            Angle  theta = angle;

            double sinTheta = Sine(theta);
            double cosTheta = Cosine(theta);

            double entry00 = cosTheta + unitX * unitX * (1 - cosTheta);
            double entry01 = unitX * unitY * (1 - cosTheta) - unitZ * sinTheta;
            double entry02 = unitX * unitZ * (1 - cosTheta) + unitY * sinTheta;
            double entry10 = unitY * unitX * (1 - cosTheta) + unitZ * sinTheta;
            double entry11 = cosTheta + unitY * unitY * (1 - cosTheta);
            double entry12 = unitY * unitZ * (1 - cosTheta) - unitX * sinTheta;
            double entry20 = unitZ * unitX * (1 - cosTheta) - unitY * sinTheta;
            double entry21 = unitZ * unitY * (1 - cosTheta) + unitX * sinTheta;
            double entry22 = cosTheta + unitZ * unitZ * (1 - cosTheta);

            var matrix = new double[, ]
            {
                { entry00, entry01, entry02, 0 },
                { entry10, entry11, entry12, 0 },
                { entry20, entry21, entry22, 0 },
                { 0, 0, 0, 1 },
            };

            matrix.ConjugateByTranslation(axis.BasePoint.VectorFromOrigin);
            return(matrix);
        }
Esempio n. 4
0
        public static Plane FromCoplanarLines(ILinear linear1, ILinear linear2)
        {
            var line1 = new Line(linear1);
            var line2 = new Line(linear2);

            var normal = Normal();

            return(new Plane(line1.BasePoint, normal));

            Direction Normal()
            {
                if (line1 == line2)
                {
                    throw new ArgumentException("The passed lines cannot be the same.");
                }

                if (line1.IsParallelTo(line2))
                {
                    var directionBetween = line1.BasePoint.DirectionTo(line2.BasePoint);
                    return(line1.Direction.CrossProduct(directionBetween));
                }

                if (line1.IsCoplanarWith(line2))
                {
                    return(line1.Direction.CrossProduct(line2.Direction));
                }

                throw new ArgumentException("The passed lines are not on the same plane.");
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Returns true if the passed line is in the same plane as this one, AKA if it intersects or is parallel to the other line
        /// </summary>
        /// <param name="passedLine"></param>
        /// <returns></returns>
        public static bool IsCoplanarWith(this ILinear thisLine, ILinear otherLine)
        {
            if (thisLine.BasePoint.Z == otherLine.BasePoint.Z &&
                thisLine.Direction.Z < 0.01 &&
                otherLine.Direction.Z < 0.01)
            {
                return(true);
            }

            var point1Line1 = new[] { thisLine.BasePoint.X.InInches(), thisLine.BasePoint.Y.InInches(), thisLine.BasePoint.Z.InInches() };

            var anotherPointOnLine1 = thisLine.GetPointAlongLine(1 * Unit.Inches);
            var point2Line1         = new [] { anotherPointOnLine1.X.InInches(), anotherPointOnLine1.Y.InInches(), anotherPointOnLine1.Z.InInches() };

            var point1Line2 = new [] { otherLine.BasePoint.X.InInches(), otherLine.BasePoint.Y.InInches(), otherLine.BasePoint.Z.InInches() };

            var anotherPointOnLine2 = otherLine.GetPointAlongLine(2 * Unit.Inches);
            var point2Line2         = new [] { anotherPointOnLine2.X.InInches(), anotherPointOnLine2.Y.InInches(), anotherPointOnLine2.Z.InInches() };

            var pointsMatrix = new double[4, 4];

            pointsMatrix.SetRow(0, point1Line1);
            pointsMatrix.SetRow(1, point2Line1);
            pointsMatrix.SetRow(2, point1Line2);
            pointsMatrix.SetRow(3, point2Line2);

            pointsMatrix.SetColumn(3, new double[] { 1, 1, 1, 1 });

            var determinant = Math.Abs(pointsMatrix.Determinant());

            // Tolerance is suspect given that the determinant has dimensions of (in.^4)
            return(determinant * Unit.Inches == Unit.ZeroDistance);
        }
Esempio n. 6
0
        public static Point GetPointAlongLine(this ILinear thisLine, Distance distance)
        {
            Distance newX = thisLine.BasePoint.X + distance * thisLine.Direction.X;
            Distance newY = thisLine.BasePoint.Y + distance * thisLine.Direction.Y;
            Distance newZ = thisLine.BasePoint.Z + distance * thisLine.Direction.Z;

            return(new Point(newX, newY, newZ));
        }
Esempio n. 7
0
        public static Angle CounterClockwiseAngleTo(this ILinear thisLine, ILinear otherLine, ILinear referenceNormal = null)
        {
            if (referenceNormal == null)
            {
                referenceNormal = Line.ZAxis;
            }

            return(thisLine.Direction.CounterClockwiseAngleTo(otherLine.Direction, referenceNormal.Direction));
        }
Esempio n. 8
0
 /// <summary>
 /// Makes a Perpendicular Line to this line that is in the passed plane with the same base point as this line
 /// this assumes the line is in the plane
 /// </summary>
 public static Line MakePerpendicularLineInGivenPlane(this ILinear thisLine, Plane planeToMakePerpendicularLineIn)
 {
     if (planeToMakePerpendicularLineIn.IsParallelTo(thisLine))
     {
         //rotate it 90 degrees in the nornal of the plane and it will be perpendicular to the original
         return(new Line(thisLine).Rotate(new Rotation(new Vector(thisLine.BasePoint, planeToMakePerpendicularLineIn.NormalVector), Unit.RightAngle)));
     }
     else
     {
         throw new ArgumentException("The given line is not in the given plane");
     }
 }
Esempio n. 9
0
        private static (double DistanceAlongLine1, double DistanceAlongLine2) DistanceAlongEachLineOfClosestApproach
        (
            ILinear line1,
            ILinear line2
        )
        {
            var d1                 = line1.Direction.Normalized;
            var d2                 = line2.Direction.Normalized;
            var d1_cross_d2        = d1.CrossProduct(d2);
            var o2_minus_o1        = (line2.BasePoint - line1.BasePoint).ToVectorInInches();
            var normSquared        = d1_cross_d2.NormSquared();
            var sharedCrossProduct = d1_cross_d2.CrossProduct(o2_minus_o1);
            var t1                 = d2.DotProduct(sharedCrossProduct) / normSquared;
            var t2                 = d1.DotProduct(sharedCrossProduct) / normSquared;

            return(t1, t2);
        }
Esempio n. 10
0
 public Rotation(ILinear axisOfRotation, Angle rotationAngle)
     : this(GetMatrix(axisOfRotation, rotationAngle))
 {
 }
Esempio n. 11
0
        // public
        /// <summary>
        /// Determines whether or not the two lines are perpindicular to each other, up to a given tolerance.
        /// </summary>
        /// <returns></returns>
        public static bool IsPerpendicularTo(ILinear thisLine, ILinear otherLine, Angle tolerance)
        {
            var angle = thisLine.SmallestAngleBetween(otherLine);

            return(angle.EqualsWithinTolerance(Unit.RightAngle, tolerance));
        }
Esempio n. 12
0
 public Distance SignedDistanceAlong(ILinear line) =>
 new Line(line).Contains(this)
         ? ProjectedSignedDistanceAlong(line)
         : throw new ArgumentOutOfRangeException(nameof(line), "The point should be on the line");
 /// <summary>
 /// Sorts out and returns only the lines in this list that are parallel to the passed Line
 /// </summary>
 /// <param name="passedLines">passed List of Lines</param>
 /// <param name="lineToCheckIfParallelTo">passed List of Lines</param>
 /// <returns>returns a List of Lines of only the Lines that are parallel to the passed line</returns>
 public static List <Line> OnlyLinesParallelTo(this IList <Line> passedLines, ILinear lineToCheckIfParallelTo)
 {
     return(passedLines.Where(l => l.IsParallelTo(lineToCheckIfParallelTo)).ToList());
 }
Esempio n. 14
0
 /// <summary>
 /// Default copy constructor
 /// </summary>
 public Line(ILinear toCopy)
     : this(toCopy.Direction, toCopy.BasePoint)
 {
 }
Esempio n. 15
0
 /// <summary>
 /// Returns the smaller of the two angles between these lines.
 /// </summary>
 public static Angle SmallestAngleBetween(this ILinear thisLine, ILinear otherLine)
 {
     return(thisLine.Direction.SmallestAngleBetween(otherLine.Direction));
 }
Esempio n. 16
0
 public static Line AsLine(this ILinear linear) => new Line(linear);
Esempio n. 17
0
 public static Plane PlaneThroughLineInDirectionOf(this ILinear thisLine, Direction direction)
 {
     return(Plane.FromCoplanarLines(thisLine, new Line(thisLine.BasePoint, direction)));
 }
Esempio n. 18
0
 public Rotation(Angle rotationAngle, ILinear axisOfRotation = null)
     : this(GetMatrix(axisOfRotation ?? Line.ZAxis, rotationAngle))
 {
 }
        protected static void InterpolateAttributeMaps <KeyType>(
            AttributeMapCollection <KeyType> original,
            AttributeMapCollection <KeyType> clone,
            Dictionary <KeyType, List <KeyValuePair <float, KeyType> > > keyNewToOlds
            )
        {
            /*  For all original attribute maps  */
            foreach (KeyValuePair <string, object> kvp in original.AttributeMaps)
            {
                string mapName = kvp.Key;
                object oldMap  = kvp.Value;             // real type is Dictionary<KeyType, ValueType>
                object newMap;
                Type   mapValueType = oldMap.GetType().GetGenericArguments()[1];

                if (mapName == "corner_indices")
                {
                    continue;
                }
                Type mapKeyType = oldMap.GetType().GetGenericArguments()[0];
#if false
                Debug.WriteLine("Attribute map name       : " + mapName);
                Debug.WriteLine("Attribute map key type   : " + mapKeyType.ToString());
                Debug.WriteLine("Attribute map value type : " + mapValueType.ToString());
#endif
                if (clone.AttributeMaps.ContainsKey(mapName) == true)
                {
                    //Debug.WriteLine("!");
                }
                newMap = System.Activator.CreateInstance(oldMap.GetType());
                clone.AttributeMaps[mapName] = newMap;

                IDictionary oldMapDictionary = (IDictionary)oldMap;
                IDictionary newMapDictionary = (IDictionary)newMap;

#if false
                Debug.WriteLine("Attribute map count      : " + oldMapDictionary.Count);
#endif

                /*  For each new object in keyNewToOlds.Keys  */
                foreach (var kvp2 in keyNewToOlds)
                {
                    KeyType newKey = kvp2.Key;
                    List <KeyValuePair <float, KeyType> > oldKeys = kvp2.Value;

                    //  Compute sum of weights, for normalizing
                    float sumWeights = 0.0f;
                    foreach (var kvp3 in oldKeys)
                    {
                        KeyType oldKey = kvp3.Value;
                        if (oldMapDictionary.Contains(oldKey))
                        {
                            sumWeights += kvp3.Key;
                        }
                    }
                    if (sumWeights == 0.0f)
                    {
                        continue;
                    }

                    object newValue = System.Activator.CreateInstance(mapValueType);
                    if (newValue is ILinear)
                    {
                        ILinear newLinearValue = (ILinear)newValue;
                        foreach (var kvp3 in oldKeys)
                        {
                            float   weight = kvp3.Key;
                            KeyType oldKey = kvp3.Value;
                            object  oldValue;
                            if (oldMapDictionary.Contains(oldKey))
                            {
                                oldValue = oldMapDictionary[oldKey];
                                //  TODO MUSTIFIX oldValue = null
                                ILinear oldLinearValue = (ILinear)oldValue;
                                newLinearValue.PlusWeightTimesOther(weight / sumWeights, oldLinearValue);
                            }
                            else
                            {
                                oldValue = null;
                            }
                        }
                        newMapDictionary[newKey] = newLinearValue;
                    }
                    else if (newValue is float)
                    {
                        float newFloatValue = (float)newValue;
                        foreach (var kvp3 in oldKeys)
                        {
                            float   weight = kvp3.Key;
                            KeyType oldKey = kvp3.Value;
                            if (oldMapDictionary.Contains(oldKey))
                            {
                                object oldValue      = oldMapDictionary[oldKey];
                                float  oldFloatValue = (float)oldValue;
                                newFloatValue += (weight / sumWeights) * oldFloatValue;
                            }
                            else
                            {
                                //Debug.WriteLine("!");
                            }
                        }
                        newMapDictionary[newKey] = newFloatValue;
                    }
                    else
                    {
                        //Debug.WriteLine("!");
                    }
                }
            }
        }
Esempio n. 20
0
 /// <summary>
 /// Creates a Plane that contains the passed point and line.
 /// Note: The point should not lie on the line.
 /// </summary>
 public static Plane FromPointAndLine(Point point1, ILinear linear)
 {
     return(Plane.FromCoplanarLines(new Line(point1, linear.BasePoint), linear));
 }
Esempio n. 21
0
 /// <summary>
 /// Creates a new line with the same direction but different base
 /// Useful for turning vectors, and segments back into lines.
 /// </summary>
 public Line(Point newBasePoint, ILinear line) : this(line.Direction, newBasePoint)
 {
 }
Esempio n. 22
0
 /// <summary>
 /// Returns whether or not the giving line is perpendicular to this plane
 /// </summary>
 /// <param name="passedLine"></param>
 /// <returns></returns>
 public bool IsPerpendicularTo(ILinear passedLine)
 {
     //check to see if it is parallel to the normal vector and if it is then it is perpendicular to the plane because the plane is
     //by definition perpendicular to the normal
     return(this.NormalVector.IsParallelTo(passedLine));
 }
Esempio n. 23
0
 public ILinear PlusWeightTimesOther(float weight, ILinear other)
 {
     this += weight * (Vector4)other;
     return(this);
 }
Esempio n. 24
0
        protected override IList <object> Pick(MouseEventArgs e)
        {
            bool          multiSelect = DragOverThreshold;
            List <object> paths       = new List <object>();

            HitRecord[] hits;


            if (multiSelect)
            {// frustum pick
                RectangleF rect = MakeRect(FirstMousePoint, CurrentMousePoint);
                hits = GameEngine.FrustumPick(SurfaceId, Camera.ViewMatrix, Camera.ProjectionMatrix, rect);
            }
            else
            {// ray pick
                Ray3F rayW = GetWorldRay(CurrentMousePoint);
                hits = GameEngine.RayPick(Camera.ViewMatrix, Camera.ProjectionMatrix, rayW, false);
            }

            // create unique list of hits
            HashSet <ulong>  instanceSet = new HashSet <ulong>();
            List <HitRecord> uniqueHits  = new List <HitRecord>();

            // build 'path' objects for each hit record.
            foreach (HitRecord hit in hits)
            {
                bool added = instanceSet.Add(hit.instanceId);
                if (added)
                {
                    uniqueHits.Add(hit);
                }
            }

            HitRecord firstHit = new HitRecord();


            // build 'path' objects for each hit record.
            foreach (HitRecord hit in uniqueHits)
            {
                NativeObjectAdapter nobj = GameEngine.GetAdapterFromId(hit.instanceId);
                DomNode             dom  = nobj.DomNode;
                object hitPath           = Util.AdaptDomPath(dom);
                object obj = DesignView.PickFilter.Filter(hitPath, e);
                if (obj != null)
                {
                    if (paths.Count == 0)
                    {
                        firstHit = hit;
                    }
                    var newPath = obj as AdaptablePath <object> ?? Util.AdaptDomPath((DomNode)obj);
                    paths.Add(newPath);
                }
            }


            if (multiSelect == false && paths.Count > 0)
            {
                var path = paths[0];
                ISelectionContext selection = DesignView.Context.As <ISelectionContext>();
                ILinear           linear    = path.As <ILinear>();
                if (linear != null &&
                    Control.ModifierKeys == System.Windows.Forms.Keys.Shift &&
                    selection.SelectionContains(path))
                {
                    ITransactionContext trans = DesignView.Context.As <ITransactionContext>();
                    trans.DoTransaction(
                        delegate
                    {
                        linear.InsertPoint(firstHit.index, firstHit.hitPt.X, firstHit.hitPt.Y, firstHit.hitPt.Z);
                    }, "insert control point".Localize()
                        );
                }
            }
            return(paths);
        }
Esempio n. 25
0
        public Distance ProjectedSignedDistanceAlong(ILinear line)
        {
            var basePoint = line.BasePoint;

            return((this - basePoint).ScalarProjection(line.Direction));
        }
Esempio n. 26
0
        /// <summary>
        /// Determines if two lines are parallel up to a custom angular tolerance.
        /// That is, if the lines are within that angle of each other the lines are considered "parallel"
        /// </summary>
        public static bool IsParallelTo(this ILinear thisLine, ILinear otherLine, Angle tolerance)
        {
            var angle = thisLine.SmallestAngleBetween(otherLine);

            return(angle.EqualsWithinTolerance(Unit.ZeroAngle, tolerance));
        }
Esempio n. 27
0
 public Plane(ILinear normal)
 {
     this.NormalLine = new Line(normal);
 }
Esempio n. 28
0
 /// <summary>
 /// Returns whether or not the two lines are perpendicular to each other
 /// </summary>
 /// <param name="passedLine"></param>
 /// <returns></returns>
 public static bool IsPerpendicularTo([NotNull] this ILinear thisLine, [NotNull] ILinear otherLine)
 {
     return(thisLine.SmallestAngleBetween(otherLine) == Unit.RightAngle);
 }
Esempio n. 29
0
        protected override IList <object> Pick(MouseEventArgs e)
        {
            bool          multiSelect = DragOverThreshold;
            List <object> paths       = new List <object>();

            Picking.HitRecord[] hits;

            if (multiSelect)
            {// frustum pick
                RectangleF rect    = MakeRect(FirstMousePoint, CurrentMousePoint);
                var        frustum = XLEBridgeUtils.Utils.MakeFrustumMatrix(Utils.AsCameraDesc(Camera), rect, ClientSize);
                hits = Picking.FrustumPick(
                    GameEngine.GetEngineDevice(),
                    Adapter.SceneManager, Adapter.TechniqueContext,
                    frustum, Utils.AsCameraDesc(Camera), ClientSize,
                    Picking.Flags.Objects | Picking.Flags.Helpers);
            }
            else
            {// ray pick
                Ray3F rayW = GetWorldRay(CurrentMousePoint);
                hits = Picking.RayPick(
                    GameEngine.GetEngineDevice(),
                    Adapter.SceneManager, Adapter.TechniqueContext,
                    rayW, Utils.AsCameraDesc(Camera), ClientSize,
                    Picking.Flags.Terrain | Picking.Flags.Objects | Picking.Flags.Helpers);
            }

            if (hits == null)
            {
                return(new List <object>());
            }

            // create unique list of hits
            HashSet <ulong> instanceSet = new HashSet <ulong>();
            var             uniqueHits  = new List <Picking.HitRecord>();

            // build 'path' objects for each hit record.
            foreach (var hit in hits)
            {
                bool added = instanceSet.Add(hit.instanceId);
                if (added)
                {
                    uniqueHits.Add(hit);
                }
            }

            var firstHit = new Picking.HitRecord();


            // build 'path' objects for each hit record.
            foreach (var hit in uniqueHits)
            {
                var nativeIdMapping = Globals.MEFContainer.GetExportedValue <INativeIdMapping>();
                var nobj            = nativeIdMapping.GetAdapter(hit.documentId, hit.instanceId).As <DomNodeAdapter>();
                if (nobj == null)
                {
                    continue;
                }

                DomNode dom     = nobj.DomNode;
                object  hitPath = Util.AdaptDomPath(dom);
                object  obj     = DesignView.PickFilter.Filter(hitPath, e);
                if (obj != null)
                {
                    if (paths.Count == 0)
                    {
                        firstHit = hit;
                    }
                    var newPath = obj as AdaptablePath <object> ?? Util.AdaptDomPath((DomNode)obj);
                    paths.Add(newPath);
                }
            }


            if (multiSelect == false && paths.Count > 0)
            {
                var path = paths[0];
                ISelectionContext selection = DesignView.Context.As <ISelectionContext>();
                ILinear           linear    = path.As <ILinear>();
                if (linear != null &&
                    Control.ModifierKeys == System.Windows.Forms.Keys.Shift &&
                    selection.SelectionContains(path))
                {
                    ITransactionContext trans = DesignView.Context.As <ITransactionContext>();
                    trans.DoTransaction(
                        delegate
                    {
                        linear.InsertPoint(firstHit.index, firstHit.hitPt.X, firstHit.hitPt.Y, firstHit.hitPt.Z);
                    }, "insert control point".Localize()
                        );
                }
            }
            return(paths);
        }
Esempio n. 30
0
 public Vector OrthogonalProjection(ILinear line)
 {
     return(ProjectOntoPlane(new Plane(line)));
 }