Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Point rotation
2009-07-07 20:56
Axel
Account closed

Registered: Apr 2006
Posts: 42
Point rotation

How can I rotate point by fixed axis? how calculate new x and new y coordinates in assembler?
 
... 5 posts hidden. Click here to view all posts....
 
2009-07-08 09:09
yago

Registered: May 2002
Posts: 332
If the angle is fixed, you can rotate without using cosine, sinus or multiplication.

NEW X = OLD X - epsilon * OLD Y
NEW Y = OLD Y + epsilon * NEW(!) X

http://www.inwap.com/pdp10/hbaker/hakmem/hacks.html#item149

epsilon can be power of 2, to change speed of rotation, use different epsilons.

this is used for example in Stars and Stabbers

PS: For this to work, you must used signed bytes, though.
2009-07-08 11:05
Jetboy

Registered: Jul 2006
Posts: 214
How about using complex numbers? That will give you rotation and scaling in one pass with only addition and multiplication used.
2009-07-08 11:41
Graham
Account closed

Registered: Dec 2002
Posts: 990
Which only gives you an advantage in notation but not in 6502 code.
2009-07-08 12:25
Slammer

Registered: Feb 2004
Posts: 416
Quote: Ok thanks, but I need to rotate many points using one angle around one axis How to do this efficiently?

If you really mean ONE axis so you dont want to rotate the rotated point around another axis afterwards, then you could represent the points as a length(l) and an angle(pa). Now you can reduce the calculation to:

x = l*cos(a+pa)
y = l*sin(a+pa)

where a is the angle you want to rotate

2009-07-08 18:20
JackAsser

Registered: Jun 2002
Posts: 1989
Or you do it like the dot-plot parts out there. Assume integer based input coords.

Per frame look up the cos and sin value of your angle.
c[0] = cos(a)
s[0] = sin(a)

Add these by themselfes a couple of times to get *2, *3, *4 etc to whatever you need depending on your input set size and store into the rest of the c[] and s[] arrays.

Now compute the a coord X,Y simple do:

x = c[X] + s[Y]
y = c[Y] - s[X]

So, for instance, if you know u have input coords ranging from 0..31 in both directions u need to do about 64 adds per frame to calculate the c[] and s[] arrays. Then the rest is simple additions.
2009-07-08 18:33
Oswald

Registered: Apr 2002
Posts: 5017
Jackie, brilliant. but why not precompute the coords into polar. giving:

x = c[X]
y = s[Y]

and while we're at it, why not precompute the *2 *3 *4 tables aswell.
2009-07-08 19:39
doynax
Account closed

Registered: Oct 2004
Posts: 212
Quote: Jackie, brilliant. but why not precompute the coords into polar. giving:

x = c[X]
y = s[Y]

and while we're at it, why not precompute the *2 *3 *4 tables aswell.


Sure, that works too. It just eats a bunch of memory.

The most straightforward method is to avoid recomputing anything each frame, as you suggested, and instead just keep a full set of scaled sine and cosine arrays with double the normal period in memory.
That way the load's address specifies both the point's distance (e.g. the table number) and relative angle (the table offset.) With an index register to animate the rotation.

The obvious drawback here is that you won't be able to animate the scaling. Well, that and fact that it eats quite a bit of memory.

Perhaps the most interesting possibility of this setup is that it allows you to precalculate significant portions of the pixel addressing calculations, though come to think of it with you might not actually save any cycles when working with a clever char layout. Plus that approach would waste *even more* memory and prevent the usual space-saving trick of overlapping the horizontal (cosine) and vertical (sine) tables.
2009-07-09 05:31
Oswald

Registered: Apr 2002
Posts: 5017
well, Axel wasnt asking for scaling, and wasting memory is no problem as long as it speeds up the routine :) I would waste happily 16k for tables in such a demopart. Regarding speed/scaling/mem usage Jack's method is the best indeed.

precomputing addies made me think, the routine would look like this for a 32x25 screen, first part setting dot&presetting dot clear code, 2nd part is clearing the dot.



lda YtabLo,x
sta $fe
sta clrspeed+wherever
lda YtabHi,x
sta $ff
sta Clrspeed+wherever
ldy Xoffset,x
sty Clrsped+wherever
lda ($fe),y
ora Mask,x
sta ($fe),y
...
...

clrspeed

ldy #Xoffset
sta bitmap,y
...
...

edit: oh my its bugged, and keeping Y zero might be faster, I'll leave it to you :)
2009-07-09 06:38
doynax
Account closed

Registered: Oct 2004
Posts: 212
I was thinking something more along these lines:
plot	lda sincos_hi(a,s),x
	sta $ff
	sta clear+1
	ldy sincos_lo(a,s),x
	sty clear+2
	lda sincos_bit(a,s),x
;	ora ($fe),y
	sta ($fe),y

	.
	.
	.

clear	sta $ffff

With, say, 128 angles and 48 scales this would eat 36k of memory for the tables alone.

A nice point is that for static objects you could figure out ahead of time which plots might potentially intersect and thus avoid the ORA in the majority of the cases. That is if you wanted to bother with masking to begin with.
For the last 127 plots or so you could store the full address in a unique zeropage location and reuse it directly in the clearing code, saving something like three cycles per plot.

In the end you might squeeze 500 or so plots out of it, but the size of the plot code alone would almost kill you. And in the end it would look pretty lame compared to a comparable 3D plotter in which you'd get full 3D rotation and scaling for half that number of vertices.
But perhaps it might pay off if you wanted to plot into some byzantine sprite-based screen layout, with complex clip regions and color-effects based on the screen coordinates.
2009-07-09 17:11
Axel
Account closed

Registered: Apr 2006
Posts: 42
Thanks for your help :). Nice ideas, now I will try to do it
Previous - 1 | 2 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
oziphantom
d'Arc/Topaz Beerline
JackAsser/Booze Design
Guests online: 70
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 Wonderland XIV  (9.6)
9 Memento Mori  (9.6)
10 Bromance  (9.5)
Top onefile Demos
1 It's More Fun to Com..  (9.7)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 TRSAC, Gabber & Pebe..  (9.5)
6 Rainbow Connection  (9.5)
7 Wafer Demo  (9.5)
8 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (9.5)
Top Groups
1 Nostalgia  (9.3)
2 Oxyron  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Musicians
1 Vincenzo  (9.8)
2 Rob Hubbard  (9.7)
3 Stinsen  (9.7)
4 Jeroen Tel  (9.6)
5 Linus  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.071 sec.