Shop OBEX P1 Docs P2 Docs Learn Events
Problem with Repeat and floating point math. — Parallax Forums

Problem with Repeat and floating point math.

Joe McClureJoe McClure Posts: 21
edited 2007-04-16 22:47 in Propeller 1
Hi all,

I am trying to implement a·line drawing routine in spin but I am having trouble with the floating point stuff.

I am not having much luck, it's hard to explain but with my spin version·(below this c version) I can't get it to increment Y correctly.· It's·an integer/float·problem I think. The X and Y·are longs(?) and·a and b are floating point numbers. Ultimately I would, like do to it in assembly, but I need to understand what's going on first in spin.··

' C++ version: unknown author

void drawLineC(u_char x1, u_char y1, u_char x2, u_char y2, u_char color)
··· {
······· float a, b;
······· u_char x, y;
······· b = (float)((y2 - y1) + 1) / (float)((x2 - x1) + 1);
······· a = y1;
······· for(x = x1; x <= x2; x++)
······· {
··········· for(y = (u_char)a; y <= (u_char)(a + b); y++)
··········· {
··············· if(y <= y2)
··············· {
··················· GotoXY(x, y); // Goto start of fill area (Top Left)
··················· SendLcd(LCDCommand, RAMWR); //··· write to display
··················· SendLcd(LCDData, color);
··············· }
··········· }
··········· a += b;
······· }
··· }





'Spin·version: Was·testing using arguments: 50,50, 131,80

' kinda ugly, trying to get it to work.

·'fmath : "float32full"
·'flmath : "floatmath"
·'fstring : "FloatString"

pub drawLineSpin(x1,y1,x2,y2,color)| x,y,a,b
··· b := fmath.fdiv(fmath.ffloat((y2 - y1) + 1), fmath.ffloat((x2-x1) + 1) )···································································
··· a := y1·······················

··· 'some·'sysouts' for debugging
··· setxy(30,0)·
··· str(fstring.floattostring(b),0, black)

··· 'outter loop
··· repeat x from x1 to x2·······

······ 'some·'sysouts' for debugging
······ setXY(0,10)······
······ str(string("x="),0,black)
······ dec(x,black)·

······ 'inner loop
······ repeat y from a to fmath.fround((fmath.ceil(fmath.fadd(fmath.ffloat(a),b))))·
········ if(y =< y2)

·········· 'some·'sysouts' for debugging
·········· setXY(0,20)··
·········· str(string("y="),0,black)
·········· dec(y, black)··············
·········· setXY(0,30)
·········· str(string("a="),0,black)
·········· dec(a, black)················
·········· setXY(0,40)
·········· str(string("c="),0,black)·····················································
·········· dec(fmath.fround((fmath.ceil(fmath.fadd(fmath.ffloat(a),b)))), black)

············'·plot the dot
·········· plot(x,y,color)

······ a:=fmath.fadd(fmath.ffloat(a),b)

······· 'some·'sysouts' for debugging

······ setXY(0,30)
······ str(string("a="),0,black)
······ dec(a,black)·



Thx!







▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Ahh! Tom Cruise! Use your witchcraft on me to get the fire off of me! ~Ricky Bobby

Comments

  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-04-16 17:28
    So what values are you getting from your sysouts? Do they make sense?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Joe McClureJoe McClure Posts: 21
    edited 2007-04-16 20:39
    sorry, yes. typed it too fast and left out the sys outs:

    I have re-arranged the y output a tad to be a little more usefull. Here's what I have now.

    pub drawLineSpin(x1,y1,x2,y2,color)| x,y,a,b
    ·b := fmath.fdiv(fmath.ffloat((y2 - y1) + 1), fmath.ffloat((x2-x1) + 1) )···································································
    ··· a := y1·······················
    ··· setxy(30,0)·
    ··· str(fstring.floattostring(b),0, black)
    ··· repeat x from x1 to x2·······
    ······ setXY(0,10)······
    ······ str(string("x="),0,black)
    ······ dec(x,black)·
    ······ repeat y from a to fmath.fround((fmath.ceil(fmath.fadd(fmath.ffloat(a),b)))) step 1·······
    ······· setXY(0,20)·····
    ······· str(string("y="),0,black)
    ······· str(fstring.floattostring(y),0, black)
    ······· if(y =< y2)······················
    ·········· setXY(0,30)
    ·········· str(string("a="),0,black)
    ·········· dec(a, black)················
    ·········· setXY(0,40)
    ·········· str(string("c="),0,black)·····················································
    ·········· dec(fmath.fround((fmath.ceil(fmath.fadd(fmath.ffloat(a),b)))), black)··························································
    ·········· plot(x,y,color)
    ······ a:=fmath.fadd(fmath.ffloat(a),b)··
    ······ setXY(0,50)
    ······ str(string("a="),0,black)
    ······ str(fstring.floattostring(a),0,black)········
    ·str(string("Fin"),0,black)···


    Here's how the iterations go:
    b = .2440945

    hits the x loop: x=5
    ·drops to y loop : y increments from· 7.00649 e-44·to· 7.14662 e-44··(ok,·maybe·at first a·FloatToString error?)
    ·drops out of y loop:
    ·a increments·from 50·to·= 50.24412e-44

    hits x loop again: x increments from 5 to 6
    ·drops to y loop again·: y·now starts to·increment (really slowly)·backwards! from 50.2441e-44· e.g. 50.2441e-44·, 50.2440e-44,· 50.2330e-44· etc!!

    Zoinks!! what going on?






    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ahh! Tom Cruise! Use your witchcraft on me to get the fire off of me! ~Ricky Bobby
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-04-16 21:10
    Spin doesn't understand floating point numbers, you cannot iterate a floating point number. You'll notice that the C code can't do it either, they are casting it (converting it) into an unsigned character (a number which can span from 0 to 255) when doing the iteration bounds.

    What spin is doing is it is taking the integer value that represents the floating point number and interpreting it as·that·integer:

    Float_example.PNG·instead of seeing this as 0.15625, it sees it as 1042284544 which is the 32 bit·number interpreted as an integer. Since this has absolutely no meaning, you will get unpredictable results.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 4/16/2007 9:26:17 PM GMT
  • Joe McClureJoe McClure Posts: 21
    edited 2007-04-16 21:24
    Thanks Paul,
    Good info.
    What are my options (if any) for implementing the drawline method?

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ahh! Tom Cruise! Use your witchcraft on me to get the fire off of me! ~Ricky Bobby
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-04-16 21:34
    Y is supposed to be an integer so convert A to an integer using FTrunc. Also (u_char)(a + b) should be interpreted as fmath.FTrunc(fmath.FAdd(a,b)) and when first assigned·A should be set equal to fmath.FFloat(y1).

    C does some automatic casting for you, you must do conversions back and forth between float and integer explicitly in Spin.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Joe McClureJoe McClure Posts: 21
    edited 2007-04-16 22:44
    Thanks Paul,
    That did the trick. I was on the right track, just strayed a little.

    Thx for looking at it.

    Joe

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ahh! Tom Cruise! Use your witchcraft on me to get the fire off of me! ~Ricky Bobby
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-04-16 22:47
    No problem, glad to help.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
Sign In or Register to comment.