mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-27 04:49:27 +00:00
Working on atan2()
This commit is contained in:
parent
13652f61f2
commit
83ed437553
14
src/main/fragment/vwsz1=vwsz2_ror_vbuxx.asm
Normal file
14
src/main/fragment/vwsz1=vwsz2_ror_vbuxx.asm
Normal file
@ -0,0 +1,14 @@
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
||||
cpx #0
|
||||
beq !e+
|
||||
!:
|
||||
lda {z1}+1
|
||||
cmp #$80
|
||||
ror {z1}+1
|
||||
ror {z1}
|
||||
dex
|
||||
bne !-
|
||||
!e:
|
14
src/main/fragment/vwsz1=vwsz2_ror_vbuyy.asm
Normal file
14
src/main/fragment/vwsz1=vwsz2_ror_vbuyy.asm
Normal file
@ -0,0 +1,14 @@
|
||||
lda {z2}
|
||||
sta {z1}
|
||||
lda {z2}+1
|
||||
sta {z1}+1
|
||||
cpy #0
|
||||
beq !e+
|
||||
!:
|
||||
lda {z1}+1
|
||||
cmp #$80
|
||||
ror {z1}+1
|
||||
ror {z1}
|
||||
dey
|
||||
bne !-
|
||||
!e:
|
@ -0,0 +1,7 @@
|
||||
clc
|
||||
lda {z1}
|
||||
adc {c1},x
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc {c1}+1,x
|
||||
sta {z1}+1
|
@ -0,0 +1,7 @@
|
||||
clc
|
||||
lda {z1}
|
||||
adc {c1},y
|
||||
sta {z1}
|
||||
lda {z1}+1
|
||||
adc {c1}+1,y
|
||||
sta {z1}+1
|
87
src/main/kc/stdlib/atan2.kc
Normal file
87
src/main/kc/stdlib/atan2.kc
Normal file
@ -0,0 +1,87 @@
|
||||
// Find atan2(x, y) using the CORDIC method
|
||||
// See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf
|
||||
|
||||
// The number of iterations performed during 16-bit CORDIC atan2 calculation
|
||||
const byte CORDIC_ITERATIONS_16 = 15;
|
||||
|
||||
// Angles representing ATAN(0.5), ATAN(0.25), ATAN(0.125), ...
|
||||
word* CORDIC_ATAN2_ANGLES_16 = 0x1000;
|
||||
|
||||
// Populate cordic angles table
|
||||
kickasm(pc CORDIC_ATAN2_ANGLES_16, uses CORDIC_ITERATIONS_16) {{
|
||||
.for (var i=0; i<CORDIC_ITERATIONS_16; i++)
|
||||
.word 256*2*256*atan(1/pow(2,i))/PI/2
|
||||
}}
|
||||
|
||||
// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
|
||||
// Finding the angle requires a binary search using CORDIC_ITERATIONS_16
|
||||
// Returns the angle in hex-degrees (0=0, 0x8000=PI, 0x10000=2*PI)
|
||||
word atan2_16(signed word x, signed word y) {
|
||||
signed word yi = (y>0)?y:-y;
|
||||
signed word xi = (x>0)?x:-x;
|
||||
word angle = 0;
|
||||
for( byte i: 0..CORDIC_ITERATIONS_16) {
|
||||
if(yi==0) {
|
||||
// We found the correct angle!
|
||||
break;
|
||||
}
|
||||
signed word xd = xi>>i;
|
||||
signed word yd = yi>>i;
|
||||
if(yi>0) {
|
||||
xi += yd;
|
||||
yi -= xd;
|
||||
angle += CORDIC_ATAN2_ANGLES_16[i];
|
||||
} else {
|
||||
xi -= yd;
|
||||
yi += xd;
|
||||
angle -= CORDIC_ATAN2_ANGLES_16[i];
|
||||
}
|
||||
}
|
||||
angle /=2;
|
||||
if(x<0) angle = 0x8000-angle;
|
||||
if(y<0) angle = -angle;
|
||||
// Iterations complete - return estimated angle
|
||||
return angle;
|
||||
}
|
||||
|
||||
// The number of iterations performed during 8-bit CORDIC atan2 calculation
|
||||
const byte CORDIC_ITERATIONS_8 = 8;
|
||||
|
||||
// Angles representing ATAN(0.5), ATAN(0.25), ATAN(0.125), ...
|
||||
byte* CORDIC_ATAN2_ANGLES_8 = 0x1100;
|
||||
|
||||
// Populate cordic angles table
|
||||
kickasm(pc CORDIC_ATAN2_ANGLES_8, uses CORDIC_ITERATIONS_8) {{
|
||||
.fill CORDIC_ITERATIONS_8, 2*256*atan(1/pow(2,i))/PI/2
|
||||
}}
|
||||
|
||||
// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
|
||||
// Finding the angle requires a binary search using CORDIC_ITERATIONS
|
||||
// Returns the angle in hex-degrees (0=0, 0x80=PI, 0x100=2*PI)
|
||||
byte atan2_8(signed byte x, signed byte y) {
|
||||
signed byte yi = (y>0)?y:-y;
|
||||
signed byte xi = (x>0)?x:-x;
|
||||
byte angle = 0;
|
||||
for( byte i: 0..CORDIC_ITERATIONS_8) {
|
||||
if(yi==0) {
|
||||
// We found the correct angle!
|
||||
break;
|
||||
}
|
||||
signed byte xd = xi>>i;
|
||||
signed byte yd = yi>>i;
|
||||
if(yi>0) {
|
||||
xi += yd;
|
||||
yi -= xd;
|
||||
angle += CORDIC_ATAN2_ANGLES_8[i];
|
||||
} else {
|
||||
xi -= yd;
|
||||
yi += xd;
|
||||
angle -= CORDIC_ATAN2_ANGLES_8[i];
|
||||
}
|
||||
}
|
||||
angle = angle/2;
|
||||
if(x<0) angle = 128-angle;
|
||||
if(y<0) angle = -angle;
|
||||
// Iterations complete - return estimated angle
|
||||
return angle;
|
||||
}
|
@ -49,6 +49,8 @@ void print_sword(signed word w) {
|
||||
if(w<0) {
|
||||
print_char('-');
|
||||
w = -w;
|
||||
} else {
|
||||
print_char(' ');
|
||||
}
|
||||
print_word((word)w);
|
||||
}
|
||||
|
41
src/test/kc/cordic-atan2-16.kc
Normal file
41
src/test/kc/cordic-atan2-16.kc
Normal file
@ -0,0 +1,41 @@
|
||||
// Find atan2(x, y) using the CORDIC method
|
||||
// See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf
|
||||
|
||||
import "font-hex"
|
||||
import "atan2"
|
||||
import "c64"
|
||||
|
||||
const byte* CHARSET = 0x2000;
|
||||
const byte* SCREEN = 0x2800;
|
||||
const byte* SCREEN_REF = 0x2c00;
|
||||
|
||||
kickasm(pc SCREEN_REF) {{
|
||||
.for(var y=-12;y<=12;y++)
|
||||
.for(var x=-19;x<=20;x++)
|
||||
.byte round(256*atan2(y, x)/PI/2)
|
||||
}}
|
||||
|
||||
|
||||
void main() {
|
||||
init_font_hex(CHARSET);
|
||||
*D018 = toD018(SCREEN, CHARSET);
|
||||
|
||||
byte* screen = SCREEN;
|
||||
byte* screen_ref = SCREEN_REF;
|
||||
for(signed byte y: -12..12) {
|
||||
for(signed byte x: -19..20) {
|
||||
//byte angle_b = atan2_8(x, y);
|
||||
signed word xw = (signed word)(word){ (byte)x, 0 };
|
||||
signed word yw = (signed word)(word){ (byte)y, 0 };
|
||||
word angle_w = atan2_16(xw, yw);
|
||||
//*screen++ = (>angle_w)-angle_b;
|
||||
//*screen++ = >angle_w;
|
||||
*screen++ = (>(angle_w+0x0080)) - *screen_ref++;
|
||||
//*screen++ = angle_b - *screen_ref++;
|
||||
//*screen++ = *screen_ref++;
|
||||
}
|
||||
}
|
||||
byte* col00 = COLS+12*40+19;
|
||||
while(true) (*col00)++;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
import "font-hex"
|
||||
import "c64"
|
||||
import "atan2"
|
||||
|
||||
|
||||
const byte* CHARSET = 0x2000;
|
||||
const byte* SCREEN = 0x2800;
|
||||
@ -14,7 +16,7 @@ void main() {
|
||||
byte* screen = SCREEN;
|
||||
for(signed byte y: -12..12) {
|
||||
for(signed byte x: -19..20) {
|
||||
byte angle = atan2(x, y);
|
||||
byte angle = atan2_8(x, y);
|
||||
*screen++ = angle;
|
||||
}
|
||||
}
|
||||
@ -24,44 +26,3 @@ void main() {
|
||||
|
||||
}
|
||||
|
||||
// The number of iterations performed during CORDIC atan2 calculation
|
||||
const byte CORDIC_ITERATIONS = 8;
|
||||
|
||||
// Angles representing ATAN(0.5), ATAN(0.25), ATAN(0.125), ...
|
||||
byte* CORDIC_ATAN2_ANGLES = 0x1000;
|
||||
|
||||
// Populate cordic angles table
|
||||
kickasm(pc CORDIC_ATAN2_ANGLES) {{
|
||||
.fill CORDIC_ITERATIONS, 2*256*atan(1/pow(2,i))/PI/2
|
||||
}}
|
||||
|
||||
// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
|
||||
// Finding the angle requires a binary search using CORDIC_ITERATIONS
|
||||
// Returns the angle in hex-degrees (0=0, 128=PI, 256=2*PI)
|
||||
byte atan2(signed byte x, signed byte y) {
|
||||
signed byte yi = (y>0)?y:-y;
|
||||
signed byte xi = (x>0)?x:-x;
|
||||
byte angle = 0;
|
||||
for( byte i: 0..CORDIC_ITERATIONS) {
|
||||
if(yi==0) {
|
||||
// We found the correct angle!
|
||||
break;
|
||||
}
|
||||
signed byte xd = xi>>i;
|
||||
signed byte yd = yi>>i;
|
||||
if(yi>0) {
|
||||
xi += yd;
|
||||
yi -= xd;
|
||||
angle += CORDIC_ATAN2_ANGLES[i];
|
||||
} else {
|
||||
xi -= yd;
|
||||
yi += xd;
|
||||
angle -= CORDIC_ATAN2_ANGLES[i];
|
||||
}
|
||||
}
|
||||
angle /=2;
|
||||
if(x<0) angle = 128-angle;
|
||||
if(y<0) angle = -angle;
|
||||
// Iterations complete - return estimated angle
|
||||
return angle;
|
||||
}
|
Loading…
Reference in New Issue
Block a user