现在的位置: 主页 > 商讯 > 文章正文
矩形裁剪算法_pyopengl
作者:吴桥县齐源纤维素有限公司 来源:www.qy-xws.com 发布时间:2017-09-07 13:29:42
矩形裁剪算法_pyopengl

Python版本是3.5.1。使用pip命令:pip install pyopengl 安装pyopengl模块。

图形学期末设计,不知道用opengl或webgl做什么炫酷的效果,只好做算法了,悲剧的写了500多行,缺点是裁剪算法未封装成函数。

代码如下:




#encoding='utf-8'
#python3.5.1
#author by 张政伟 2016/6/16
#矩形裁剪算法
from OpenGL.GLUT import *
from OpenGL.GL import *
import sys
blue=(0.0,0.0,1.0)
green=(0.0,1.0,0.0)
red=(1.0,0.0,0.0)
color=blue
winx=400 #窗口宽度
winy=400 #窗口高度
l1=[];#存储坐标
class point:
x=0 #x坐标
y=0 #y坐标
pl=0 #相对于矩形裁剪区域左边,此点的位置,0为内,1为外
pt=0 #相对于矩形裁剪区域上边,此点的位置,0为内,1为外
pr=0 #相对于矩形裁剪区域右边,此点的位置,0为内,1为外
pb=0 #相对于矩形裁剪区域下边,此点的位置,0为内,1为外
def __init__(self,x,y,pl,pt,pr,pb):
self.x=x
self.y=y
self.pl=pl
self.pt=pt
self.pr=pr
self.pb=pb
#窗口左上角为(0,0),而PyOpengl画图以窗口中心为(0,0)且最大x坐标与y坐标都是100。
#因此需要将鼠标获取的坐标转换成PyOpengl画图坐标。
def translate(point):
a=winx/2
b=winy/2
if point.x < a and point.y < b:
point.x=(point.x/a)*100-100
point.y=100-(point.y/b)*100
elif point.x > a and point.y < b:
point.x=((point.x-a)/a)*100
point.y=100-(point.y/b)*100
elif point.x < a and point.y > b:
point.x=(point.x/a)*100-100
point.y=((point.y-b)/b)*100*(-1)
else:
point.x=((point.x-a)/a)*100
point.y=((point.y-b)/b)*100*(-1)
def display():
glClearColor(0.0,0.0,0.0,0.0) #背景色=黑色,RGBA全为0
glClear(GL_COLOR_BUFFER_BIT) #清除颜色缓冲区
glColor3fv(color)
#设置下面绘制物体的颜色
#f表示参数类型为浮点类型,v表示接受的参数为数组形式
#glRectf(-10.0,-20.0,20.0,10.0)
#绘制坐标系
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_LINES)
glVertex2f(0.0, 0.0)
glVertex2f(0.0, 95.0)
glVertex2f(0.0, 95.0)
glVertex2f(4.0, 92.0)
glVertex2f(0.0, 95.0)
glVertex2f(-4.0, 92.0)
glVertex2f(0.0, 0.0)
glVertex2f(0.0, -95.0)
glVertex2f(0.0, 0.0)
glVertex2f(95.0,0.0)
glVertex2f(95.0,0.0)
glVertex2f(92.0,4.0)
glVertex2f(95.0,0.0)
glVertex2f(92.0,-4.0)
glVertex2f(0.0, 0.0)
glVertex2f(-95.0,0.0)
glEnd()
glColor3f(0.0,0.0,1.0)
glBegin(GL_POINTS);
glVertex2i(0,0);
glEnd();
glFlush()
def reshape(winx,winy):
glViewport(0,0,winx,winy)
#定义相对视窗大小(像素范围)
glMatrixMode(GL_PROJECTION) #选择投影矩阵
glLoadIdentity()
#读取规范化的单位矩阵
glOrtho(-100.0,100.0, -100.0,100.0, 0.0,100.0)
#定义空间坐标系范围
glMatrixMode(GL_MODELVIEW)
#选择模型视图矩阵
glLoadIdentity()
def key(key,mousex,mousey):
global color
if (key==b'q'):
#按下q按键时
print('退出')
glutDestroyWindow(winid) #根据ID结束窗口
sys.exit()
elif (key==b'e'):
l1.clear()
print('初始化界面')
glutPostRedisplay()
#重绘,将调用display
elif (key==b'g'):
#以绿线画裁剪后图形并输出裁剪后坐标
if l1[0].x<l1[1].x:
#矩形裁剪区域:左下点的坐标
plb=point(l1[0].x,l1[0].y,0,0,0,0)
#矩形裁剪区域:右上点的坐标
prt=point(l1[1].x,l1[1].y,0,0,0,0)
else:
#矩形裁剪区域:左下点的坐标
plb=point(l1[1].x,l1[1].y,0,0,0,0)
#矩形裁剪区域:右上点的坐标
prt=point(l1[0].x,l1[0].y,0,0,0,0)
#输出
print('裁剪区域左下点坐标:')
print(plb.x,plb.y)
print('裁剪区域右上点坐标:')
print(prt.x,prt.y)
#被裁剪区域顶点坐标
l=l1[2:]
#函数:得到被裁剪区域顶点坐标相对于裁剪区域四条边的位置
def judgePositon(point):
#判断左边
if(i.x<plb.x):
i.pl=1
else:
i.pl=0
#判断上边
if(i.y<prt.y):
i.pt=0
else:
i.pt=1
#判断右边
if(i.x<prt.x):
i.pr=0
else:
i.pr=1
#判断下边
if(i.y<plb.y):
i.pb=1
else:
i.pb=0
#调用函数,完全初始化被裁减区域顶点坐标
for i in l1:
judgePositon(i)
#测试输出被裁剪区域顶点坐标
print("init:")
for i in l:
print(i.x,i.y,i.pl,i.pt,i.pr,i.pb)
#列表:存储裁剪后坐标
l2=[]
#左边裁剪
for i in range(0,len(l)):
if(i==len(l)-1):
if(l[i].pl==0):
#都在内部,保留第二个顶点
if(l[0].pl==0):
l2.append(l[0])
#一内一外,保留交点
else:
k=(l[i].y-l[0].y)/(l[i].x-l[0].x)
b=l[i].y-k*l[i].x
x=plb.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
else:
#一外一内,保留交点与内
if(l[0].pl==0):
k=(l[i].y-l[0].y)/(l[i].x-l[0].x)
b=l[i].y-k*l[i].x
x=plb.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
l2.append(l[0])
#都在外部,全部舍弃
else:
pass
else:
if(l[i].pl==0):
#都在内部,保留第二个顶点
if(l[i+1].pl==0):
l2.append(l[i+1])
#一内一外,保留交点
else:
k=(l[i].y-l[i+1].y)/(l[i].x-l[i+1].x)
b=l[i].y-k*l[i].x
x=plb.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
else:
#一外一内,保留交点与内
if(l[i+1].pl==0):
k=(l[i].y-l[i+1].y)/(l[i].x-l[i+1].x)
b=l[i].y-k*l[i].x
x=plb.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
l2.append(l[i+1])
#都在外部,全部舍弃
else:
pass
#初始化左裁剪后顶点坐标相对裁剪区域的位置
for i in l2:
judgePositon(l2)
#输出左裁剪后顶点坐标
print("leftClip:")
for i in l2:
print(i.x,i.y,i.pl,i.pt,i.pr,i.pb)
#上边裁剪
#清除列表l,用来存储上边裁剪后顶点坐标
l.clear()
for i in range(0,len(l2)):
if(i==len(l2)-1):
if(l2[i].pt==0):
#都在内部,保留第二个顶点
if(l2[0].pt==0):
#l.append(l2[i])
l.append(l2[0])
#一内一外,保留交点
else:
if(l2[i].x==l2[0].x):
x=l2[i].x
y=prt.y
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
k=(l2[i].y-l2[0].y)/(l2[i].x-l2[0].x)
b=l2[i].y-k*l2[i].x
y=prt.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
#一外一内,保留交点与内
if(l2[0].pt==0):
if(l2[i].x==l2[0].x):
x=l2[i].x
y=prt.y
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[0])
else:
k=(l2[i].y-l2[0].y)/(l2[i].x-l2[0].x)
b=l2[i].y-k*l2[i].x
y=prt.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[0])
#都在外部,全部舍弃
else:
pass
else:
if(l2[i].pt==0):
#都在内部,保留第二个顶点
if(l2[i+1].pt==0):
#l.append(l2[i])
l.append(l2[i+1])
#一内一外,保留交点
else:
if(l2[i].x==l2[i+1].x):
x=l2[i].x
y=prt.y
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
k=(l2[i].y-l2[i+1].y)/(l2[i].x-l2[i+1].x)
b=l2[i].y-k*l2[i].x
y=prt.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
#一外一内,保留交点与内
if(l2[i+1].pt==0):
if(l2[i].x==l2[i+1].x):
x=l2[i].x
y=prt.y
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[i+1])
else:
k=(l2[i].y-l2[i+1].y)/(l2[i].x-l2[i+1].x)
b=l2[i].y-k*l2[i].x
y=prt.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[i+1])
#都在外部,全部舍弃
else:
pass
#初始化上裁剪后顶点坐标相对裁剪区域的位置
for i in l:
judgePositon(l)
#输出上裁剪后顶点坐标
print("topClip:")
for i in l:
print(i.x,i.y,i.pl,i.pt,i.pr,i.pb)
#右边裁剪
#清除列表l2,用来存储上边裁剪后顶点坐标
l2.clear()
for i in range(0,len(l)):
if(i==len(l)-1):
if(l[i].pr==0):
#都在内部,保留第二顶点
if(l[0].pr==0):
l2.append(l[0])
#一内一外,保留交点
else:
k=(l[i].y-l[0].y)/(l[i].x-l[0].x)
b=l[i].y-k*l[i].x
x=prt.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
else:
#一外一内,保留交点与内
if(l[0].pr==0):
k=(l[i].y-l[0].y)/(l[i].x-l[0].x)
b=l[i].y-k*l[i].x
x=prt.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
l2.append(l[0])
#都在外部,全部舍弃
else:
pass
else:
if(l[i].pr==0):
#都在内部,保留第二顶点
if(l[i+1].pr==0):
l2.append(l[i+1])
#一内一外,保留交点
else:
k=(l[i].y-l[i+1].y)/(l[i].x-l[i+1].x)
b=l[i].y-k*l[i].x
x=prt.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
else:
#一外一内,保留交点与内
if(l[i+1].pr==0):
k=(l[i].y-l[i+1].y)/(l[i].x-l[i+1].x)
b=l[i].y-k*l[i].x
x=prt.x
y=x*k+b
temp=point(x,y,0,0,0,0)
l2.append(temp)
l2.append(l[i+1])
#都在外部,全部舍弃
else:
pass
#初始化右裁剪后顶点坐标相对裁剪区域的位置
for i in l2:
judgePositon(l2)
#输出右裁剪后顶点坐标
print("rightClip:")
for i in l2:
print(i.x,i.y,i.pl,i.pt,i.pr,i.pb)
#下边裁剪
#清除列表l,用来存储下边裁剪后顶点坐标
l.clear()
for i in range(0,len(l2)):
if(i==len(l2)-1):
if(l2[i].pb==0):
#都在内部,保留第二顶点
if(l2[0].pb==0):
#l.append(l2[i])
l.append(l2[0])
#一内一外,保留交点
else:
if(l2[i].x==l2[0].x):
x=l2[i].x
y=plb.y
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
k=(l2[i].y-l2[0].y)/(l2[i].x-l2[0].x)
b=l2[i].y-k*l2[i].x
y=plb.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
#一外一内,保留交点内
if(l2[0].pb==0):
if(l2[i].x==l2[0].x):
x=l2[i].x
y=plb.y
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[0])
else:
k=(l2[i].y-l2[0].y)/(l2[i].x-l2[0].x)
b=l2[i].y-k*l2[i].x
y=plb.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[0])
#都在外部,全部舍弃
else:
pass
else:
if(l2[i].pb==0):
#都在内部,保留第二顶点
if(l2[i+1].pb==0):
#l.append(l2[i])
l.append(l2[i+1])
#一内一外,保留交点
else:
if(l2[i].x==l2[i+1].x):
x=l2[i].x
y=plb.y
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
k=(l2[i].y-l2[i+1].y)/(l2[i].x-l2[i+1].x)
b=l2[i].y-k*l2[i].x
y=plb.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
else:
#一外一内,保留交点与内
if(l2[i+1].pb==0):
if(l2[i].x==l2[i+1].x):
x=l2[i].x
y=plb.y
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[i+1])
else:
k=(l2[i].y-l2[i+1].y)/(l2[i].x-l2[i+1].x)
b=l2[i].y-k*l2[i].x
y=plb.y
if k!=0:
x=(y-b)/k
temp=point(x,y,0,0,0,0)
l.append(temp)
l.append(l2[i+1])
#都在外部,全部舍弃
else:
pass
#初始化下裁剪后顶点坐标相对裁剪区域的位置
for i in l:
judgePositon(l)
#输出下裁剪后顶点坐标
print("bottomClip:")
for i in l:
print(i.x,i.y,i.pl,i.pt,i.pr,i.pb)
#以绿线画裁剪后区域
color=green
glColor3fv(color)
print('以绿线画被裁剪多边形')
for i in range(0,len(l)):
if(i==len(l)-1):
glBegin(GL_LINES) #画线
glVertex2f(l[i].x,l[i].y)
glVertex2f(l[0].x,l[0].y)
glEnd()
glFlush()
else:
glBegin(GL_LINES) #画线
glVertex2f(l[i].x,l[i].y)
glVertex2f(l[i+1].x,l[i+1].y)
glEnd()
glFlush()
elif (key==b'r'):#以红色画矩形裁剪窗口
color=red
glColor3fv(color)
print('以红线画矩形裁剪窗口')
glBegin(GL_LINES) #画线
glVertex2f(l1[0].x,l1[0].y)
glVertex2f(l1[0].x,l1[1].y)
glVertex2f(l1[0].x,l1[1].y)
glVertex2f(l1[1].x,l1[1].y)
glVertex2f(l1[1].x,l1[1].y)
glVertex2f(l1[1].x,l1[0].y)
glVertex2f(l1[1].x,l1[0].y)
glVertex2f(l1[0].x,l1[0].y)
glEnd()
glFlush()
elif (key==b'b'):
color=blue
glColor3fv(color)
print('以蓝线画被裁剪多边形')
for i in range(2,len(l1)):
if(i==len(l1)-1):
glBegin(GL_LINES) #画线
glVertex2f(l1[i].x,l1[i].y)
glVertex2f(l1[2].x,l1[2].y)
glEnd()
glFlush()
else:
glBegin(GL_LINES) #画线
glVertex2f(l1[i].x,l1[i].y)
glVertex2f(l1[i+1].x,l1[i+1].y)
glEnd()
glFlush()
def mouse(button,state,x,y):
#鼠标左键按下
if button == GLUT_LEFT_BUTTON and state == GLUT_DOWN:
glColor3fv(color)
temp=point(x,y,0,0,0,0)
translate(temp)
l1.append(temp)
print('使用说明:')
print('请用鼠标点击确定矩形裁剪区域左下点与右下点坐标,按\'r\'键绘制裁剪区域')
print('请用鼠标点击确定被裁剪区域坐标,按\'b\'键绘制被裁剪区域')
print('按\'g\'键绘制被裁剪后区域')
print('按\'e\'键初始化界面')
print('按\'q\'键退出程序')
glutInit(sys.argv)
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA)
glutInitWindowSize(winx,winy)
glutInitWindowPosition(100,100)
winid=glutCreateWindow(b"main") #建立窗口的ID返回到winid
glutDisplayFunc(display)
glutReshapeFunc(reshape)
glutKeyboardFunc(key)
glutMouseFunc(mouse)
glutMainLoop()



企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:神农架网站建设 http://shennongjia.45qun.com


  • 上一篇:PHP配置,链接access数据库
  • 下一篇:最后一页
  • 
    COPYRIGHT © 2015 吴桥县齐源纤维素有限公司 ALL RIGHTS RESERVED.
    本站所有原创信息,未经许可请勿任意转载或复制使用 网站地图 技术支持:肥猫科技
    精彩专题:网站建设
    购买本站友情链接、项目合作请联系客服QQ:2500-38-100