C # winforms графика увеличена

#c# #graphics2d

#c# #graphics2d

Вопрос:

Я уже неделю пытаюсь нарисовать нечетную фигуру, а затем правильно изменить ее размер, скажем.1 когда я пытаюсь использовать приведенный ниже код, я получаю этот результат:

неверный результат

Как я могу «очертить» чертеж с правильным соотношением сторон?

Код:

             foreach (clsDisplayList p in mDisplayLists)
            {
                if (!p.InView)
                {
                    continue;
                }
                if (p.Rapid)
                {
                    mCurPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                    mCurPen.DashPattern = mRapidDashStyle;
                }
                else
                {
                    mCurPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                }
                path.AddLines(p.Points);
                mCurPen.Color = p.Color;
                g.DrawLines(mCurPen, p.Points);
            }

            g.ResetTransform();
            g.MultiplyTransform(mMtxDraw);
            g.TranslateTransform(0, 1);
            //make new matrix
            Matrix newpath = new Matrix();
            newpath.Translate(0, 1);
            newpath.Scale(1.1f, 1.1f);
            path.Transform(newpath);
            g.DrawPath(mCurPen, path); //tring to scale here
  

Этот код основан на проекте под названием cnc viewer. Я в основном пытаюсь получить свою форму на основе gcode, а затем увеличить ее, чтобы я мог изменить свой gcode для точек детализации. Я написал программу для написания gcode, но не понял, как ее изменить, чтобы отобразить нужные мне координаты. Я добавил код масштабирования в соответствии с запросом. Внутренняя форма правильная, но мне нужно, чтобы внешняя форма была увеличена на 2 дюйма. Я рисую «внешнюю фигуру» после отображения начальной формы. https://www.codeproject.com/Articles/17424/CNC-Graphical-Backplotter

     public void WindowViewport(float X1, float Y1, float X2, float Y2)
    {
        float temp = 0;

        //convert window from right to left
        if ((X1 > X2))
        {
            temp = X2;
            X2 = X1;
            X1 = temp;
        }

        //convert window from bottom to top
        if ((Y1 > Y2))
        {
            temp = Y2;
            Y2 = Y1;
            Y1 = temp;
        }

        if (Math.Abs(X2 - X1) < 0.01)
        {
            return;
        }
        if (Math.Abs(Y2 - Y1) > 1000)
        {
            return;
        }

        mViewRect.X = X1;
        mViewRect.Y = Y1;
        mViewRect.Width = X2 - X1;
        mViewRect.Height = Y2 - Y1;
        AdjustAspect();
    }

    private void SetBufferContext()
    {
        if (mGfxBuff != null)
        {
            mGfxBuff.Dispose();
            mGfxBuff = null;
        }
        // Retrieves the BufferedGraphicsContext for the
        // current application domain.
        mContext = BufferedGraphicsManager.Current;

        // Sets the maximum size for the primary graphics buffer
        mContext.MaximumBuffer = new Size(this.Width   1, this.Height   1);

        // Allocates a graphics buffer the size of this control
        mGfxBuff = mContext.Allocate(CreateGraphics(), new Rectangle(0, 0, 
    this.Width, this.Height));
        mGfx = mGfxBuff.Graphics;
    }

    /// <summary>
    /// Sets the matrix required to draw to the specified view
    /// </summary>
    private void SetViewMatrix()
    {
        if (float.IsInfinity(mViewRect.Width) | 
       float.IsInfinity(mViewRect.Height)) return;
        if (mViewRect.Width == 0 | mViewRect.Height == 0) return;

        //The ratio between the actual size of the screen and the size of the 
        graphics.
        mScaleToReal = (mClientRect.Width / mGfx.DpiX) / mViewRect.Width;
        if (first == 0)
        {
            mScale_stick = mScaleToReal;
            first = 1;
        }
        mMtxDraw.Reset();
        mMtxDraw.Scale(mScaleToReal, mScaleToReal);
        mMtxDraw.Translate(-mViewportCenter.X, mViewportCenter.Y);
        mMtxDraw.Translate((mViewRect.Width / 2f), (mViewRect.Height / 2f));
        mMtxDraw.Scale(1, -1);
        //Flip the Y

        //The matrix for the triad is the same as the other geometry but 
        without the scale
        mMtxWCS.Reset();
        mMtxWCS.Multiply(mMtxDraw);
        mMtxWCS.Scale(1 / mScaleToReal, 1 / mScaleToReal);

        mPixelF = ((1 / mGfx.DpiX) / mScaleToReal);
        mBlipSize = (mPixelF * 3f);

        SetFeedbackMatrix();
    }
  

Не уверен, поможет ли это, но это то, что я пытался заставить внешнюю границу правильно масштабироваться:

  foreach (clsDisplayList p in mDisplayLists)
            {
                if (!p.InView)
                {
                    continue;
                }
                if (p.Rapid)
                {
                    mCurPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                    mCurPen.DashPattern = mRapidDashStyle;
                }
                else
                {
                    mCurPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                }
                path.AddLines(p.Points);
                mCurPen.Color = p.Color;
                g.DrawLines(mCurPen, p.Points);
                LineFixUp(ref p.Points);

                foreach (PointF line in p.Points)
                {
                    if (Math.Abs(line.Y) > points)
                    {
                        points = Math.Abs(line.Y);
                    }
                    if (Math.Abs(line.X) > points)
                    {
                        pointsx = Math.Abs(line.X);
                    }
                    try
                    {
                        if (line.Y > 0)
                        {
                            useoffsettranslation = true;
                        }

                        if (line.Y < ytop)
                        {
                            points = line.Y;
                            ytop = line.Y;
                        }
                        if (line.Y > ybottom)
                        {
                            ybottom = line.Y;
                        }
                        if (line.X < xleft)
                        {
                            xleft = line.X;
                        }
                        if (line.X > xright)
                        {
                            xright = line.X;
                        }
                    }
                    catch { }
                }
            }
            path.Flatten();
            mCurPen.Color = Color.Red;

            float third = 0;
            float fourth = 0;
            try
            {
                float first = Math.Abs(xleft) * 2;
                float second = (Math.Abs(xleft) * 2)   2;
                third = (second / first);
            }
            catch { }
            try
            {
                float first = Math.Abs(ytop / 2) * 2;
                float second = (Math.Abs(ytop / 2) * 2)   2; //trying to add 2 inches to oversize
                fourth = (second / first);
            }
            catch { }
            g.DrawPath(mCurPen, path);
            float tran = (points   2) / points;
            tran = Math.Abs(aspect - tran)   tran;
            mCurPen.Color = Color.Pink;
            float off = fourth * .85f;
            Matrix translateMatrix = new Matrix();
            translateMatrix.Scale((float)third, (float)fourth);
            if (useoffsettranslation == false)// if G54 is not center
            {
                translateMatrix.Translate((float)0, off);
            }
            else
            {
                translateMatrix.Translate(0, 0);
            }
            g.DrawPath(mCurPen, path);
  

кроме того, gcode для файла:

G42 G01 Y-9.8484 G02 X-14.62 Y-7.8484 Z-0.0787 R2 G02 X-14.4063 Y-3.147 Z-0.0787 R51.8248 G02 X-11.441 Y-0.1132 Z-0.0787 R3.3602 G02 X-9.4488 Y0 Z-0.0787 R17.5728 G01 X5.9055 G02 X11.331 Y-0,1248 Z-0,0787 R117.9665 G02 X14.5344 Y-3,3534 Z-0,0787 R3.3603 G02 X14.6201 Y-7,8481 Z-0,0787 R117.9602 G02 X14.5332 Y-12,3735 Z-0,0787 R117.9602 G02 X9.9758 Y-17,7879 Z- 0,0787 R5.7617 G02 X5.9054 Y-18.2165 Z-0.0787 R19.5415 G02 X1.8352 Y-17.7879 Z-0.0787 R19.5415 G02 X-1.0066 Y-16.2587 Z-0.0787 R5.7618 G02 X-1.0751 Y-16.1879 Z-0.0787 R2 G03 X-2.1946 Y-15.6968 Z-0,0787 R1.5217 G01 X-9,4488 G02 X-11,4409 Y-15,5835 Z-0,0787 R17.5728 G02 X-14,4064 Y-12,5498 Z-0,0787 R3.3602 G02 X-14,62 Y-7,8484 Z-0,0787 R51.8248 G02 X-12,62 Y-5,8484 Z-0,0787 R2 G40

Комментарии:

1. Неясно, как вычисляется эта TranslateTransform матрица. Поскольку вы масштабируете на основе Canvas (DC вашего графического объекта) с масштабным коэффициентом = float scale = 0.9f; , перевод (X1->X2s, Y1->Y2s) (без упрощений): var tx = -(((canvas.Width * scale) - canvas.Width) / 2.0f); var ty = -(((canvas.Height * scale) - canvas.Height) / 2.0f); . Порядок матрицы правильный (сначала перевести, затем масштабировать), но, похоже, вы вообще не рассчитали перевод. Обратите внимание, что вы можете применить матрицу к графическому объекту : g.Transform = [Matrix] .

2. Вы должны опубликовать полный код, который может воспроизвести проблему, который включает в себя другие имеющиеся у вас преобразования и образец точек данных (полигонов или полигона, который вы хотите очертить ), которые вы рисуете. У вас также есть GraphicsPath.Widen() метод (он использует ту же матрицу, но добавляет flatness параметр, который может быть интересным).

3. Хорошо, я обновил код, чтобы отразить то, на чем я основываю свою форму

4. Это называется «компенсация радиуса инструмента», станки с ЧПУ имеют эту встроенную функцию (G41 и G42). Это не линейное преобразование, поэтому графические методы не могут этого сделать. Продвигайтесь вперед, набрав в Google «математику компенсации радиуса инструмента» и пообщавшись с боссом, чтобы сказать им, что это не будет сделано какое-то время.

5. Я знаю, что это такое, я создал параметрические программы на основе этого. Это вопрос увеличения внешнего слоя чертежа. не компенсирует увеличение пути.