Quote:
|
Actually this task needs quite a custom DIV & MULT routines.
It needs 1/X routine, where X is 16bit number and where we don't need the actual result (as that is always 0) but 16bit reminder. (1/1 can be handled as special case)
Also in multibly we need to multibly two 16bit numbers to get a 32bit number, but we really don't need lower 16bits to anything.
|
Well, I'm not much of a math-wiz, but I remember doing something like this in BASIC once. Here's more or less what I did:
I'll assume drawing a line is done by LINE (SX, SY)-(DX, DY) If you're working with the VDP line command this is ofcourse different, but the same priciples apply.
Keep all your coordinates positive, having an overflow of maybe the size of a screen. So something like this:
X: 0 - 512 (i.e. -128 till 384)
y: 0 - 424 (i.e. -106 till 318)
The use the following psuedo code to clip a coordinate, for instance SX:
IF SX > DX THEN DELTAX = SX - DX ELSE DELTAX = DX - SX
IF SY > DY THEN DELTAY = SY - DY ELSE DELTAY = DY - SY
CLIPSX:
IF SX >= MINX THEN GOTO SXOVER
SLOPE = (DELTAY * 64) / DELTAX
XDISP = MINX - SX
YDISP = (XDISP * SLOPE) / 64
SX = MINX
IF SY < DY THEN SY = SY + YDISP ELSE SY = SY - YDISP
GOTO CLIPSY
SXOVER:
IF SX <= MAXX THEN GOTO CLIPSY
SLOPE = (DELTAY * 64) / DELTAX
XDISP = SX - MAXX
YDISP = (XDISP * SLOPE) / 64
SX = MAXX
IF SY < DY THEN SY = SY + YDISP ELSE SY = SY - YDISP
GOTO CLIPSY
While probably not the best method, it doesn't use too many multiplications either, and no divisions. The * and / 64 can be done swiftly with a SHIFT and are done to increase accuracy. Depending on the range of coordinates you use you can increase or decrease this value to adjust the accuracy. In this example you could further increase it by a couple of shifts. In total, assuming all coordinates are out of bounds, you'd be doing a maximum of four 16bit multiplications and eigth 16bit shifts. Not _that_ bad.
I'm sure it could be done a lot better though. Like I said, I'm no math expert... It did do the trick for me though. But this way all you'd need is a good multiplication routine.