public void rotate(Point curPoint) { SLine line = blob.curFigure; rotate(ref line, curPoint); blob.curFigure = line; }
//используется только при граничных условиях в трансформировании private void rotateCrach(ref SLine figure, double angel) { PointF centerPointsArr = new PointF(figure.getCentrX(), figure.getCentrY()); figure.affinMatrix.RotateAt((float)(-angel), centerPointsArr, MatrixOrder.Append); blob.drawingScieneOnly(); }
private void changeTurnPoint() { SLine cur = points[curLineIndex]; cur.turnPoint.X = cur.getRotateX(); cur.turnPoint.Y = cur.getRotateY(); points[curLineIndex] = cur; }
public void moveTo(float x, float y, int index) { SLine line = blob.points[index]; line.affinMatrix = blob.points[index].affinMatrix.Clone(); line.affinMatrix.Translate(x, y, MatrixOrder.Append); blob.points[index] = line; }
public void drawingSciene(SLine line) {//очистка холста, отрисовка, отрисовка текущей линии (которая меняем), подмена холста bmpGr.Clear(Color.White); drawingScieneOnly(); primaryPen.Color = line.color; bmpGr.DrawLine(primaryPen, line.aW, line.bW); canvas.DrawImage(bmp, 0, 0); return; }
public double findAngel(SLine line) { //найти угол данной линии double c = d(line.aW, line.bW); //длина отрезка double a = line.aW.X - line.bW.X; //проекциия на Х //поворот на 90 градусов, от того кто а, кто б double b = line.aW.Y - line.bW.Y; // проекция на У //return findAngel(a, b, c, findDirection(curLineIndex)); return(findAngel(line.aW, line.bW)); }
public void repaireLine(int index) {//востановление линии в случае, если произошло переполнение SLine temp = new SLine(); temp = points[index]; temp.affinMatrix = new Matrix(1, 0, 0, 1, 0, 0); temp.aW = curLine.a; temp.bW = curLine.b; points[index] = temp; applyMatrix(index); }
private SLine tranformPoint(float ugol, SLine temp) {//100500 функция, которая пытается дать правильные координаты (тщетно) Point[] tempArr = { temp.a, temp.b }; Point c = new Point(40, 40); tempArr = tranformPoint(ugol, temp.b, tempArr); temp.a = tempArr[0]; temp.b = tempArr[1]; return(temp); }
private void popMatrix(SLine tempLine) { Point[] ps = new Point[2]; ps[0] = tempLine.a; ps[1] = tempLine.b; tempLine.affinMatrix.TransformPoints(ps); tempLine.a = ps[0]; tempLine.b = ps[1]; tempLine.affinMatrix = new Matrix(1, 0, 0, 1, 0, 0); return; }
public void rotate(ref SLine figure, double angel) { PointF centerPointsArr = new PointF(figure.getCentrX(), figure.getCentrY()); if (Math.Abs(angel) > 9999 || Math.Abs(bufAngel) > 9999 || Math.Abs(angel) < 0.01) { return; } figure.affinMatrix.RotateAt((float)(bufAngel - angel), centerPointsArr, MatrixOrder.Append); bufAngel = angel; blob.drawingScieneOnly(); }
//масшатабирование линии + коеф. Х + коеф. У в разных режимых public void scale2D(ref SLine figure, float x, float y) { float dx = figure.getRotateX(); float dy = figure.getRotateY(); if (x > 10000 || y > 10000) { return; } figure.affinMatrix.Translate(-dx, -dy, MatrixOrder.Append); figure.affinMatrix.Scale(x, y, MatrixOrder.Append); figure.affinMatrix.Translate(dx, dy, MatrixOrder.Append); }
private void popMatrix(int indexLine) {//применить матрицу афинных преобразований к фигуре и сбросить матрицу афинных преобразований SLine tempLine = points[indexLine]; Point[] ps = new Point[2]; ps[0] = tempLine.a; ps[1] = tempLine.b; tempLine.affinMatrix.TransformPoints(ps); tempLine.a = ps[0]; tempLine.b = ps[1]; tempLine.aW = ps[0]; tempLine.bW = ps[1]; tempLine.affinMatrix = new Matrix(1, 0, 0, 1, 0, 0); points[indexLine] = tempLine; return; }
public void applyMatrix(int indexLine) {//применить матрицу афинных преобразований, без сброса самой матрицы SLine tempLine = points[indexLine]; tempLine.affinMatrix = points[indexLine].affinMatrix.Clone(); Point[] ps = new Point[2]; ps[0] = tempLine.a; ps[1] = tempLine.b; tempLine.affinMatrix.TransformPoints(ps); tempLine.aW = ps[0]; tempLine.bW = ps[1]; points[indexLine] = tempLine; return; }
//отрисовка холста с учетом надатия ЛКМ public void drawingDown(MouseEventArgs e) {//при нажатии ЛКМ на холсте switch (pen) { case (int)penType.line: switch (curModes) { case (int)modes.MODE_DROW: isDragging = true; curPoint = e.Location; curLine.a = e.Location; curLine.aW = e.Location; curLine.color = Color.Black; curLine.affinMatrix = new Matrix(1, 0, 0, 1, 0, 0); break; case (int)modes.MODE_MOVE: int index = getLine(e.Location); //если мы куда попали в фигуру if (curCaptures != (int)captures.TAKE_NONE) { isDragging = true; curLineIndex = index; curPoint = e.Location; curLine = points[curLineIndex]; //blockDCM = true; } break; case (int)modes.MODE_DELETE: curLineIndex = getLine(e.Location); if (curLineIndex != -1) { points.RemoveAt(curLineIndex); drawingSciene(); } break; } break; case (int)penType.poligon: break; } }
//масштабирование с использованием матриц (без c# WinForms api) private void naturalScale(ref SLine figure, float x, float y) { float dx = figure.getRotateX(); float dy = figure.getRotateY(); //матрица переноса центра в ноль Matrix amx = new Matrix(1, 0, 0, 1, -dx, -dy); //применяем матрицу figure.affinMatrix.Multiply(amx, MatrixOrder.Append); //масштабирование amx = new Matrix(x, 0, 0, y, 0, 0); figure.affinMatrix.Multiply(amx, MatrixOrder.Append); //матрица возврощения обратно amx = new Matrix(1, 0, 0, 1, dx, dy); figure.affinMatrix.Multiply(amx, MatrixOrder.Append); //figure.applyAffinMatrix(); }
//преобразует масштабирование линия + точка в линии + коеф. Х + коеф. У public void scale(ref SLine figure, Point curPoint, int numberPoint) {//TODO: //важно помнить про то, с какой стороны браться с difAngel //оптимизация? //отдельный консольный выход? //if (d(figure.aW, figure.bW) < 3 * editor.visibility) // return; float x, y; //коэффициенты x = y = 0; double difAngel = 0; double curAngel = findAngel(figure); int curDirect = findDirection(); float znamX = (float)(figure.aW.X - figure.bW.X); float znamY = (float)(figure.aW.Y - figure.bW.Y); if (znamX == 0) { znamX = (float)0.01; } if (znamY == 0) { znamY = (float)0.01; } if (numberPoint == 1) //если тянули за первую точку { x = (float)Math.Abs((curPoint.X - figure.bW.X) / znamX); y = (float)Math.Abs((curPoint.Y - figure.bW.Y) / znamY); difAngel = findAngel(curPoint, figure.turnPoint); } else if (numberPoint == 2) // если за вторую { x = (float)Math.Abs((curPoint.X - figure.aW.X) / znamX); y = (float)Math.Abs((curPoint.Y - figure.aW.Y) / znamY); difAngel = findAngel(figure.turnPoint, curPoint); } if (x == 0 || y == 0 || Double.IsNaN(x) || double.IsNaN(y) || double.IsInfinity(x) || double.IsInfinity(y)) { return; } if (Math.Abs(difAngel - curAngel) > 5) { if (double.IsNaN(difAngel) || double.IsNaN(curAngel)) { return; } rotateCrach(ref figure, difAngel - curAngel); return; } //String bug = ""; //if (Math.Abs(difAngel - curAngel) > 1) // bug = "\nda"; //blob.konsole.Print("direcrion=" + findDirection().ToString() + " angel=" + aux.substr(findAngel(figure).ToString()) + // "\nx,y=" + aux.substr(x.ToString()) + " " + aux.substr(y.ToString()) + // "\ndiffAngel=" + aux.substr(difAngel.ToString()) + // "\ncurAngel=" + aux.substr(curAngel.ToString()) + // "\ndifAngels=" + aux.substr((difAngel - curAngel).ToString()) + // bug); scale2D(ref figure, x, y); return; }
public void drawingScieneOnly() {//отрисовки всех фигур + короб (без пост и пред действий) //потому что иногда нужна толко отрисовка без других действий try { foreach (SLine line in points) { primaryPen.Color = line.color; try { bmpGr.DrawLine(primaryPen, line.aW, line.bW); } catch (OverflowException) { applyMatrix(curLineIndex); } } } catch (InvalidOperationException) { } SLine tempL = new SLine(); //отрисовка короба try { if (curModes == (int)modes.MODE_MOVE && curLineIndex != -1) { tempL = points[curLineIndex]; if (double.IsNaN(points[curLineIndex].aW.X) || double.IsNaN(points[curLineIndex].aW.Y) || points[curLineIndex].aW.X < -99999 || points[curLineIndex].aW.X > 99999) { printLine(points[curLineIndex]); repaireLine(curLineIndex); return; } try { int height = Math.Abs(curFigure.bW.X - curFigure.aW.X); int weidth = Math.Abs(curFigure.bW.Y - curFigure.aW.Y); int limit = 10; if (height < limit) { height = limit; } if (weidth < limit) { weidth = limit; } Rectangle frame = new Rectangle(Math.Min(curFigure.aW.X, curFigure.bW.X), Math.Min(curFigure.aW.Y, curFigure.bW.Y), height, weidth); bmpGr.DrawRectangle(secondryPen, frame); bmpGr.DrawPolygon(secondryPen, getPointsTransform(points[curLineIndex].bW)); bmpGr.DrawPolygon(secondryPen, getPointsTransform(points[curLineIndex].aW)); } catch (OverflowException) { repaireLine(curLineIndex); } if (curCaptures != (int)captures.TAKE_TURN) { changeTurnPoint(); } //points[curLineIndex].applyAffinMatrix(); applyMatrix(curLineIndex); Debug.WriteLine(points[curLineIndex].ToStringMx()); //popMatrix(curLineIndex); SLine myLine = points[curLineIndex]; bmpGr.DrawEllipse(secondryPen, myLine.turnPoint.X, myLine.turnPoint.Y, 5, 5); } } catch (StackOverflowException) { // points[curLineIndex]= curLine; //applyMatrix(curLineIndex); } }
//найти угол по индексу линии public int findDirection(ref SLine figure) { return(findDirection(figure.aW, figure.bW)); }
public void rotateCrach(ref SLine figure, Point curPoint) { double angel = findAngel(figure.aW, curPoint); rotateCrach(ref figure, angel); }
//для отладки поворота public void drawingSciene(PictureBox pictureBox1, MouseEventArgs e) {//отрисовка + выполнение действий пользователя (поворот, маштабирвоание, трансформ, деформ) if (curModes == (int)modes.MODE_DROW) { curLine.bW = e.Location; if (isDragging) { drawingSciene(curLine); } } else { if (isDragging) { if (curCaptures != prevCaptur) { } // popMatrix(curLineIndex); SLine templine = new SLine(); templine = points[curLineIndex]; templine.affinMatrix = points[curLineIndex].affinMatrix.Clone(); switch (curCaptures) { //меняем кординаты у перетягиваемого изображения прямо в хранилище //готовимся к отрисовке case (int)captures.TAKE_TURN: aft.rotate(ref templine, e.Location); points[curLineIndex] = templine; break; case (int)captures.TAKE_PT1: if (zoom) { //если деформ popMatrix(curLineIndex); curLine = points[curLineIndex]; curLine.a = e.Location; curLine.aW = e.Location; points[curLineIndex] = curLine; } else { //если маштаб aft.scale(ref templine, e.Location, 1); points[curLineIndex] = templine; } break; case (int)captures.TAKE_PT2: if (zoom) { popMatrix(curLineIndex); curLine = points[curLineIndex]; curLine.b = e.Location; curLine.bW = e.Location; points[curLineIndex] = curLine; popMatrix(curLineIndex); } else { aft.scale(ref templine, e.Location, 2); points[curLineIndex] = templine; } break; case (int)captures.TAKE_CENTR: //мат! //Matrix coordinans3 = new Matrix(1,0, 0,1, // (e.Location.X - curPoint.X), // (e.Location.Y - curPoint.Y) ); aft.moveTo((e.Location.X - curPoint.X), (e.Location.Y - curPoint.Y), curLineIndex); curPoint.X = e.Location.X; curPoint.Y = e.Location.Y; break; } drawingSciene(); prevCaptur = curCaptures; } } }
private void printLine(SLine line) {//вывести состояние линии // Console.WriteLine("!{0}, {1} - {2},{3}", line.a.X, line.a.Y, line.b.X, line.b.Y); // Console.WriteLine("!!{0}, {1} - {2},{3}", line.aW.X, line.aW.Y, line.bW.X, line.bW.Y); }
public void rotate(ref SLine figure, Point curPoint) { double angel = findAngel(blob.curFigure.turnPoint, curPoint); rotate(ref figure, angel); }
private void changeTurnPoint(ref SLine line) {//изменить точку поворота, ее нужна менять отдельно, каждый раз забываю почему такой апендикс line.turnPoint.X = (int)((line.aW.X + line.bW.X) / 2 + 20); line.turnPoint.Y = (int)((line.aW.Y + line.bW.Y) / 2 + 35); return; }
public void scale(ref SLine figure, float x, float y) { scale2D(ref figure, x, y); }