Set Origin?

Just starting out? Need help? Post your questions and find answers here.
eVAPor8
User
User
Posts: 49
Joined: Tue Aug 14, 2007 10:58 am
Contact:

Set Origin?

Post by eVAPor8 »

I've a search through the help file and forums and maybe it's not possible BUT...

In the Good Ol' Days of the BBC Model B you could set the graphics origin. So, for instance, on an 800x600 screen, you could pseudo the following

[pseudocode]
SetOrigin( 400, 300 )
Plot( Colour("white"), MathsX(), MathsY() )
[/pseudocode]

...to plot a white point in the centre of the screen. It was a fantastic feature for stuff like plotting +/- waveforms, animations, etc. Now I can't find a similar function in PB but I can't beleive it doesn't exist or else every Plot() function will have to be

ScrW.l = 800
ScrH.l = 400
Plot((ScrW / 2) + MathsX(), (ScrW / 2) + MathsY())

Does a SetOrigin() type function exist? It just seems overcomplex code and more CPU intensive to me otherwise. :?
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Re: Set Origin?

Post by Fluid Byte »

eVAPor8 wrote:Does a SetOrigin() type function exist?
No but you could probably do it with DirectX API though.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I don't know about such, but you can easily do it with a formula function or a macro.

Setting an Origin alone is of no use, because you would also need to set a scale and a direction.

for the most mathematical plottings you would inverse the y-axis,
and depending on what function you want to plot you would apply a big scale, like 20-100 pixels per Unit.
oh... and have a nice day.
eVAPor8
User
User
Posts: 49
Joined: Tue Aug 14, 2007 10:58 am
Contact:

Post by eVAPor8 »

@Fluid Byte

Yeah, I was afraid of that, but it adds yet another layer of complication and also kicks any cross-platform code into the long grass.

@ Kaeru

I realise that the 0, 0 is top-left on a PB Screen, however the exercise I have in mind is to plot and animate a number of pixels, each in a (near) circler orbit around the centre of the display, so Dims and trajectories would be handled by formula code anyway. ;)

[EDIT] And thanks to both for your input! :D [/EDIT]
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

On windows you can change the mapping mode if you wish via the SetMapMode_() function.
I may look like a mule, but I'm not a complete ass.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

srod wrote:On windows you can change the mapping mode if you wish via the SetMapMode_() function.
Dat works for Screens?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Whoops.... teach me to only scan through! :)
I may look like a mule, but I'm not a complete ass.
eVAPor8
User
User
Posts: 49
Joined: Tue Aug 14, 2007 10:58 am
Contact:

Post by eVAPor8 »

srod wrote:Whoops.... teach me to only scan through! :)
:lol:

Not that I've ever done the same thing... of course... errrm... :oops:
User avatar
idle
Always Here
Always Here
Posts: 5919
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Post by idle »

Even if the function did exist, it's not magic, it'd still have to apply the transform, so you may as well set a couple of vars instead.

In homers Simpson's words - hmm donuts!

Code: Select all


Procedure drawElipse(hdc,ox.f,oy.f,majoraxis,minoraxis,sfx.f,sfy.f,orient.f)

Protected dx.f,dy.f,px.i,py.i

;draw elipse 
For alpha = 1 To 3600   
   
   dx = ox + (Sin(alpha) * majoraxis) * sfx
   dy = oy + (Cos(alpha) * minoraxis) * sfy
   px = ox + (((dx - ox) * Sin(orient))) - (((dy - oy) * Cos(orient))) 
   py = oy + (((dx - ox) * Cos(orient))) + (((dy - oy) * Sin(orient))) 
   SetPixel_(hdc, px, py, RGB(255,0,0))
        
Next
 

EndProcedure 

OpenWindow(0,0,0,800,600,"")

hdc = StartDrawing(WindowOutput(0))
 
For a = 1 To 905 Step 5

drawelipse(hdc,400,300,300,100,0.5,0.5,a)

Next 

StopDrawing()

Repeat 

 event = WaitWindowEvent() 
 
Until event = #WM_CLOSE  

eVAPor8
User
User
Posts: 49
Joined: Tue Aug 14, 2007 10:58 am
Contact:

Post by eVAPor8 »

Idle,

Very nice code, but it's using the same "Plot((ScrW / 2) + MathsX(), (ScrW / 2) + MathsY())" that I mentioned in the OP and I'm trying to avoid. Also, it's using an hDC to a window rather than a Screen (though it should be easy enough to convert).

I'm trying to eventually model (in 2D at first, 3D later) a black-hole spiral galaxy, where each star's orbit decays to the centre... Bearing in mind there will be (tens of?) thousands of stars I'd require a double-buffered Screen.

Now if you recall my BBC Model B nostalgia in the OP you'll realise it's been years since I've even plotted a Cos/Sin circle but all recollections of building mentalist animations like this involved algorithms generating negative x/y values.

It just seems to me that the extra CPU overhead per "star" is mad!

And just to make the challenge easier I want it to be cross-platform, so goodbye DX.

I guess I'll just have to learn Ogre, RTFM yet again and start again from scratch.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

1.) don't calculate (ScrW / 2) and (ScrW / 2) every call.
it's a constant, make it a constant.

2.) a simple subtraction is no "overhead".

3.) the sine is time intensive.
when you need it for a lot of elements, build a lookup table on startup, use the table in the critical loops.

4.) the way to display makes the edge between performance and slideshow.
on Windows, Plotting with colorvalue uses DSA.
when not mixing it up with other Draw commands, it's fastest to plot.
but at the end, using tiny Sprite3D stars would be even faster.
all of those use a standard grid with 0/0 in the upper left corner.
use it.
it's sufficent.
don't bother about one subtraction more or less.

5.) cross-platform back or forth...
when you want performance, don't simply stick to a crossplat engine and use the same code allover.
this will be the tunnel that steals you the performance.
write seperated includes for each platform that makes your GPU burn.

6.) stick to simple plotting first.

PS:
and I'm sorry if it sounds rude. it's not meant rude. take it easy.
oh... and have a nice day.
User avatar
idle
Always Here
Always Here
Posts: 5919
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Post by idle »

There's no avoiding the math you just need to avoid the overheads of calculating what you don't need.

This is a bit faster using lookups and pre calculating the orientation.

Code: Select all


Global Dim arCos.f(360)
Global Dim arSin.f(360)

Procedure drawElipse(hdc,ox.f,oy.f,majoraxis,minoraxis,sfx.f,sfy.f,orient.i)

Protected dx.f,dy.f,px.i,py.i,cosOrient.f,sinOrient.f,dx1.f,dy1.f,color.i 

cosOrient = ArCos(orient%360)
sinOrient = ArSin(orient%360) 
color = RGB(Random(196)+59,Random(196)+59,Random(196)+59) 
 
;draw elipse
For alpha = 1 To 3600   
   
   dx = ox + (ArSin(alpha%360) * majoraxis) * sfx
   dy = oy + (ArCos(alpha%360) * minoraxis) * sfy
   dx1 = dx - ox
   dy1 = dy - oy
   px = ox + (dx1 * sinOrient - dy1 * cosorient)
   py = oy + (dx1 * cosOrient + dy1 * sinorient)
   SetPixel_(hdc, px, py,color)
       
Next
 

EndProcedure

OpenWindow(0,0,0,800,600,"")
SetWinBackgroundColor(WindowID(0),RGB(0,0,0))
For a = 0 To 360 
  ArCos(a)=Cos(a)
  ArSin(a)=Sin(a)
Next 

hdc = StartDrawing(WindowOutput(0))
 
For a = 1 To 905 Step 5

drawelipse(hdc,400,300,300,100,0.5,0.5,a)

Next

StopDrawing()

Repeat

 event = WaitWindowEvent()
 
Until event = #WM_CLOSE  

Last edited by idle on Sat May 02, 2009 2:21 am, edited 1 time in total.
eVAPor8
User
User
Posts: 49
Joined: Tue Aug 14, 2007 10:58 am
Contact:

Post by eVAPor8 »

Kaeru Gaman wrote:1.) don't calculate (ScrW / 2) and (ScrW / 2) every call.
it's a constant, make it a constant.

2.) a simple subtraction is no "overhead".

3.) the sine is time intensive.
when you need it for a lot of elements, build a lookup table on startup, use the table in the critical loops.

4.) the way to display makes the edge between performance and slideshow.
on Windows, Plotting with colorvalue uses DSA.
when not mixing it up with other Draw commands, it's fastest to plot.
but at the end, using tiny Sprite3D stars would be even faster.
all of those use a standard grid with 0/0 in the upper left corner.
use it.
it's sufficent.
don't bother about one subtraction more or less.

5.) cross-platform back or forth...
when you want performance, don't simply stick to a crossplat engine and use the same code allover.
this will be the tunnel that steals you the performance.
write seperated includes for each platform that makes your GPU burn.

6.) stick to simple plotting first.

PS:
and I'm sorry if it sounds rude. it' not mean rude. take it easy.
1. I was using the Pseudocode to explain the problem. Of course I use a const.

2. A simple subtraction * 100,000 (or more) = added CPU cycles and overhead.

3. Since the "orbits" will eventually be slightly randomised, the Cos/Sin equations will have to be dynamic

4. I didn't know that. I'd have thought a Sprite3D would be slower than plotting a pixel. Thanks for the heads-up. ;)

5. Listen mate, I don't have the time or inclination to learn and build seperate libraries and builds per platform. Besides, if you take that route then the sourcecode isn't truly cross-platform anyway.

6. No offence, but that's exactly what I'm doing. It's just a plain fact that the ability to plot negative values makes life easier and code more simple and literate.
eVAPor8
User
User
Posts: 49
Joined: Tue Aug 14, 2007 10:58 am
Contact:

Post by eVAPor8 »

PS, Sorry if that last post sounds shirty on re-reading. It's late, I'm tired and probably not at my diplomatic best!
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

a sine function is not more dynamic than a lookup table.
A simple subtraction * 100,000 (or more) = added CPU cycles and overhead.
the basic DC or DSA uses a left-top-origin surface.

when you have a SetOrigin command, it will be within a Framework, and the overhead will be in the framework.
what do you think the framework will do when you have a SetOrigin command?
it will add a subtraction for every plot within the command.

better keep it in your own code where you have control over the amount of "overhead".

it's just...
why worry about the overhead of having one or two subtractions per element,
but not worry about using a big fat framework that may eat performance like a Mafiaboss eats noodles?

this is simply the wrong way round!

when you don't need to worry about the big fat framework, just don't care about the tiny billion subtractions either.
it will be the smaller problem. promise.


>> PS, Sorry if that last post sounds shirty on re-reading. It's late, I'm tired and probably not at my diplomatic best!

no problem. I take it easy. ;)


PS:
after having thought it over a bit...
it can be the fastest way to use OGRE, when you use it the right way.
not because it avoids a billion subtractions (it won't),
but because it accesses the modern graphics hardware the best way.

nowadays, the whole 3D stuff is Hardcoded into the Grafix Cards.
using 2D stuff is just an emulation build upon 3D internals, so it isn't any longer fast as it could be.
using a 2D surface already wastes a lot of power into a transforming framework.

best choice would perhaps be coding everything in openGL directly.
oh... and have a nice day.
Post Reply