#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. Я знаю, что это такое, я создал параметрические программы на основе этого. Это вопрос увеличения внешнего слоя чертежа. не компенсирует увеличение пути.