图形学实验报告画直线圆剪裁Word下载.docx
- 文档编号:22311757
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:26
- 大小:181.04KB
图形学实验报告画直线圆剪裁Word下载.docx
《图形学实验报告画直线圆剪裁Word下载.docx》由会员分享,可在线阅读,更多相关《图形学实验报告画直线圆剪裁Word下载.docx(26页珍藏版)》请在冰豆网上搜索。
点到直线的距离:
distance=|a*x0-b*y0+c|/sqrt(a*a+b*b)
设directionX,directionY分别为从(x1,y1)==>
(x2,y2)的单位变化量(+/-1)
当直线偏向X轴时,当前象素为(xk,yk),下一个象素可能为:
(xk+directionX,yk)或者(xk+directionX,yk+directionY)这两点到直线的距离分别为:
d1=|a*xk+b*yk+c+a*directionX|/sqrt(a*a+b*b);
d2=|a*xk+b*yk+c+a*directionX+b*directonY|/sqrt(a*a+b*b);
便于运算,定义:
f(xk,yk)=d2*d2-d1*d1(将d1和d2的分母去掉了的)
=b*b+*b*directonY*(a*xk+b*yk+c+a*directionX);
当f(xk,yk)<
0的时候,下一个点为(xk+directionX,yk+directionY):
f(xk+directionX,yk+directionY)=f(xk,yk)+2*b*b+2*a*b*directionX*directionY;
当f(xk,yk)>
=0的时候,下一个点为(xk+directionX,yk):
f(xk+directionX,yk)=f(xk,yk)+2*a*b*directionX*directionY;
当直线偏向Y轴时,当前象素为(xk,yk),下一个象素可能为:
(xk,yk+directionY)或者(xk+directionX,yk+directionY)这两点到直线的距离分别为:
d1=|a*xk+b*yk+c+b*directionY|/sqrt(a*a+b*b);
d2=|a*xk+b*yk+c+b*directionY+a*directonX|/sqrt(a*a+b*b);
=a*a+*a*directonX*(a*xk+b*yk+c+b*directionY);
f(xk+directionX,yk+directionY)=f(xk,yk)+2*a*a+2*a*b*directionX*directionY;
1.3截图
2.中点画圆
2.1基本原理:
对于圆上的点,F(x,y)=0;
对于圆外的点,F(x,y)>
0;
而对于圆内的点,F(x,y)<
0。
假设M是P1和P2的中点,即M=(xp+1,yp-0.5)。
那么,当F(M)<
0时,M在圆内,这说明P1距离圆弧更近,应取P1作为下一像素。
而当F(M)>0时,P2离圆弧更近,应取P2。
当F(M)=0时,在P1与P2之中随便取一个即可,我们约定取P2。
与中点画线法一样,构造判别式
d=F(M)=F(xp+1,yp-0.5)
=(xp+1)2+(yp-0.5)2-R2
若d<0,则应取P1为下一像素,而且再下一个像素的判别式为
d=F(xp+2,yp-0.5)=(xp+2)2+(yp-0.5)2-R2=d+2xp+3
所以,沿正右方向,d的增量为2xp+3。
而若d≥0,则P2是下一像素,而且下一像素的判别式为
d'
=F(xp+2,yp–1.5)=(xp+2)2+(yp–1.5)2–R2=d+(2xp+3)+(–2yp+2)
所以,沿右下方向,判别式d的增量为2(xp–yp)+5。
由于我们这里讨论的是按顺时针方向生成第二个8分圆,因此,第一像素是(0,R),判别量d的初始值为:
d0=F(l,R–0.5)=1+(R–0.5)2–R2=1.25–R
设则判别量的初值为
递推公式中其他与d有管的狮子可以直接换成
所以
圆心位于原点的圆有四条对称轴x=0、y=0、x=y和x=-y。
从而若已知圆弧上一点P(x,y),就可以得到其关于四条对称轴的七个对称点,这种性质称为八分对称性。
因此只要能画出八分之一的圆弧,就可以利用对称性的原理得到整个圆弧。
2.2截图
3.直线剪裁
3.1基本原理:
裁剪窗口:
矩形区域
若线段两端点均落在窗口内:
线段可见;
.若线段两端点分别落在窗口的内外两侧:
计算线段与窗口边界的交点(1个),确定可见部分线段;
.若线段两端点均落在窗口外:
计算线段与窗口交点(0个或2个),若无交点,则线段不可见,否则线段部分可见。
分别记线段端点P1,P2的编码为code1,code2,当P1,P2均在窗口内:
code1=0000且code2=0000;
P1,P2在同一边框线外:
code1[i]=code2[i]=1,i=1,2,3,4;
即code1&
code2!
=0000,
其它code1&
code2=0000;
code1!
=0000或code2!
=0000
利用中点分割法并采用迭代方法找到距端点最近的可见点进行剪裁
3.2流程图
3.3截图
附录
:
代码:
MAINFRAME
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
importjavax.swing.event.*;
importjavax.swing.border.*;
publicclassMainFrameextendsJFrame{
MainFrame(){
Containerc=getContentPane();
drawPanel=newPanelEX(this,730,540);
mainPanel=newJPanel();
mainPanel.setLayout(newGridBagLayout());
ctrlPanel=newJPanel();
ctrlPanel.setLayout(newBoxLayout(ctrlPanel,BoxLayout.Y_AXIS));
initButtonPanel();
ctrlPanel.add(buttonPanel);
gridBagConstraints=newGridBagConstraints();
mainPanel.add(ctrlPanel,gridBagConstraints);
gridBagConstraints.insets=newInsets(5,5,15,5);
add(mainPanel,BorderLayout.WEST);
add(drawPanel,BorderLayout.CENTER);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setTitle("
画线圆剪裁——ZXJ"
);
setSize(885,572);
show();
}
voidinitButtonPanel(){
buttonPanel=newJPanel();
JPanelt=newJPanel(newGridLayout(6,1,6,6));
ButtonGroupbg=newButtonGroup();
line=newJToggleButton();
line.setFont(newFont("
Dialog"
0,30));
line.setSelected(true);
line.setText("
画线"
line.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){
drawPanel.setOperate(PanelEX.DrawLine);
}
});
bg.add(line);
t.add(line);
clip=newJToggleButton();
clip.setFont(newFont("
clip.setText("
裁剪"
clip.addActionListener(newActionListener(){
drawPanel.setOperate(PanelEX.SegmentClip);
bg.add(clip);
t.add(clip);
circle=newJToggleButton();
circle.setFont(newFont("
circle.setText("
画圆"
circle.addActionListener(newActionListener(){
drawPanel.setOperate(PanelEX.drawcircle);
bg.add(circle);
t.add(circle);
clear=newJButton();
clear.setFont(newFont("
clear.setText("
清屏"
clear.addActionListener(newActionListener(){
drawPanel.clear();
t.add(clear);
buttonPanel.add(t);
publicstaticvoidmain(Stringargs[]){
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(Exceptione){
e.printStackTrace();
}
newMainFrame();
JPanelmainPanel;
JPanelctrlPanel;
JPanelbuttonPanel;
JToggleButtonline;
JToggleButtoncircle;
JToggleButtonclip;
JButtonclear;
GridBagConstraintsgridBagConstraints;
PanelEXdrawPanel;
}
PANELEX
importjava.awt.image.*;
importjava.awt.event.*;
importjavax.swing.event.*;
importjava.math.*;
publicclassPanelEXextendsJPanelimplementsMouseMotionListener,MouseListener{
PanelEX(MainFramemf,intwidth,intheight)//绘制画图面板
{
this.mf=mf;
xmin=ymin=0;
xmax=width;
ymax=height;
resetSize(width,height);
circle=newCircleOP(this);
clip=newClipOP(this);
clip.setClipRect(0,0,width,height);
line=newLineOP(this,clip);
addMouseListener(this);
addMouseMotionListener(this);
publicvoidmousePressed(MouseEvente)//鼠标压下获取当前位置
if(e.getButton()==MouseEvent.BUTTON1)
{xstart=xcurrent=e.getX();
ystart=ycurrent=e.getY();
publicvoidmouseDragged(MouseEvente)//鼠表拖动,根据不同情况有不同处理方式
switch(currentOperate){
caseDrawLine:
//画线鼠标拖动过程中获取坐标并且将拖动过程显示
line.pushBack(xstart,ystart,xcurrent,ycurrent);
xcurrent=e.getX();
ycurrent=e.getY();
line.pushForward(xstart,ystart,xcurrent,ycurrent);
break;
casedrawcircle:
//画圆鼠标拖动过程中获取坐标计算半径并且将拖动过程显示
intradix=(int)Math.sqrt((xstart-xcurrent)*(xstart-xcurrent)+(ystart-ycurrent)*(ystart-ycurrent));
circle.pushBack(xstart,ystart,radix);
radix=(int)Math.sqrt((xstart-xcurrent)*(xstart-xcurrent)+(ystart-ycurrent)*(ystart-ycurrent));
circle.pushForward(xstart,ystart,radix);
caseSegmentClip:
//剪裁由于剪裁的为直线,所以类似直线
clip.pushBack(xstart,ystart,xcurrent,ycurrent);
clip.pushForward(xstart,ystart,xcurrent,ycurrent);
publicvoidmouseReleased(MouseEvente)//松开鼠标
if(e.getButton()!
=MouseEvent.BUTTON1){return;
if(currentOperate==DrawLine)//根据中点画线方法画线
line.MidPoint(xstart,ystart,e.getX(),e.getY());
if(currentOperate==drawcircle)//根据中点画圆方法画圆
intradix=(int)Math.sqrt((xcurrent-xstart)*(xcurrent-xstart)+(ycurrent-ystart)*(ycurrent-ystart));
radix=(int)Math.sqrt((e.getX()-xstart)*(e.getX()-xstart)+(e.getY()-ystart)*(e.getY()-ystart));
circle.MidPoint(xstart,ystart,radix);
if(currentOperate==SegmentClip)//剪裁
if(xstart>
e.getX())//获取xmin,xmax,ymin,ymax绘制剪裁矩形
{xmin=e.getX();
xmax=xstart;
}
else
{xmin=xstart;
xmax=e.getX();
if(ystart>
e.getY())
{ymin=e.getY();
ymax=ystart;
{ymin=ystart;
ymax=e.getY();
if(xmin<
0){xmin=0;
if(xmax>
width){xmax=width;
if(ymin<
0){ymin=0;
if(ymax>
height){ymax=height;
clip.drawRectBoth(xmin,ymin,xmax,ymax);
clip.setClipRect(xmin,ymin,xmax,ymax);
publicvoidmouseMoved(MouseEvente){}
voidresetSize(intwidth,intheight){//绘图面板
if(this.width==width&
&
this.height==height){
return;
this.width=width;
this.height=height;
bi=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
g2=(Graphics2D)bi.getGraphics();
g2.setColor(Color.white);
g2.fillRect(0,0,width,height);
g2.dispose();
setSize(width,height);
publicvoidclear()//清屏
g2.dispose();
paint(getGraphics());
publicvoidpaint(Graphicsg){g.drawImage(bi,0,0,width,height,this);
publicvoidupdate(Graphicsg){paint(g);
publicvoidstop(){}
publicvoidsetOperate(intop)
{currentOperate=op;
needConnectPoint=false;
publicvoidmouseClicked(MouseEvente){}
publicvoidmouseEntered(MouseEvente){}
publicvoidmouseExited(MouseEvente){}
MainFramemf;
BufferedImagebi;
LineOPline;
ClipOPclip;
CircleOPcircle;
Graphics2Dg2;
intxstart;
intystart;
intxcurrent;
intycurrent;
intxend;
intyend;
privateintxmin;
privateintymin;
privateintxmax;
privateintymax;
intwidth=0;
intheight=0;
intcurrentOperate=DrawLine;
Colorcolor;
booleanneedConnectPoint=false;
publicstaticfinalintDrawLine=1;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图形学 实验 报告 直线 剪裁