草帽

图形学作业。消隐搞了半天。
开始因为书没带回家,最大值最小值消隐忘了,就依稀记得书上那个图的样子。
但是……记反了。书上的意思是先画前面的,然后后面的线如果在原先的可见范围内就不显示,但我却以为是先画后面的,然后画前面的时候把后面的擦掉。。。。。。。。。。。。。

代码:

import wx
import wx.lib.colourchooser.canvas
import math

class MyApp(wx.App):
    def OnInit(self):
        frame = MainFrame()
        self.SetTopWindow(frame)
        frame.Show(1)
        return 1

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Hat",wx.DefaultPosition,(640,480))
        self.dc=wx.ClientDC(self)
        self.buffer=wx.lib.colourchooser.canvas.BitmapBuffer(640,480,wx.Colour(0,0,0))
        self.SetBackgroundColour('#000000')
        self.WhitePen=wx.Pen(wx.Colour(255,255,255))
        self.buffer.SetPen(self.WhitePen)
        self.buffer.SetBrush(wx.Brush(wx.Colour(0,0,0)))
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_KEY_UP,self.OnKeyUp)
        self.ViewAngel=45
        self.Scale=20
        self.DrawHat()

    def OnKeyUp(self,event):
        if event.GetKeyCode()==wx.WXK_UP:
            if self.ViewAngel>-90:
                self.ViewAngel-=5
        elif event.GetKeyCode()==wx.WXK_DOWN:
            if self.ViewAngel<90:
                self.ViewAngel+=5
        elif event.GetKeyCode()==wx.WXK_LEFT:
            if self.Scale>0:
                self.Scale-=1
        elif event.GetKeyCode()==wx.WXK_RIGHT:
            if self.Scale<50:
                self.Scale+=1
        else:
            return
        self.DrawHat()
    def OnPaint(self,event):
        dc=wx.PaintDC(self)
        dc.Blit(0,0,640,480,self.buffer,0,0)

    def DrawHat(self):
        self.buffer.Clear()
        self.Freeze()
        rstep=5
        r=1.0
        zk=2.0*self.Scale
        rk=1.0*self.Scale
        rmax=rk*2*math.pi

        def func(r):
            return math.sin(float(r)/rk)*zk
            return math.cos(float(r)/rk)*zk
            return 2.4*float(r)-200
            return -float(r)**2/100+200
            return abs(r-(rmax/2))

        ymax=[-1 for i in range(640)]
        ymin=[-1 for i in range(640)]

        def plot(r,theta,z):            
            x=r*math.cos(theta)
            y=r*math.sin(theta)
            xs,ys=self.Transform(x,y,z)
            if not (0<=xs<640):
                return
            if not (0<=ys<480):
                return
            if ymax[xs]==ymin[xs]==-1:
                ymax[xs]=ymin[xs]=ys
            elif ys<ymin[xs]:                 
                ymin[xs]=ys
            elif ys>ymax[xs]:         
                ymax[xs]=ys
            else:
                return
            self.buffer.DrawPoint(xs,ys)  
        r=int(rmax)
        r-=(r-1)%rstep
        while r>1:
            #break
            tstep=1.0/r
            z=func(r)
            theta=math.pi*3/2
            while theta>math.pi:
                plot(r,theta,z)
                theta-=tstep
            theta=math.pi*3/2
            while theta<math.pi*2:
                plot(r,theta,z)
                theta+=tstep
            r-=rstep

        r=1
        while r<rmax:
            #break
            tstep=1.0/r
            z=func(r)
            theta=math.pi
            while theta>math.pi/2:
                plot(r,theta,z)
                theta-=tstep
            theta=0
            while theta<math.pi/2:
                plot(r,theta,z)
                theta+=tstep
            r+=rstep       
        self.Thaw()
        self.Refresh()

    def Transform(self,x,y,z):
        sx=x
        th=math.radians(self.ViewAngel)
        sy=round(y*math.sin(th))
        sy+=round(z*math.cos(th))
        return int(sx+320),int(240-sy)

app = MyApp(0)
app.MainLoop()


1 thought on “草帽

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.