i wish to create a virtual cockpit using GDI ,have not yet found functions in GDI to apply transformations on rectangles,lines etc.Any suggestion son how to go about the task.
Well, exactly what do you mean by "transformations"? GDI is a 2D API,
and a primitive one at that. You can do scaling and origin using the
mapping modes and SetWindowOrg/SetViewportOrg. Or, you can do a
general matrix transform using SetWorldTransform, although there are
some requirements to use it.
Most virtual cockpit applications would be constructed using OpenGL or
Direct3D. There are wxPython surfaces that support both.
···
On Sep 8, 7:21 pm, nipun batra <nipunredde...@gmail.com> wrote:
i wish to create a virtual cockpit using GDI ,have not yet found functions
in GDI to apply transformations on rectangles,lines etc.Any suggestion son
how to go about the task.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
nipun batra wrote:
i wish to create a virtual cockpit using GDI ,have not yet found functions in GDI to apply transformations on rectangles,lines etc.Any suggestion son how to go about the task.
Take a look at the wx.GraphicsContext and related classes, although as Tim mentions something like OpenGL may be better suited for this if you need to handle motion or animation in a 3D space.
···
--
Robin Dunn
Software Craftsman
Sir,what i meant by virtual cockpit is that it shows roll,pitch,yaw graphically in a 2d rectangular environment.I have been able to get it working for pitch(vertical transformation) and yaw(horizontal transformation).Now what i need is rotation of the rectangles which i have not yet understood how to.
Here is my code and attached file 1.txt which is also required for execution.You will have to change the path though.
__code
#!/usr/bin/python
import wx,time,re,math
class Nipun(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(200, 200))
print'Program execution reached here'
self.f=open('/home/nipun/1.txt')
self.g=open('/home/nipun/out.txt','w')
self.vars = re.compile('^(\d+\.?\d*)a(\d+\.?\d*)b(\d+\.?\d*)c(\d+\.?\d*)d(.*)')
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer)
self.Centre()
self.Show(True)
self.timer.Start(200)
def OnTimer(self, evt):
self.Refresh() # will cause your OnPaint to be called
def OnPaint(self, evt):
dc = wx.PaintDC(self)
self.s=self.f.readline()
print self.s
self.g.write(self.s)
m = re.search(self.vars, self.s) # Run the regexp on the packet
self.var1 = m.group(1)
self.var2 = m.group(2)
self.var3 = m.group(3)
self.var4 = m.group(4)
dc.SetBrush(wx.Brush('BLUE'))
#Now basic mathematics will be used to shift rectangles and labels
dc.DrawRectangle(-100,-100-int(self.var1), 400,200)
dc.SetBrush(wx.Brush('GREEN'))
dc.DrawRectangle(-100,100-int(self.var1), 400,200)
dc.SetBrush(wx.Brush('BLACK'))
dc.DrawRectangle(100+int(self.var3),10,10,10)
dc.SetPen(wx.Pen('WHITE'))
dc.DrawLine(100,0,100,200)
dc.DrawText(" 00",100,100-int(self.var1))
#dc.DrawText(" 10",100,90-int(self.var1))
dc.DrawText(" 20",100,80-int(self.var1))
dc.DrawText(" 40",100,60-int(self.var1))
#dc.DrawText("-10",100,110-int(self.var1))
dc.DrawText("-20",100,120-int(self.var1))
dc.DrawText("-40",100,140-int(self.var1))
dc.DrawText("-45",0,5)
dc.DrawText(" 45",180,5)
#dc.DrawRectangle(65-(15*math.cos(int(self.var1))),60+(15*math.sin(int(self.var1))),65+(15*math.cos(int(self.var1))),60-(15*math.sin(int(self.var1))))
#dc.DrawLine(50,50+int(self.var1),80,50+int(self.var1))#This will help in drawing of a virtual cockpit
#dc.drawText(self.var4,100,160)
app = wx.App()
Nipun(None, -1, ‘UAS DCE’)
app.MainLoop()__
1.txt (1.23 KB)
And yes for the 3d part where a model of plane will be shown i will use PyOpenGL or OpenGL .Have used VPython till now but have been advised against it.
nipun batra wrote:
Sir,what i meant by virtual cockpit is that it shows roll,pitch,yaw graphically in a 2d rectangular environment.I have been able to get it working for pitch(vertical transformation) and yaw(horizontal transformation).Now what i need is rotation of the rectangles which i have not yet understood how to.
First, you are using DCs, not GDI, so that may have confused some folks.
DCs do not support rotation, so to rotate a rectangle, you'll need to draw it as a polygon with four points. You can then rotate those points similarly to how you are trying to do it.
Do a bit of googling for "affine transform". Rotation is a special care of the general affine transform, and can be accomplished by multiplying by a "transform matrix"
However, you may be happier using wx.GraphicsContext, which does have affine transform built it, ans thus could rotate a rectangle (and anything else) for you
A few other suggestions:
I strongly suggest you use numpy -- it's a really good way to work with a bunch of points.
Even Better:
Use an existing higher-level 2-d graphics tool.
wx.lib.floatcanvas (that's my baby) gives you a lot, though it does not support ratation -- you'd have to write a "RotatedRectangle" DrawObject as above.
There is a newer version: FloatCanvas2, that was written by as a GSoC project. It does support rotation (and other nifty features lke alpha blending) -- there are demos showing how. It's not quite as mature, and may not qork quite right on GTK or MAc, but if you are using Windows, it could be a great option. It is now in the wxPython SVN:
There is a mailing list for both versions of FloatCanvas here:
http://mail.paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
Feel free to post your questions there.
-Chris
···
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
You need to start thinking about your points abstractly. That is,
think about your coordinates as if there were no offsets or rotations,
then pass the points through a transform to get the final numbers.
For example:
#!/usr/bin/python
import wx,time,re,math
class Transform:
def __init__( self, a, b, c, d ):
# a is xoffset
# b is yoffset
# d is rotation
self.a = a
self.b = b
self.c = c
self.d = d
theta = math.radians(d)
self.sinth = math.sin(theta)
self.costh = math.cos(theta)
def Transform( self, x, y ):
# Assume coordinates run (0,0)-(200,200)
x = x-100 + 50-self.a
y = y-100 + 50-self.b
theta = math.radians(self.d)
x1 = 100 + x * self.costh + y * self.sinth
y1 = 100 - x * self.sinth + y * math.costh
return wx.Point(x1, y1)
class Nipun(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(200, 200))
print'Program execution reached here'
self.f=open('1.txt')
self.g=open('out.txt','w')
self.vars = re.compile('^(\d+\.?\d*)a(\d+\.?\d*)b(\d+\.?\d*)c
(\d+\.?\d*)d(.*)')
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer)
self.Centre()
self.Show(True)
self.timer.Start(200)
def OnTimer(self, evt):
self.Refresh() # will cause your OnPaint to be called
def OnPaint(self, evt):
dc = wx.PaintDC(self)
self.s=self.f.readline()
if not self.s:
self.timer.Stop()
return
print self.s
self.g.write(self.s)
m = re.search(self.vars, self.s) # Run the regexp on the
packet
a = int(m.group(1))
b = int(m.group(2))
c = int(m.group(3))
d = int(m.group(4))
#Now basic mathematics will be used to shift rectangles and
labels
xform = Transform( a, b, c, d )
dc.SetBrush(wx.Brush('BLUE'))
pts = [
xform.Transform(0,-100),
xform.Transform(0,100),
xform.Transform(200,100),
xform.Transform(200,-100)
]
dc.DrawPolygon( pts )
dc.SetBrush(wx.Brush('GREEN'))
pts = [
xform.Transform(0,100),
xform.Transform(0,300),
xform.Transform(200,300),
xform.Transform(200,100)
]
dc.DrawPolygon( pts )
dc.SetBrush(wx.Brush('BLACK'))
dc.DrawRectangle(100+c,10,10,10)
dc.SetPen(wx.Pen('WHITE'))
dc.DrawLinePoint(xform.Transform(100,0), xform.Transform
(100,200))
dc.DrawTextPoint(" 00", xform.Transform(100,100))
#dc.DrawText(" 10",100,90-int(self.var1))
dc.DrawTextPoint(" 20", xform.Transform(100,80))
dc.DrawTextPoint(" 40", xform.Transform(100,60))
#dc.DrawText("-10",100,110-int(self.var1))
dc.DrawTextPoint("-20", xform.Transform(100,120))
dc.DrawTextPoint("-40", xform.Transform(100,140))
dc.DrawTextPoint("-45", xform.Transform(0,5))
dc.DrawTextPoint(" 45", xform.Transform(180,5))
app = wx.App()
Nipun(None, -1, 'UAS DCE')
app.MainLoop()
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
Tim Roberts wrote:
For example:
I couldn't help myself, enclosed is a numpy version, though it would be even cleaner if you used matrix multiplication.
You'd be even better off using GraphicsContext or FloatCanvas2
Another note:
self.vars = re.compile('^(\d+\.?\d*)a(\d+\.?\d*)b(\d+\.?\d*)c
(\d+\.?\d*)d(.*)')
m = re.search(self.vars, self.s) # Run the regexp on the
packet
...
a = int(m.group(1))
b = int(m.group(2))
c = int(m.group(3))
d = int(m.group(4))
regular expressions are not often the best route in python. this looks like fixed-length fields, so you could just do:
a = int(s[:2])
b = int(s[3:5])
etc.
Transform.py (3.58 KB)
···
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
Thanks Chris,Tim
Your codes have helped a lot in getting close to what i actually wanted to make.With just slight modifications i got it working perfectly for me.I have attached it along with the new 1.txt(having more practical values).
Now i have to work on “re” so as to also incorporate the negative numbers.
Also i need this widget to be a panel in a frame which contains other panels as well(such as displaying other variables like c in text entries)
Thanks a lot again.Any faster approach to the program you have helped me make.Although this is also lightning fast.
I would like that tutorials on zetcode be extended and transformations be included,will help a lot of newbies.
1.txt (10.8 KB)
Transform_final.py (3.46 KB)