Лабораторная работа 2-3. Задание: Используя алгоритм Брезенхема, реализовать построение прямой линии и дуги окружности.
Задание: Используя алгоритм Брезенхема, реализовать построение прямой линии и дуги окружности.
Язык программирования Java.
import java.awt.Color; import java.awt.Frame; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;
public class drawLine extends Frame{ private static final long serialVersionUID = 1L; public static void main(String[] args) { drawLine a = new drawLine(); a.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we){ System.exit(0); } }); } public drawLine(){ setTitle("Лаб2"); setSize(150,150); setVisible(true); } public void paint(Graphics gr){ drawBresenhamLine(30, 50, 100, 100, gr); setArc(20, 50, 30, 0, 45); } //Этот код "рисует" все 9 видов отрезков. Наклонные (из начала в конец и из конца в начало каждый), вертикальный и горизонтальный - тоже из начала в конец и из конца в начало, и точку. private int sign (int x) { return (x > 0)? 1: (x < 0)? -1: 0; //возвращает 0, если аргумент (x) равен нулю; -1, если x < 0 и 1, если x > 0. }
public void drawBresenhamLine (int xstart, int ystart, int xend, int yend, Graphics g) /** * xstart, ystart - начало; * xend, yend - конец;*/ { int x, y, dx, dy, incx, incy, pdx, pdy, es, el, err; dx = xend - xstart;//проекция на ось икс dy = yend - ystart;//проекция на ось игрек incx = sign(dx); /* * Определяем, в какую сторону нужно будет сдвигаться. Если dx < 0, т.е. отрезок идёт * справа налево по иксу, то incx будет равен -1. * Это будет использоваться в цикле постороения. */ incy = sign(dy); /* * Аналогично. Если рисуем отрезок снизу вверх - * это будет отрицательный сдвиг для y (иначе - положительный). */
if (dx < 0) dx = -dx;//далее мы будем сравнивать: "if (dx < dy)" if (dy < 0) dy = -dy;//поэтому необходимо сделать dx = |dx|; dy = |dy| //эти две строчки можно записать и так: dx = Math.abs(dx); dy = Math.abs(dy);
if (dx > dy) //определяем наклон отрезка: { /* * Если dx > dy, то значит отрезок "вытянут" вдоль оси икс, т.е. он скорее длинный, чем высокий. * Значит в цикле нужно будет идти по икс (строчка el = dx;), значит "протягивать" прямую по иксу * надо в соответствии с тем, слева направо и справа налево она идёт (pdx = incx;), при этом * по y сдвиг такой отсутствует. */ pdx = incx; pdy = 0; es = dy; el = dx; } else//случай, когда прямая скорее "высокая", чем длинная, т.е. вытянута по оси y { pdx = 0; pdy = incy; es = dx; el = dy;//тогда в цикле будем двигаться по y }
x = xstart; y = ystart; err = el/2; g.drawLine (x, y, x, y);//ставим первую точку //все последующие точки возможно надо сдвигать, поэтому первую ставим вне цикла
for (int t = 0; t < el; t++)//идём по всем точкам, начиная со второй и до последней { err -= es; if (err < 0) { err += el; x += incx;//сдвинуть прямую (сместить вверх или вниз, если цикл проходит по иксам) y += incy;//или сместить влево-вправо, если цикл проходит по y } else { x += pdx;//продолжить тянуть прямую дальше, т.е. сдвинуть влево или вправо, если y += pdy;//цикл идёт по иксу; сдвинуть вверх или вниз, если по y }
g.drawLine (x, y, x, y); } }
/* Рисуем дуги окружности в 4х квадрантах */ public void setArc(int xC, int yC, int r, int sAngle, int fAngle) { if(sAngle<=90) { setFirst(xC,yC,r,sAngle,fAngle); } if((sAngle>90 && fAngle<=180) || (sAngle<=90 && fAngle>90)||(sAngle>90 && fAngle>=180 && fAngle<270)) { setSecond(xC,yC,r,sAngle,fAngle); } if((sAngle>180 && fAngle<=270) || (sAngle<=180 && fAngle>180)||(sAngle>180 && fAngle>=270)) { setThird(xC,yC,r,sAngle,fAngle); } if((sAngle>270 && fAngle<=360) || (sAngle<=270 && fAngle>270)||(sAngle>270 && fAngle>=360)) { setForth(xC,yC,r,sAngle,fAngle); } }
public void setFirst(int xC, int yC, int r, int sAngle, int fAngle) { int sAngleCopy = sAngle; int fAngleCopy; if(fAngle > 90) { fAngleCopy=90; }else { fAngleCopy=fAngle; } x=Math.abs((int)(r*Math.cos((fAngleCopy*(Math.PI/180))))); y=Math.abs((int)(r*Math.sin((fAngleCopy*(Math.PI/180))))); double d=2*(1-r),d1,d2; int limit=Math.abs((int)(r*Math.sin((sAngleCopy*(Math.PI/180)))));
while (y>=limit) { backgroundGraphics.setColor(colorPanel.getBackground()); backgroundGraphics.drawLine(x+xC,-y+yC,x+xC,-y+yC); //первая четверть углы наоборот repaint(); if (d<0) { d1=2*d-2*y-1; if (d1<0) { x=x+1; d=d+2*x+1; } if (d1>0) { x++; y--; d=d+2*x-2*y+2; } } if (d>0) { d2=2*d-2*x-1; if (d2<=0) { x++; y--; d=d+2*x-2*y+2; } if (d2>0) { y--; d=d-2*y+1; } } if (d==0) { x++; y--; d=d+2*x-2*y+2; } } }
public void setSecond(int xC, int yC, int r, int sAngle, int fAngle) { int sAngleCopy = sAngle; int fAngleCopy; if(fAngle > 180) { fAngleCopy=180; }else { fAngleCopy=fAngle; } if(sAngle < 90) { sAngleCopy=90; }else { sAngleCopy=sAngle; } x=Math.abs((int)(r*Math.cos((sAngleCopy*(Math.PI/180))))); y=Math.abs((int)(r*Math.sin((sAngleCopy*(Math.PI/180))))); double d=2*(1-r),d1,d2; int limit=Math.abs((int)(r*Math.sin((fAngleCopy*(Math.PI/180)))));
while (y>=limit) { backgroundGraphics.setColor(colorPanel.getBackground()); backgroundGraphics.drawLine(-x+xC,-y+yC,-x+xC,-y+yC); repaint(); if (d<0) { d1=2*d-2*y-1; if (d1<0) { x=x+1; d=d+2*x+1; } if (d1>0) { x++; y--; d=d+2*x-2*y+2; } } if (d>0) { d2=2*d-2*x-1; if (d2<=0) { x++; y--; d=d+2*x-2*y+2; } if (d2>0) { y--; d=d-2*y+1; } } if (d==0) { x++; y--; d=d+2*x-2*y+2; } } }
public void setThird(int xC, int yC, int r, int sAngle, int fAngle) { int sAngleCopy = sAngle; int fAngleCopy; if(fAngle > 270) { fAngleCopy=270; }else { fAngleCopy=fAngle; } if(sAngle < 180) { sAngleCopy=180; }else { sAngleCopy=sAngle; } x=Math.abs((int)(r*Math.cos((fAngleCopy*(Math.PI/180))))); y=Math.abs((int)(r*Math.sin((fAngleCopy*(Math.PI/180))))); double d=2*(1-r),d1,d2; int limit=Math.abs((int)(r*Math.sin((sAngleCopy*(Math.PI/180)))));
while (y>=limit) { backgroundGraphics.setColor(colorPanel.getBackground()); backgroundGraphics.drawLine(-x+xC,y+yC,-x+xC,y+yC); repaint(); if (d<0) { d1=2*d-2*y-1; if (d1<0) { x=x+1; d=d+2*x+1; } if (d1>0) { x++; y--; d=d+2*x-2*y+2; } } if (d>0) { d2=2*d-2*x-1; if (d2<=0) { x++; y--; d=d+2*x-2*y+2; } if (d2>0) { y--; d=d-2*y+1; } } if (d==0) { x++; y--; d=d+2*x-2*y+2; } } }
public void setForth(int xC, int yC, int r, int sAngle, int fAngle) { int sAngleCopy = sAngle; int fAngleCopy; if(fAngle > 360) { fAngleCopy=360; }else { fAngleCopy=fAngle; } if(sAngle < 270) { sAngleCopy=270; }else { sAngleCopy=sAngle; } x=Math.abs((int)(r*Math.cos((sAngleCopy*(Math.PI/180))))); y=Math.abs((int)(r*Math.sin((sAngleCopy*(Math.PI/180))))); double d=2*(1-r),d1,d2; int limit=Math.abs((int)(r*Math.sin((fAngleCopy*(Math.PI/180)))));
while (y>=limit) { backgroundGraphics.setColor(colorPanel.getBackground()); backgroundGraphics.drawLine(x+xC,y+yC,x+xC,y+yC); repaint(); if (d<0) { d1=2*d-2*y-1; if (d1<0) { x=x+1; d=d+2*x+1; } if (d1>0) { x++; y--; d=d+2*x-2*y+2; } } if (d>0) { d2=2*d-2*x-1; if (d2<=0) { x++; y--; d=d+2*x-2*y+2; } if (d2>0) { y--; d=d-2*y+1; } } if (d==0) { x++; y--; d=d+2*x-2*y+2; } } } }
|