コード例 #1
0
 /// <summary>
 /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.SameGeometry (BoundingRect, ISurface, BoundingRect, double, out ModOp2D)"/>
 /// </summary>
 /// <param name="thisBounds"></param>
 /// <param name="other"></param>
 /// <param name="otherBounds"></param>
 /// <param name="precision"></param>
 /// <param name="firstToSecond"></param>
 /// <returns></returns>
 public override bool SameGeometry(BoundingRect thisBounds, ISurface other, BoundingRect otherBounds, double precision, out ModOp2D firstToSecond)
 {
     firstToSecond = ModOp2D.Null;
     if (other is PlaneSurface)
     {
         PlaneSurface second = other as PlaneSurface;
         GeoPoint     p      = PointAt(thisBounds.GetCenter());
         if (Math.Abs(second.Plane.Distance(p)) > precision)
         {
             return(false);
         }
         p = second.PointAt(otherBounds.GetCenter());
         if (Math.Abs(Plane.Distance(p)) > precision)
         {
             return(false);
         }
         if (Precision.SameDirection(Normal, second.Normal, false))
         {
             GeoPoint2D[] src = new GeoPoint2D[] { GeoPoint2D.Origin, new GeoPoint2D(1, 0), new GeoPoint2D(0, 1) };
             GeoPoint2D[] dst = new GeoPoint2D[3];
             for (int i = 0; i < 3; ++i)
             {
                 dst[i] = second.PositionOf(PointAt(src[i]));
             }
             firstToSecond = ModOp2D.Fit(src, dst, true);
             return(true);
         }
         else
         {
             return(false);
         }
     }
     return(base.SameGeometry(thisBounds, other, otherBounds, precision, out firstToSecond));
 }
コード例 #2
0
 /// <summary>
 /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.SameGeometry (BoundingRect, ISurface, BoundingRect, double, out ModOp2D)"/>
 /// </summary>
 /// <param name="thisBounds"></param>
 /// <param name="other"></param>
 /// <param name="otherBounds"></param>
 /// <param name="precision"></param>
 /// <param name="firstToSecond"></param>
 /// <returns></returns>
 public override bool SameGeometry(BoundingRect thisBounds, ISurface other, BoundingRect otherBounds, double precision, out ModOp2D firstToSecond)
 {
     if (other is SurfaceOfLinearExtrusion)
     {
         firstToSecond = ModOp2D.Null;
         SurfaceOfLinearExtrusion sleother = other as SurfaceOfLinearExtrusion;
         // es würde genügen, wenn die beiden Kurven sich überlappen. Dann auf das Überlappungsintervall testen
         bool reverse;
         if (!Curves.SameGeometry(BasisCurve, sleother.BasisCurve, precision, out reverse))
         {
             return(false);
         }
         // zwei Extrempunkte bestimmen, damit sollte es OK sein
         GeoPoint2D uv1 = new GeoPoint2D(curveStartParameter, 0.0);
         GeoPoint   p1  = PointAt(uv1);
         GeoPoint2D uv2 = sleother.PositionOf(p1);
         GeoPoint   p2  = sleother.PointAt(uv2);
         if ((p1 | p2) > precision)
         {
             return(false);
         }
         uv1 = new GeoPoint2D(curveEndParameter, 1.0);
         p1  = PointAt(uv1);
         uv2 = sleother.PositionOf(p1);
         p2  = sleother.PointAt(uv2);
         if ((p1 | p2) > precision)
         {
             return(false);
         }
         firstToSecond = ModOp2D.Translate(uv2 - uv1);
         return(true);
     }
     return(base.SameGeometry(thisBounds, other, otherBounds, precision, out firstToSecond));
 }
コード例 #3
0
        void IView.ZoomToRect(BoundingRect World2D)
        {
            Rectangle screen = (this as IView).DisplayRectangle;
            double    factor;

            // Höhe und Breite==0 soll einen Fehler liefern!
            if (World2D.Height == 0.0)
            {
                factor = screen.Width / World2D.Width;
            }
            else if (World2D.Width == 0.0)
            {
                factor = screen.Height / World2D.Height;
            }
            else
            {
                factor = Math.Min(screen.Width / World2D.Width, screen.Height / World2D.Height);
            }
            // wie ist das mit der Y-Richtung in screen?
            double dx = (screen.Right + screen.Left) / 2.0 - (World2D.Right + World2D.Left) / 2.0 * factor;
            double dy = (screen.Top + screen.Bottom) / 2.0 + (World2D.Top + World2D.Bottom) / 2.0 * factor;

            layoutToScreen = new ModOp2D(factor, 0.0, dx, 0.0, -factor, dy);
            screenToLayout = layoutToScreen.GetInverse(); // ginge auch einfacher
        }
コード例 #4
0
        // eigentlich eine Untergruppe für alle Patches

        public LayoutView(Layout layout, Project project)
        {
            this.project    = project;
            this.layout     = layout;
            screenToLayout  = layoutToScreen = ModOp2D.Null;
            base.resourceId = "LayoutView";
            // printDocument = project.printDocument;
            printDocument = new PrintDocument();

            if (printDocument != null)
            {
                if (layout.pageSettings != null)
                {
                    printDocument.DefaultPageSettings = layout.pageSettings;
                }
                else
                {
                    if (project.printDocument != null)
                    {
                        printDocument.DefaultPageSettings = (PageSettings)project.printDocument.DefaultPageSettings.Clone();
                    }
                    else
                    {
                        printDocument.DefaultPageSettings.Landscape = layout.PaperWidth > layout.PaperHeight;
                    }
                }
            }
        }
コード例 #5
0
        public static EllipseArc2D Create(GeoPoint2D center, GeoVector2D majorAxis, GeoVector2D minorAxis, GeoPoint2D startPoint, GeoPoint2D endPoint, bool counterClock)
        {
            // bestimme die beiden Winkel
            GeoVector2D majAx;
            GeoVector2D minAx;
            GeoPoint2D  left, right, bottom, top;

            Geometry.PrincipalAxis(center, majorAxis, minorAxis, out majAx, out minAx, out left, out right, out bottom, out top, false);
            ModOp2D    toUnit = ModOp2D.Fit(new GeoPoint2D[] { center, center + majAx, center + minAx }, new GeoPoint2D[] { GeoPoint2D.Origin, GeoPoint2D.Origin + GeoVector2D.XAxis, GeoPoint2D.Origin + GeoVector2D.YAxis }, true);
            GeoPoint2D p      = toUnit * startPoint;
            double     sa     = p.ToVector().Angle.Radian;

            p = toUnit * endPoint;
            double ea = p.ToVector().Angle.Radian;
            double sw;

            if (counterClock)
            {
                sw = ea - sa;
                if (sw <= 0.0)
                {
                    sw += Math.PI * 2.0;            // geändert auf <= bzw. >=, da sonst aus Vollkreisen Leerkreise werden
                }
            }
            else
            {
                sw = ea - sa;
                if (sw >= 0.0)
                {
                    sw -= Math.PI * 2.0;
                }
            }
            return(new EllipseArc2D(center, majAx, minAx, sa, sw, left, right, bottom, top));
        }
コード例 #6
0
        public override ICurve2D GetModified(ModOp2D m)
        {
            Polyline2D res = this.Clone() as Polyline2D;

            res.Modify(m);
            return(res);
        }
コード例 #7
0
 public void Modify(ModOp2D m) // gehört das nicht in das ICurve Interface?
 {
     for (int i = 0; i < vertex.Length; ++i)
     {
         vertex[i] = m * vertex[i];
     }
 }
コード例 #8
0
ファイル: Ellipse2D.cs プロジェクト: SOFAgh/CADability
        private Plane zPosition; // die Raum-Ebene, in deren Mittelpunkt der Kreis bezüglich seine 2d Darstellung liegt

        internal void RecalcUnitCircle()
        {
            // berechnen der beiden ModOps fromUnitCircle und toUnitCircle
            // Achtung: das berücksichtigt nicht ein Linkssystem. Das ist somit eigentlich falsch
            // im Linkssystem müsste das Vorzeichen von MinorRadius negativ sein, damit die Matrix stimmt!
            double MajorRadius = majorAxis.Length;
            double MinorRadius = minorAxis.Length;

            if (GeoVector2D.Orientation(majorAxis, minorAxis) < 0)
            {   // eingeführt wg. dem Umdrehen eines Faces mit elliptischen Begrenzungen (11.3.15), Datei 97871_086103_032.cdb, nach Shell.AssertOutwardOrientation stimmt das Face Nr. 8 nicht mehr
                MinorRadius = -MinorRadius;
            }
            if (MajorRadius == 0.0 || MinorRadius == 0.0)
            {
                fromUnitCircle = toUnitCircle = ModOp2D.Identity;
            }
            else
            {
                Angle  MajorAngle = majorAxis.Angle;
                double s          = Math.Sin(MajorAngle);
                double c          = Math.Cos(MajorAngle);
                toUnitCircle = new ModOp2D(c / MajorRadius, s / MajorRadius, (-c * center.x - s * center.y) / MajorRadius,
                                           -s / MinorRadius, c / MinorRadius, (s * center.x - c * center.y) / MinorRadius);
                fromUnitCircle = new ModOp2D(MajorRadius * c, -MinorRadius * s, center.x,
                                             MajorRadius * s, MinorRadius * c, center.y);
            }
        }
コード例 #9
0
ファイル: BoundingRect.cs プロジェクト: SOFAgh/CADability
        internal BoundingRect GetModified(ModOp2D m)
        {
            BoundingRect res = new BoundingRect(this);

            res.Modify(m);
            return(res);
        }
コード例 #10
0
 public ScaledSurface(ISurface original, double fu, double fv)
 {
     this.fu       = fu;
     this.fv       = fv;
     this.original = original;
     scale         = ModOp2D.Scale(fu, fv);
     unscale       = scale.GetInverse();
 }
コード例 #11
0
        /// <summary>
        /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.GetModified (ModOp2D)"/>
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public override ICurve2D GetModified(ModOp2D m)
        {   // allgemeine Lösung, wird für Kreis und Ellipse übernommen
            Line2D res = Clone() as Line2D;

            res.startPoint = m * startPoint;
            res.endPoint   = m * endPoint;
            return(res);
        }
コード例 #12
0
ファイル: DualSurfaceCurve.cs プロジェクト: SOFAgh/CADability
 ICurve2D ICurve2D.GetModified(ModOp2D m)
 {
     return(theCurve.GetModified(m));
     // war vorher so: nicht sicher ob das jemand so braucht, macht Probleme wenn nicht geklippt
     //Curve2DAspect c2da = Clone();
     //c2da.MakeClipped();
     //c2da.clippedCurve = c2da.clippedCurve.GetModified(m);
     //// wie Move. Lösung: ModOp2D ansammeln
     //return c2da;
 }
コード例 #13
0
        /// <summary>
        /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.GetModified (ModOp2D)"/>
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public override ICurve2D GetModified(ModOp2D m)
        {
            // es ist wichtig hier zu überschreiben, die Basisfunktionalität macht aus einem 360°
            // Kreisbogen einen Kreis und der Anfangspunkt geht verloren. Diese Information ist aber
            // für die Edges wichtig.
            if (m.IsIsogonal)
            {
                bool cc = sweep > 0.0;
                if (m.Determinant < 0.0)
                {
                    cc = !cc;
                }
                Arc2D res = new Arc2D(m * Center, m.Factor * Radius, m * StartPoint, m * EndPoint, cc);
                if (m.Determinant < 0.0)
                {
                    res.sweep = -sweep; // das schaltet die Fälle aus, wo Unsicherheit zwischen 0 und 360° besteht
                }
                else
                {
                    res.sweep = sweep;
                }
                return(res);
            }
            else
            {
                //double sw = sweep;
                //if (m.Determinant < 0.0) sw = -sw;
                GeoVector2D majorAxis;
                GeoVector2D minorAxis;
                GeoPoint2D  left, right, bottom, top;
                bool        cc = sweep > 0.0;
                if (m.Determinant < 0.0)
                {
                    cc = !cc;
                }
                majorAxis = m * (Radius * GeoVector2D.XAxis);
                minorAxis = m * (Radius * GeoVector2D.YAxis);
                if (Math.Abs(majorAxis.Length - minorAxis.Length) < (majorAxis.Length + minorAxis.Length) * 1e-6)
                {
                    return(new Arc2D(m * Center, Math.Abs(m.Determinant * Radius), m * StartPoint, m * EndPoint, cc));
                }
                Geometry.PrincipalAxis(m * Center, m * (Radius * GeoVector2D.XAxis), m * (Radius * GeoVector2D.YAxis), out majorAxis, out minorAxis, out left, out right, out bottom, out top, false);
                // geändert wg. Fehler in IsIsogonal Fall, noch nicht getestet
                return(EllipseArc2D.Create(m * Center, majorAxis, minorAxis, m * StartPoint, m * EndPoint, cc));

                //if (m.Determinant < 0.0)
                //{
                //    return new EllipseArc2D(m * Center, m * (Radius * GeoVector2D.XAxis), m * (Radius * GeoVector2D.YAxis), start + sweep, sw, left, right, bottom, top);
                //}
                //else
                //{
                //    return new EllipseArc2D(m * Center, m * (Radius * GeoVector2D.XAxis), m * (Radius * GeoVector2D.YAxis), start, sw, left, right, bottom, top);
                //}
            }
        }
コード例 #14
0
        public override double PositionOf(GeoPoint2D p)
        {
            ModOp2D toUnit = fromUnit.GetInverse();
            double  u      = (toUnit * p).x;

#if DEBUG
            GeoPoint2D tp = PointAt(ParToPos(u));
            double     d  = p | tp;
#endif
            return(ParToPos(u));
        }
コード例 #15
0
        public override void Copy(ICurve2D toCopyFrom)
        {
            SineCurve2D other = toCopyFrom as SineCurve2D;

            if (other is SineCurve2D)
            {
                ustart   = other.ustart;
                udiff    = other.udiff;
                fromUnit = other.fromUnit;
            }
        }
コード例 #16
0
 public PlanePolygon(GeoPoint2D uv, GeoPoint loc, GeoVector diru, GeoVector dirv, GeoPoint edgeStart, GeoPoint edgeEnd, Tangulation tangulation)
 {
     // TODO: Complete member initialization
     plane   = new Plane(loc, diru, dirv);
     toUV    = ModOp2D.Translate(uv.x, uv.y) * ModOp2D.Fit(new GeoVector2D[] { GeoVector2D.XAxis, GeoVector2D.YAxis }, new GeoVector2D[] { plane.Project(diru), plane.Project(dirv) });
     polygon = new List <GeoPoint2D>();
     polygon.Add(plane.Project(edgeStart)); // die beiden Punkte geben die Linie an, die die Ebene begrenzt
     polygon.Add(plane.Project(edgeEnd));
     isOpen = true;                         // die Linie "halbiert" die Ebene, links davon ist innerhalb
     extend = BoundingCube.EmptyBoundingCube;
 }
コード例 #17
0
ファイル: BoundingRect.cs プロジェクト: SOFAgh/CADability
        /// <summary>
        /// Modifies the rectangle by the provided <see cref="ModOp2D"/>. The resulting rectangle contains the modified
        /// vertices of this rectangle
        /// </summary>
        /// <param name="m">Modification to use</param>
        public void Modify(ModOp2D m)
        {
            GeoPoint2D p1 = m * new GeoPoint2D(Left, Bottom);
            GeoPoint2D p2 = m * new GeoPoint2D(Left, Top);
            GeoPoint2D p3 = m * new GeoPoint2D(Right, Bottom);
            GeoPoint2D p4 = m * new GeoPoint2D(Right, Top);

            Left   = Right = p1.x;
            Bottom = Top = p1.y;
            MinMax(p2);
            MinMax(p3);
            MinMax(p4);
        }
コード例 #18
0
        public override void CopyData(ISurface CopyFrom)
        {
            NonPeriodicSurface nps = CopyFrom as NonPeriodicSurface;

            if (nps != null)
            {
                periodicSurface     = nps.periodicSurface;
                periodicBounds      = nps.periodicBounds;
                hasPole             = nps.hasPole;
                fullPeriod          = nps.fullPeriod;
                toNonPeriodicBounds = nps.toNonPeriodicBounds;
                toPeriodicBounds    = nps.toPeriodicBounds;
            }
        }
コード例 #19
0
ファイル: HatchStyleLines.cs プロジェクト: SOFAgh/CADability
        /// <summary>
        /// This method is used by a <see cref="Hatch"/> object to calculate its contents. It generates a
        /// set of parallel lines according to <see cref="LineDistance"/> and <see cref="LineAngle"/>
        /// and clips them with the given shape. The lines are projected into the 3D world
        /// by the given plane. <seealso cref="CompoundShape.Clip"/>
        /// </summary>
        /// <param name="shape">shape of the hatch object</param>
        /// <param name="plane">local plane of the hatch object</param>
        /// <returns></returns>
        public override GeoObjectList GenerateContent(CompoundShape shape, Plane plane)
        {
            GeoObjectList res = new GeoObjectList();

            if (shape == null)
            {
                return(res);
            }
            if (marginOffset != 0.0)
            {
                shape.Approximate(false, Settings.GlobalSettings.GetDoubleValue("Approximate.Precision", 0.01));
                shape = shape.Shrink(marginOffset);
            }
            for (int i = 0; i < Math.Max(1, number); ++i)
            {
                double       a   = lineAngle.Radian + i * (double)offset;
                ModOp2D      m   = ModOp2D.Rotate(new SweepAngle(-a));
                BoundingRect ext = shape.GetExtent();
                ext.Modify(m);                         // ext ist jetzt waagrecht, u.U. zu groß, was aber egal ist
                m = ModOp2D.Rotate(new SweepAngle(a)); // die umgekehrte ModOp
                int alt = 0;
                // eine Linie soll durch die Mitte gehen
                double c   = (ext.Bottom + ext.Top) / 2.0;
                double num = Math.Ceiling((c - ext.Bottom) / lineDistance);
                ext.Bottom = c - num * lineDistance; // das untere Ende sowei nach unten verschoben, dass eine Linie durch die mitte geht
                // das ist wichtig, weil sonst manche Schraffuren nicht zu picken sind, da keine Linie darin erscheint
                // da eine Schraffur meist nur aus einem SimpleShape besteht, gibt es immer eine Linie durch die Mitte
                for (double y = ext.Bottom; y < ext.Top; y += lineDistance)
                {
                    GeoPoint2D startPoint = m * new GeoPoint2D(ext.Left, y);
                    GeoPoint2D endPoint   = m * new GeoPoint2D(ext.Right, y);
                    Line2D     l          = new Line2D(startPoint, endPoint);
                    if (alternate && ((alt & 0x01) != 0))
                    {
                        l.Reverse();
                    }
                    double[] seg = shape.Clip(l, true);
                    for (int j = 0; j < seg.Length; j += 2)
                    {
                        IGeoObject go = l.Trim(seg[j], seg[j + 1]).MakeGeoObject(plane);
                        (go as ILineWidth).LineWidth     = lineWidth;
                        (go as ILinePattern).LinePattern = linePattern;
                        (go as IColorDef).ColorDef       = colorDef;
                        res.Add(go);
                    }
                    ++alt;
                }
            }
            return(res);
        }
コード例 #20
0
ファイル: Ellipse2D.cs プロジェクト: SOFAgh/CADability
 internal void GetAxisAlignedEllipse(out double MajorRadius, out double MinorRadius, out ModOp2D toAxis, out ModOp2D fromAxis)
 {
     MajorRadius = majorAxis.Length;
     MinorRadius = minorAxis.Length;
     if (MajorRadius == 0.0 || MinorRadius == 0.0)
     {
         fromAxis = toAxis = ModOp2D.Identity;
     }
     else
     {
         // noch überprüfen dass MajorAxis>MinorAxis ist
         Angle  MajorAngle = majorAxis.Angle;
         double s          = Math.Sin(MajorAngle);
         double c          = Math.Cos(MajorAngle);
         toAxis   = new ModOp2D(c, s, (-c * center.x - s * center.y), -s, c, (s * center.x - c * center.y));
         fromAxis = new ModOp2D(c, -s, center.x, s, c, center.y);
     }
 }
コード例 #21
0
        public InfiniteLine2D(GeoPoint2D startPoint, GeoPoint2D endPoint)
        {
            this.startPoint = startPoint;
            direction       = endPoint - startPoint;
            Angle a = direction.Angle;

            if (Precision.IsEqual(a, Angle.A0) || Precision.IsEqual(a, Angle.A180))
            {
                toXAxis = ModOp2D.Translate(0.0, -startPoint.y);
            }
            else
            {
                double l = -startPoint.y / direction.y; // != 0.0, da nicht horizontal
                double x = startPoint.x + l * direction.x;
                // double y = startPoint.y+l*direction.y;
                toXAxis = ModOp2D.Rotate(new GeoPoint2D(x, 0.0), new SweepAngle(-a));
            }
        }
コード例 #22
0
ファイル: HelicalSurface.cs プロジェクト: SOFAgh/CADability
 /// <summary>
 /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.SameGeometry (BoundingRect, ISurface, BoundingRect, double, out ModOp2D)"/>
 /// </summary>
 /// <param name="thisBounds"></param>
 /// <param name="other"></param>
 /// <param name="otherBounds"></param>
 /// <param name="precision"></param>
 /// <param name="firstToSecond"></param>
 /// <returns></returns>
 public override bool SameGeometry(BoundingRect thisBounds, ISurface other, BoundingRect otherBounds, double precision, out ModOp2D firstToSecond)
 {
     if (other is HelicalSurface)
     {
         firstToSecond = ModOp2D.Null;
         HelicalSurface srother = other as HelicalSurface;
         bool           reverse;
         if (!Curves.SameGeometry(BasisCurve, srother.BasisCurve, precision, out reverse))
         {
             return(false);
         }
         if ((Location | srother.Location) > precision)
         {
             return(false);
         }
         if (Math.Abs(pitch - srother.pitch) > precision)
         {
             return(false);
         }
         GeoPoint2D uv1 = new GeoPoint2D(curveStartParameter, 0.0);
         GeoPoint   p1  = PointAt(uv1);
         GeoPoint2D uv2 = srother.PositionOf(p1);
         GeoPoint   p2  = srother.PointAt(uv2);
         if ((p1 | p2) > precision)
         {
             return(false);
         }
         uv1 = new GeoPoint2D(curveEndParameter, 0.0);
         p1  = PointAt(uv1);
         uv2 = srother.PositionOf(p1);
         p2  = srother.PointAt(uv2);
         if ((p1 | p2) > precision)
         {
             return(false);
         }
         firstToSecond = ModOp2D.Translate(uv2 - uv1);
         return(true);
     }
     return(base.SameGeometry(thisBounds, other, otherBounds, precision, out firstToSecond));
 }
コード例 #23
0
ファイル: Bitmap.cs プロジェクト: SOFAgh/CADability
        /// <summary>
        /// Clips the bitmap according to the provided shape and plane. The BitmapBits are replaced by
        /// transparent pixels, the original bits are lost. Setting another clip area doesn't restore already clipped
        /// pixels. (Ofcourse undo restores the original bitmap bits)
        /// </summary>
        /// <param name="plane">The plane as a reference system for the shape</param>
        /// <param name="shape">The shape for the clip operation</param>
        public void Clip(Plane plane, CompoundShape shape)
        {
#if !WEBASSEMBLY
            Plane         pln  = new Plane(location, directionWidth, directionHeight);
            CompoundShape prsh = shape.Project(plane, pln);
            ModOp2D       m    = ModOp2D.Scale(bitmap.Width / directionWidth.Length, -bitmap.Height / directionHeight.Length);
            prsh = prsh.GetModified(m);
            m    = ModOp2D.Translate(0, bitmap.Height);
            prsh = prsh.GetModified(m);
            GraphicsPath gp = prsh.CreateGraphicsPath();
            using (new Changing(this))
            {
                Region   rg       = new Region(gp);
                Bitmap   clone    = bitmap.Clone() as Bitmap;
                Graphics graphics = Graphics.FromImage(bitmap);
                graphics.Clear(Color.FromArgb(0, 0, 0, 0));
                graphics.SetClip(rg, CombineMode.Replace);
                graphics.DrawImage(clone, new System.Drawing.Point(0, 0));
                graphics.Dispose();
            }
#endif
        }
コード例 #24
0
ファイル: RuledSurface.cs プロジェクト: SOFAgh/CADability
 public override bool SameGeometry(BoundingRect thisBounds, ISurface other, BoundingRect otherBounds, double precision, out ModOp2D firstToSecond)
 {
     if (other is RuledSurface)
     {
         RuledSurface rsother = other as RuledSurface;
         if ((firstCurve.SameGeometry(rsother.firstCurve, precision) && secondCurve.SameGeometry(rsother.secondCurve, precision)) ||
             (firstCurve.SameGeometry(rsother.secondCurve, precision) && secondCurve.SameGeometry(rsother.firstCurve, precision)))
         {
             GeoPoint2D[] srcPoints = new GeoPoint2D[] { GeoPoint2D.Origin, new GeoPoint2D(1, 0), new GeoPoint2D(0, 1) };
             GeoPoint2D[] dstPoints = new GeoPoint2D[3];
             for (int i = 0; i < dstPoints.Length; i++)
             {
                 dstPoints[i] = rsother.PositionOf(this.PointAt(srcPoints[i]));
             }
             firstToSecond = ModOp2D.Fit(srcPoints, dstPoints, true);
             return(true);
         }
         firstToSecond = ModOp2D.Null;
         return(false);
     }
     return(base.SameGeometry(thisBounds, other, otherBounds, precision, out firstToSecond));
 }
コード例 #25
0
 public override ModOp2D ReverseOrientation()
 {
     GeoPoint2D[] from = new GeoPoint2D[3];
     from[0] = new GeoPoint2D(0.5, 0.5);
     from[1] = new GeoPoint2D(0.5, 0.7);
     from[2] = new GeoPoint2D(0.7, 0.5);
     GeoPoint[] from3d = new GeoPoint[3];
     for (int i = 0; i < 3; i++)
     {
         from3d[i] = PointAt(from[i]);
     }
     periodicSurface.ReverseOrientation();
     Init(periodicSurface.IsUPeriodic);
     //toNonPeriodicBounds = toNonPeriodicBounds * ModOp2D.Scale(-1, 1);
     //toPeriodicBounds = toNonPeriodicBounds.GetInverse();
     GeoPoint2D[] to = new GeoPoint2D[3];
     for (int i = 0; i < 3; i++)
     {
         to[i] = PositionOf(from3d[i]);
     }
     return(ModOp2D.Fit(from, to, true));
 }
コード例 #26
0
ファイル: Hatch.cs プロジェクト: SOFAgh/CADability
 /// <summary>
 /// Overrides IGeoObjectImpl.<see cref="IGeoObjectImpl.Modify"/> and implements IGeoObject.<see cref="IGeoObject.Modify"/>.
 /// </summary>
 /// <param name="m">see <see cref="IGeoObject.Modify"/></param>
 public override void Modify(ModOp m)
 {
     using (new Changing(this, "ModifyInverse", m))
     {
         // die ModOp wird in zwei Komponente aufgeteilt:
         // eine Skalierungsfreie, die auf die Ebene angewendet wird
         // und eine Skalierung, die nochmal auf die compoundShape wirkt
         try
         {
             Plane newPlane = new Plane(m * plane.Location, m * plane.DirectionX, m * plane.DirectionY);
             // die Ebene verändert sich gemäß der Matrix m, wie verändert sich die Umrandung im 2D?
             // Die brutale Methode: aus den bekannten Veränderungen von 3 Punkten die Matrix bestimmen
             // das funktioniert, alles andere hat bislang nicht geklappt
             GeoPoint2D[] src = new GeoPoint2D[3];
             GeoPoint2D[] dst = new GeoPoint2D[3];
             src[0] = GeoPoint2D.Origin;
             src[1] = GeoPoint2D.Origin + GeoVector2D.XAxis;
             src[2] = GeoPoint2D.Origin + GeoVector2D.YAxis;
             dst[0] = newPlane.Project(m * plane.ToGlobal(src[0]));
             dst[1] = newPlane.Project(m * plane.ToGlobal(src[1]));
             dst[2] = newPlane.Project(m * plane.ToGlobal(src[2]));
             ModOp2D m2d = ModOp2D.Fit(src, dst, true);
             compoundShape = compoundShape.GetModified(m2d);
             plane         = newPlane;
             if (m.Mode == ModOp.ModificationMode.Translation && base.Count > 0)
             {
                 containedObjects.Modify(m);
             }
             else
             {
                 needsRecalc = true;
             }
         }
         catch (PlaneException) { } // neue Ebene enthält Nullvector
     }
 }
コード例 #27
0
        /// <summary>
        /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.GetModified (ModOp2D)"/>
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public override ICurve2D GetModified(ModOp2D m)
        {
#if DEBUG
            ////DebuggerContainer dc = new DebuggerContainer();
            ////GeoPoint[] tst = new GeoPoint[10];
            ////for (int i = 0; i < 10; i++)
            ////{
            ////    tst[i] = new GeoPoint(PointAt(i / 9.0));
            ////}
            ////Polyline pl = Polyline.Construct();
            ////try
            ////{
            ////    pl.SetPoints(tst, false);
            ////    dc.Add(pl, 0);
            ////}
            ////catch { }
            ////EllipseArc2D dbg = EllipseArc2D.Create(m * center, m * majorAxis, m * minorAxis, m * StartPoint, m * EndPoint, counterClock);
            ////for (int i = 0; i < 10; i++)
            ////{
            ////    tst[i] = new GeoPoint(dbg.PointAt(i / 9.0));
            ////}
            ////pl = Polyline.Construct();
            ////try
            ////{
            ////    pl.SetPoints(tst, false);
            ////    dc.Add(pl, 1);
            ////}
            ////catch { }
#endif
            EllipseArc2D res = EllipseArc2D.Create(m * center, m * majorAxis, m * minorAxis, m * StartPoint, m * EndPoint, counterClock);
            if (Math.Abs(res.sweepPar) < 1e-6 && Math.Abs(this.sweepPar) > Math.PI * 2.0 - 1e-6)
            {
                res.sweepPar = this.sweepPar;
            }
            return(res);
        }
コード例 #28
0
 public override bool SameGeometry(BoundingRect thisBounds, ISurface other, BoundingRect otherBounds, double precision, out ModOp2D firstToSecond)
 {
     if (other is NonPeriodicSurface nps)
     {
         if (nps.periodicSurface.SameGeometry(nps.periodicBounds, periodicSurface, periodicBounds, precision, out ModOp2D periodicFirstToSecond))
         {
             firstToSecond = ModOp2D.Null;
             return(true);
         }
         firstToSecond = ModOp2D.Null;
         return(false);
     }
     return(base.SameGeometry(thisBounds, other, otherBounds, precision, out firstToSecond));
 }
コード例 #29
0
        private void Init(bool uPeriodic)
        {
            hasPole    = false;
            fullPeriod = false;
            if (uPeriodic)
            {
                fullPeriod = true;
                double[] sv = periodicSurface.GetVSingularities();
                if (sv != null && sv.Length > 1)
                {
                    List <double> lsv = new List <double>(sv);
                    for (int i = lsv.Count - 1; i >= 0; --i)
                    {
                        if (lsv[i] < periodicBounds.Bottom || lsv[i] > periodicBounds.Top)
                        {
                            lsv.RemoveAt(i);
                        }
                    }
                    sv = lsv.ToArray();
                }
                if (sv != null && sv.Length > 0)
                {
                    if (sv.Length == 1)
                    {
                        hasPole = true;
                        if (sv[0] == periodicBounds.Bottom)
                        {
                            // bounds.Bottom => 0.0, bounds.Top => 1.0
                            // bounds.Left => 0, bountd.Right => 2*pi
                            double fvu = 2.0 * Math.PI / periodicBounds.Width;
                            double fuv = 1.0 / periodicBounds.Height;
                            toNonPeriodicBounds = new ModOp2D(fvu, 0, -fvu * periodicBounds.Left, 0, fuv, -fuv * periodicBounds.Bottom);
                        }
                        else if (sv[0] == periodicBounds.Top)
                        {
                            // bounds.Bottom => 0.0, bounds.Top => 1.0
                            // bounds.Left => 2*pi, bountd.Right => 0
                            double fvu = 2.0 * Math.PI / periodicBounds.Width;
                            double fuv = 1.0 / periodicBounds.Height;
                            toNonPeriodicBounds = new ModOp2D(-fvu, 0, fvu * periodicBounds.Right, 0, fuv, -fuv * periodicBounds.Bottom);
                        }
                        else
                        {
                            throw new ApplicationException("pole must be on border");
                        }
                    }
                    else
                    {
                        throw new ApplicationException("more than one pole");
                    }
                }
                else
                {
                    // bounds.Bottom => 0.5, bounds.Top => 1.5
                    // bounds.Left => 0, bountd.Right => 2*pi
                    double fvu = -2.0 * Math.PI / periodicBounds.Width; // "-", because toroidal surface needs it for correct orientation. What about NURBS?
                    double fuv = 1.0 / periodicBounds.Height;
                    toNonPeriodicBounds = new ModOp2D(fvu, 0, -fvu * periodicBounds.Left - Math.PI, 0, fuv, -fuv * periodicBounds.Bottom + 0.5);
                }
            }
            else if (periodicSurface.IsVPeriodic)
            {
                fullPeriod = true;
                double[] su = periodicSurface.GetUSingularities();
                if (su != null && su.Length > 1)
                {
                    List <double> lsu = new List <double>(su);
                    for (int i = lsu.Count - 1; i >= 0; --i)
                    {
                        if (lsu[i] < periodicBounds.Left || lsu[i] > periodicBounds.Right)
                        {
                            lsu.RemoveAt(i);
                        }
                    }
                    su = lsu.ToArray();
                }
                if (su != null && su.Length > 0)
                {
                    if (su.Length == 1)
                    {
                        hasPole = true;
                        if (su[0] == periodicBounds.Left)
                        {
                            double fvu = 2.0 * Math.PI / periodicBounds.Height;
                            double fuv = 1.0 / periodicBounds.Width;
                            toNonPeriodicBounds = new ModOp2D(0, fvu, -fvu * periodicBounds.Bottom, fuv, 0, -fuv * periodicBounds.Left);
                        }
                        else if (su[0] == periodicBounds.Right)
                        {
                            double fvu = 2.0 * Math.PI / periodicBounds.Height;
                            double fuv = 1.0 / periodicBounds.Width;
                            toNonPeriodicBounds = new ModOp2D(0, -fvu, fvu * periodicBounds.Top, fuv, 0, -fuv * periodicBounds.Left);
                        }
                        else
                        {
                            throw new ApplicationException("pole must be on border");
                        }
                    }
                    else
                    {
                        throw new ApplicationException("more than one pole");
                    }
                }
                else
                {
                    double fvu = 2.0 * Math.PI / periodicBounds.Height;
                    double fuv = 1.0 / periodicBounds.Width;
                    toNonPeriodicBounds = new ModOp2D(0, fvu, -fvu * periodicBounds.Bottom, fuv, 0, -fuv * periodicBounds.Left + 0.5);
                }
            }
            else
            {   // not periodic, only pole removal
                // map the "periodic" parameter (where there is a singularity) onto [0..pi/2], the other parameter to [0..1]
                bool     done = false;
                double[] su   = periodicSurface.GetUSingularities();
                if (su != null && su.Length == 1)
                {   // the "period" to be resolved is in v, when u==su[0] you can change v and the point stays fixed
                    hasPole = true;
                    if (Math.Abs(su[0] - periodicBounds.Left) < periodicBounds.Width * 1e-6)
                    {                                                       // we have to map the v interval of the periodic surface onto [0..pi/2] and the u interval onto [0..1]
                        // and we also have to exchange u and v, so the non periodic bounds are [0..pi/2] in u and [0..1] in v
                        double fvu = Math.PI / 2.0 / periodicBounds.Height; // tested: ok
                        double fuv = 1.0 / periodicBounds.Width;
                        toNonPeriodicBounds = new ModOp2D(0, fvu, -fvu * periodicBounds.Bottom, fuv, 0, -fuv * periodicBounds.Left);
                    }
                    else if (Math.Abs(su[0] - periodicBounds.Right) < periodicBounds.Width * 1e-6)
                    {                                                       // here we additionally have tor reverse the v interval
                        double fvu = Math.PI / 2.0 / periodicBounds.Height; // tested: ok
                        double fuv = 1.0 / periodicBounds.Width;
                        toNonPeriodicBounds = new ModOp2D(0, -fvu, fvu * periodicBounds.Top, -fuv, 0, fuv * periodicBounds.Right);
                    }
                    else
                    {
                        throw new ApplicationException("the pole must be on the border of the bounds");
                    }
                    done = true;
                }
                if (!done)
                {
                    double[] sv = periodicSurface.GetVSingularities();
                    if (sv != null && sv.Length == 1)
                    {   // the "period" to be resolved is in u
                        hasPole = true;
                        if (Math.Abs(sv[0] - periodicBounds.Bottom) < periodicBounds.Height * 1e-6)
                        {                                                      // we have to map the u interval of the periodic surface onto [0..pi/2] and the v interval onto [0..1]
                            double fvu = Math.PI / 2.0 / periodicBounds.Width; // tested: ok
                            double fuv = 1.0 / periodicBounds.Height;
                            toNonPeriodicBounds = new ModOp2D(-fvu, 0, fvu * periodicBounds.Right, 0, fuv, -fuv * periodicBounds.Bottom);
                        }
                        else if (Math.Abs(sv[0] - periodicBounds.Top) < periodicBounds.Height * 1e-6)
                        {
                            double fvu = Math.PI / 2.0 / periodicBounds.Width; // tested: ok
                            double fuv = 1.0 / periodicBounds.Height;
                            toNonPeriodicBounds = new ModOp2D(fvu, 0, -fvu * periodicBounds.Left, 0, -fuv, fuv * periodicBounds.Top);
                        }
                        else
                        {
                            throw new ApplicationException("the pole must be on the border of the bounds");
                        }
                        done = true;
                    }
                }
                if (!done)
                {
                    throw new ApplicationException("there must be a single pole on the border of the bounds");
                }
            }
            toPeriodicBounds = toNonPeriodicBounds.GetInverse();
#if DEBUG
            //GeoObjectList dbg = this.DebugGrid;
            //GeoObjectList dbgp = (this.periodicSurface as ISurfaceImpl).DebugGrid;
#endif
        }
コード例 #30
0
 public override bool SameGeometry(BoundingRect thisBounds, ISurface other, BoundingRect otherBounds, double precision, out ModOp2D firstToSecond)
 {
     if (other is CylindricalSurfaceNP cnp)
     {
         if (Geometry.DistPL(cnp.location, location, zAxis) < precision && Geometry.DistPL(cnp.location + cnp.zAxis, location, zAxis) < precision)
         {
             firstToSecond = ModOp2D.Null;
             return(true);
         }
         firstToSecond = ModOp2D.Null;
         return(false);
     }
     return(base.SameGeometry(thisBounds, other, otherBounds, precision, out firstToSecond));
 }