Пример #1
0
        /// <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);
        }
Пример #2
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));
            }
        }
Пример #3
0
 void IPaintTo3D.Arc(GeoPoint center, GeoVector majorAxis, GeoVector minorAxis, double startParameter, double sweepParameter)
 {
     try
     {
         GeoVector normal = majorAxis ^ minorAxis; // normale der Ebene des Bogens
         // wird der Bogen von vorne oder hinten betrachtet?
         // statt projection.Direction besser die Richtung zum Mittelpunkt (bei perspektivischer Projektion)
         double sc = projection.Direction.Normalized * normal.Normalized;
         if (Math.Abs(sc) < 1e-6)
         {                                                  // eine Linie
             GeoVector dir = normal ^ projection.Direction; // Richtung der Linie
             double    pmin, pmax;
             double    par = Geometry.LinePar(center, dir, center + Math.Cos(startParameter) * majorAxis + Math.Sin(startParameter) * minorAxis);
             pmin = pmax = par;
             par  = Geometry.LinePar(center, dir, center + Math.Cos(startParameter + sweepParameter) * majorAxis + Math.Sin(startParameter + sweepParameter) * minorAxis);
             if (par < pmin)
             {
                 pmin = par;
             }
             if (par > pmax)
             {
                 pmax = par;
             }
             // fehlt noch: jetzt noch die Achsenpunkt abprüfen...
             (this as IPaintTo3D).Polyline(new GeoPoint[] { center + pmin * dir, center + pmax * dir });
         }
         else
         {
             GeoPoint2D  center2d = projection.Project(center);
             GeoVector2D maj2D    = projection.Project(center + majorAxis) - center2d;
             GeoVector2D min2D    = projection.Project(center + minorAxis) - center2d;
             if (maj2D.IsNullVector() || min2D.IsNullVector())
             {   // eigentlich auch eine Linie
                 return;
             }
             GeoPoint2D sp           = center2d + Math.Cos(startParameter) * maj2D + Math.Sin(startParameter) * min2D;
             GeoPoint2D ep           = center2d + Math.Cos(startParameter + sweepParameter) * maj2D + Math.Sin(startParameter + sweepParameter) * min2D;
             bool       counterclock = sweepParameter > 0.0;
             //if (normal.z > 0.0) counterclock = !counterclock;
             EllipseArc2D ea2d = EllipseArc2D.Create(center2d, maj2D, min2D, sp, ep, counterclock);
             ea2d.MakePositivOriented();
             GeoVector2D prmaj2D, prmin2D;
             // Geometry.PrincipalAxis(maj2D, min2D, out prmaj2D, out prmin2D);
             prmaj2D = ea2d.MajorAxis;
             prmin2D = ea2d.MinorAxis;
             Angle rot = prmaj2D.Angle;
             //ModOp2D toHorizontal = ModOp2D.Rotate(center2d, -rot.Radian);
             ModOp2D    fromHorizontal = ModOp2D.Rotate(center2d, rot.Radian);
             SweepAngle swapar         = new SweepAngle(ea2d.StartPoint - center2d, ea2d.EndPoint - center2d);
             if (counterclock && swapar < 0)
             {
                 swapar += 360;
             }
             if (!counterclock && swapar > 0)
             {
                 swapar -= 360;
             }
             float swPar = (float)(ea2d.axisSweep / Math.PI * 180);
             float stPar = (float)(ea2d.axisStart / Math.PI * 180);
             if (sweepParameter >= Math.PI * 2.0 || sweepParameter <= -Math.PI * 2.0)
             {   // Notlösung wg. ERSACAD und wg. Nürnberger 5.12.13
                 swPar = 360.0f;
             }
             try
             {
                 Matrix r      = fromHorizontal.Matrix2D;
                 double maxRad = prmaj2D.Length;
                 double minRad = prmin2D.Length;
                 if ((maxRad + minRad) * Projection.WorldToDeviceFactor < 1)
                 {     // sonst gibt es ein out of memory exception
                     if (graphicsPath != null)
                     { // kann auch schräge Ellipsen zufügen mit Transformation
                         GraphicsPath tmpPath = new GraphicsPath();
                         tmpPath.AddLine((float)center2d.x, (float)center2d.y, (float)center2d.x, (float)center2d.y);
                         tmpPath.Transform(r);
                         graphicsPath.AddPath(tmpPath, true);
                     }
                     else
                     {
                         Pen drawPen = MakePen();
                         using (drawPen)
                         {
                             using (new Transform(graphics, r, false))
                             {   // wenigstens einen Pixel darstellen
                                 graphics.DrawLine(drawPen, (float)(center2d.x - 0.5), (float)center2d.y, (float)(center2d.x + 0.5), (float)center2d.y);
                             }
                         }
                     }
                 }
                 else
                 {
                     if (graphicsPath != null)
                     {   // kann auch schräge Ellipsen zufügen mit Transformation
                         GraphicsPath tmpPath = new GraphicsPath();
                         tmpPath.AddArc((float)(center2d.x - maxRad), (float)(center2d.y - minRad), (float)(2.0 * maxRad), (float)(2.0 * minRad), stPar, swPar);
                         tmpPath.Transform(r);
                         graphicsPath.AddPath(tmpPath, true);
                     }
                     else
                     {
                         Pen drawPen = MakePen();
                         using (drawPen)
                         {
                             using (new Transform(graphics, r, false))
                             {
                                 graphics.DrawArc(drawPen, (float)(center2d.x - maxRad), (float)(center2d.y - minRad), (float)(2.0 * maxRad), (float)(2.0 * minRad), stPar, swPar);
                             }
                         }
                     }
                 }
             }
             catch (ArgumentException)
             {
             }
             catch (ModOpException)
             {
             }
             catch (OutOfMemoryException)
             {
             }
         }
     }
     catch
     {   // damit es sicher durchläuft. z.B. eine Ellipse, bei der beide Achsen dieselbe Richtung haben, erzeugt eine ModOp Exception
     }
 }