Parse error: syntax error, unexpected '<' in /home/vintagec/public_html/vcforum/archive/index.php(475) : eval()'d code on line 1
Plotting a circle the Hard way (in GWBASIC) [Archive] - The Vintage Computer Forums

PDA

View Full Version : Plotting a circle the Hard way (in GWBASIC)


CP/M User
January 11th, 2004, 11:58 PM
---- PCIRC.BAS ---
10 CLS:SCREEN 2:FOR A=1 TO 360
20 X=50*COS(A):Y=50*SIN(A)
30 PSET(50+X,50+Y)
40 NEXT A

---- End PCIRC.BAS ----
Some Notes:Line 10: Clear Screen
Set Video Mode (2 : 640x200 mono)
Begin FOR loop
Line 20: Calculate X
(50 = size of Circle * COS of 1 to 360)
Calculate Y
(50 = size of Circle * SIN of 1 to 360)
Line 30: Plot Point
- Added 50 to draw complete Circle on Screen for X
- Added 50 to draw complete Circle on Screen for Y
Line 40: Go back & add one to FOR loop

Terry Yager
January 12th, 2004, 04:03 AM
Kewl! Can you do it in MBASIC-80 under CP/M? (Now that's the hard way, no pset command.)

--T

carlsson
January 12th, 2004, 06:55 AM
Of course, you can make it even harder by writing your own implementations of sinus and cosinus. The BASIC Handbook by David A. Lien (now, is that a made-up name?) has such subroutines for the poor computers not equipped with trigonometric functions:


1000 REM SIN(X) subroutine: X in radians, result stored in Y
1001 REM C and Z used internally
1002 X=X*57.29578 : REM Skip this line if X is in degrees
1003 IF X=0 THEN 1016
1004 Z=ABS(X)/X : C=X : X=Z*X : IF X<360 THEN 1006
1005 X=X-INT(X/360)*360
1006 IF X<=90 THEN 1012
1007 X=X/90 : Y=INT(X) : X=(X-Y)*90
1008 ON Y GOTO 1009,1010,1011
1009 X=90-X : GOTO 1012
1010 X=-X : GOTO 1012
1011 X=X-90
1012 X=Z*X/57.29578
1013 IF ABS(X)<2.48616E-4 THEN 1016
1014 Y=X*X : Y=((((Y/72-1)*Y/42+1)*Y/20-1)*Y/6+1)*X
1015 GOTO 1017
1016 Y=X
1017 X=C/57.29578 : RETURN


How to use this routine to calculate cosinus is left as an exercise to the reader. :-)

CP/M User
January 12th, 2004, 02:14 PM
"Terry Yager" wrote:

> Kewl! Can you do it in MBASIC-80 under CP/M?
> (Now that's the hard way, no pset command.)

Actually, I'm not one for using MBASIC-80 once,
getting something like this into CP/M would req.
a machine with Graphical abilities. I could
probably do one for the Amstrad.

When I was referening to plotting a circle the hard
way, I was referning to using the standard
graphical commands for archieving this. Normally,
if you want circles & you are using GWBASIC,
then the circle command would be the common
way! :-)

Cheers,
CP/M User.

CP/M User
January 16th, 2004, 10:46 PM
"carlsson" wrote:

> Of course, you can make it even harder by
> writing your own implementations of sinus
> and cosinus. The BASIC Handbook by David
> A. Lien (now, is that a made-up name?) has
> such subroutines for the poor computers not
> equipped with trigonometric functions:

1000 REM SIN(X) subroutine: X in radians, result stored in Y
1001 REM C and Z used internally
1002 X=X*57.29578 : REM Skip this line if X is in degrees
1003 IF X=0 THEN 1016
1004 Z=ABS(X)/X : C=X : X=Z*X : IF X<360 THEN 1006
1005 X=X-INT(X/360)*360
1006 IF X<=90 THEN 1012
1007 X=X/90 : Y=INT(X) : X=(X-Y)*90
1008 ON Y GOTO 1009,1010,1011
1009 X=90-X : GOTO 1012
1010 X=-X : GOTO 1012
1011 X=X-90
1012 X=Z*X/57.29578
1013 IF ABS(X)<2.48616E-4 THEN 1016
1014 Y=X*X : Y=((((Y/72-1)*Y/42+1)*Y/20-1)*Y/6+1)*X
1015 GOTO 1017
1016 Y=X
1017 X=C/57.29578 : RETURN

> How to use this routine to calculate cosinus is left as
> an exercise to the reader. :-)

Wow! That looks interesting. I had the problem of trying
to make my Turbo Pascal programs faster (even though
it had cosine & sine) by writing some faster cosine &
sine, but in actual fact, I made the program much faster
by writing a program which calculates the sine & cosine
& store them into a constant array (also since it was for
a graphical demo, I rounded the numbers to the nearest
decimal number - since the video display doesn't consist
of decimal numbers).

Cheers,
CP/M User.

CP/M User
January 16th, 2004, 10:51 PM
"Terry Yager" wrote:

> Kewl! Can you do it in MBASIC-80 under CP/M?
> (Now that's the hard way, no pset command.)

Terry, I was wonderning which CP/M system you
were referning to with this?

The way I see it, to get something reasonibly
quick, it may have to be system specific, with
graphical abilities.

I don't know how you would make the code as
portable as possible, since I tend to look at
things by a system by system case.

Cheers,
CP/M User.

carlsson
January 17th, 2004, 08:33 AM
I had the problem of trying to make my Turbo Pascal programs faster (even though it had cosine & sine) by writing some faster cosine & sine
I would believe the built in routines are written in assembler, not compiled Pascal, so it might be hard to beat those.

but in actual fact, I made the program much faster by writing a program which calculates the sine & cosine & store them into a constant array
Yes, that is very common in the demo and game programming world, both because one does not have to write a routine to calculate the values and also because it is faster if the needed values already are there.

Speaking about circles, a number of years ago I heard a rumour about a person who had attended a course in drawing circles on free hand. I don't know if it was a bad joke or not, but the rumour claimed anyone who went through the course could draw perfectly round circles on the whiteboard without any tools. I'm sure it is possible to train, but who arranges a course only in drawing circles?

CP/M User
January 17th, 2004, 05:53 PM
"carlsson" wrote:

>> I had the problem of trying to make my Turbo Pascal
>> programs faster (even though it had cosine & sine)
>> by writing some faster cosine & sine

> I would believe the built in routines are written in
> assembler, not compiled Pascal, so it might be hard
> to beat those.

In actual fact, I found that on a machine like my
Amstrad, the Interpreted BASICs Cosine & Sine were
quicker than the ones used in Turbo Pascal. I can
only guess (which maybe a reasonible guess) that
since the interpreted BASIC automatically translated
a decimal number into an Integer, it was doing this
quicker than TP (because I had the problem where I
needed to convert the number into an integer, since
TP wouldn't automatically do it for me! :-)

>> but in actual fact, I made the program much faster
>> by writing a program which calculates the sine &
>> cosine & store them into a constant array

> Yes, that is very common in the demo and game
> programming world, both because one does not have
> to write a routine to calculate the values and also
> because it is faster if the needed values already are
> there.

Maybe less so nowadays, since computers are so quick
that it's not so noticable. I guess it's good for games
as they need to quick & just leave the more random
features to be worked out instead.

> Speaking about circles, a number of years ago I
> heard a rumour about a person who had attended a
> course in drawing circles on free hand. I don't know if
> it was a bad joke or not, but the rumour claimed
> anyone who went through the course could draw
> perfectly round circles on the whiteboard without any
> tools. I'm sure it is possible to train, but who arranges
> a course only in drawing circles?

I think it's hard enough drawing a perfectly round circle
on the computer, let alone doing one freehand. So, I'd
take that as a bad joke! :-)

Cheers,
CP/M User.

mbbrutman
January 20th, 2004, 07:47 AM
This is an interesting thread. It gives me some ideas for one of my side projects.

On a PCjr there are video modes supported by the special 'Cartridge BASIC' but not supported by programming environments like Turbo Pascal or Turbo C. It was the only machine with those video modes, so none of the software houses bothered to support it. (The Tandy 1000 video modes are similar.) If you wanted to use these video modes, you need to write your own assembler.

I've started playing with machine language to do primitives, like putting up specific pixels and drawing lines. It's done using assembler and poking directly into the video buffer for speed. (The BIOS routines are slow because they are general purpose.)

It's a lot harder than it sounds. Although video memory is 32K and it is contiguous, it is not a linear mapping. i.e: The screen is interleaved in memory. On a machine with an 8088 floating point takes too long; integer arithmetic is preferred.

People should try their hand at drawing lines, circles, doing fill routines, etc. - it's not that easy. It makes you appreciate BASIC a little more. :-)

carlsson
January 20th, 2004, 10:03 AM
I once took a (3D) graphics course, and the first lab was to produce a triangle filler to be used later. The basic version used floating point, but as a bonus exercise we had to do an integer version. I might locate my code somewhere and let you find ideas if you need. It is written in C though and only does lines/triangles.

Re: the PCjr and Tandy - I knew a Wang PC which apart from its IBM PC/CGA emulation mode had a few extended modes on its own, namely 320x200x16 and 640x200x4. Does those sound like the PCjr modes, or did it have even more variation? Obviously the BASIC in Wang mode took care of the more colours. It is one of the few personal (incl. UNIX workstations) computers I would like to have gotten.

CP/M User
January 20th, 2004, 02:26 PM
"mbbrutman" wrote:

> This is an interesting thread. It gives me some ideas for
> one of my side projects.

Good! :-)

> On a PCjr there are video modes supported by the
> special 'Cartridge BASIC' but not supported by
> programming environments like Turbo Pascal or Turbo
> C. It was the only machine with those video modes, so
> none of the software houses bothered to support it.
> (The Tandy 1000 video modes are similar.) If you
> wanted to use these video modes, you need to write
> your own assembler.

Which Video Mode are you referning to?

Cheers,
CP/M User.

mbbrutman
January 20th, 2004, 08:45 PM
Jrs have 3 non-standard modes:

320x200 in 16 colors. This requires 32K of video ram.
160x200 in 16 colors. This requires just 16K of video ram.
640x200 in 4 colors. This requires 32K of video ram.

And of course you have the standard CGA modes.

On standard CGA modes and the 160x200 mode, the screen memory is in two banks. On the modes requiring 32K, the screen memory is divided into four banks.

On a Jr things are compounded more by the goofy video circuitry. Normal CGA starts at B8000 in the memory map, and goes for 16K. The Jr's video memory is actually on the first 128K of the system board, and it lessens the amount available for DOS. To be compatible with CGA, memory references to the 16K starting at B8000 are magically remapped to the correct memory segment on the system board.

That works fine for the 16K modes. However to hit the upper part of a 32K mode video screen you actually have to hit the real memory location, not an offset from B8000. That's because the redirection circuitry only redirects 16K.

It's not a big problem, except that the Jr tries to hide the true location of video memory from you. Have have to try to find it in the first 128K. :-)

CP/M User
January 20th, 2004, 09:37 PM
"mbbrutman" wrote:

> Jrs have 3 non-standard modes:

> 320x200 in 16 colors. This requires 32K of video ram.
> 160x200 in 16 colors. This requires just 16K of video ram.
> 640x200 in 4 colors. This requires 32K of video ram.

> And of course you have the standard CGA modes.

I suspect that this would be an enhancement of the CGA
card, since CGA allowed up to 16k of memory I believe.

Though it doesn't have 160x200x16, only 160x100x16
which a couple of games made use of (it wasn't support
from the BIOS - so special routines were required to
access this).

> On standard CGA modes and the 160x200 mode, the
> screen memory is in two banks. On the modes
> requiring 32K, the screen memory is divided into four
> banks.

> On a Jr things are compounded more by the goofy
> video circuitry. Normal CGA starts at B8000 in the
> memory map, and goes for 16K. The Jr's video
> memory is actually on the first 128K of the system
> board, and it lessens the amount available for DOS.
> To be compatible with CGA, memory references to
> the 16K starting at B8000 are magically remapped
> to the correct memory segment on the system
> board.

> That works fine for the 16K modes. However to
> hit the upper part of a 32K mode video screen you
> actually have to hit the real memory location, not
> an offset from B8000. That's because the
> redirection circuitry only redirects 16K.

It's seems easy enough to redirect the first 16k,
since standard IBM programs (for CGA) would
look there. So it seems like an deliberate way of
telling the programmer that if you know where
the other 32k is, then use that, unfortuately it's
not friendly, if someone tried to use a Jnr program
which does that on their IBM! ;-)

Cheers,
CP/M User.

mbbrutman
January 24th, 2004, 12:51 PM
Oh yes - it's definitely non standard CGA. The Jr had these extra video modes, most (or all) of which are available on the Tandy 1000. The Tandy 1000 was a PCjr clone .. a bit more successful though.

As a cost cutting measure the Jr shared video memory with main memory, instead of having a separate 16K of video memory on a CGA card. The circuitry allows you to grow and shrink the amount of memory used by the video controller dynamically.

A true CGA 160x100 mode probably would have been done by programing that 6845 CRT controller directly. On the Jr 160x200x16 was a fully supported mode in BIOS and BASIC.

We generally don't worry about Jr specific programs running on other machines - I can count those programs on my fingers. Any machine that was Jr specific for sound or video checked the ID byte in BIOS on the machine first to see if the extra hardware was available. Same with the Tandy 1000 video modes and sound ..

CP/M User
January 24th, 2004, 02:25 PM
"mbbrutman" wrote:

> As a cost cutting measure the Jr shared video memory
> with main memory, instead of having a separate 16K
> of video memory on a CGA card. The circuitry allows
> you to grow and shrink the amount of memory used
> by the video controller dynamically.

Do you know how far this can go, or is it like you said
between 16k & 32k.

Cheers,
CP/M User.

mbbrutman
January 24th, 2004, 06:46 PM
The whole 128K can be used. In reality, it's more like 96K. If you tried to use the whole 128K, you'd be stepping on the interrupt vector area, and that's a definite no-no .. You'd also have no place to run software to use the video buffer.

I've used 64K before - 2 screens of 32K. Generally the most that is used is 32K.

Tandy 1000 machines should be a lot more flexible - their video memory comes out of the high memory ranges, either right below 512K or right below 640K. (The Jr was only designed to have 128K, so conceptually the video memory is pulled from the top of memory too.) The Tandy 1000 probably can allocate gobs of memory because they don't have to worry about bumping into the interrupt vector. Can any Tandy 1000 owners confirm this?

CP/M User
January 24th, 2004, 09:50 PM
"mbbrutman" wrote:

> The whole 128K can be used. In reality, it's more
> like 96K. If you tried to use the whole 128K,
> you'd be stepping on the interrupt vector area,
> and that's a definite no-no .. You'd also have no
> place to run software to use the video buffer.

> I've used 64K before - 2 screens of 32K.
> Generally the most that is used is 32K.

> Tandy 1000 machines should be a lot more
> flexible - their video memory comes out of the
> high memory ranges, either right below 512K
> or right below 640K. (The Jr was only designed
> to have 128K, so conceptually the video memory
> is pulled from the top of memory too.) The
> Tandy 1000 probably can allocate gobs of
> memory because they don't have to worry about
> bumping into the interrupt vector. Can any
> Tandy 1000 owners confirm this?

Oh okay. Theorically, if it's possible to add more
memory for the Jnr, or move the Interrupt Vector
elsewhere, then the 128k could be used, couldn't
it, or is the Interrupt Vector part of the screen
memory?

Cheers,
CP/M User.

mbbrutman
January 25th, 2004, 04:26 PM
Ah, the big difference between a Jr and a Tandy ....

The Jr was designed with a max of 128K of memory. All of that memory sits on the motherboard, or in a special expansion card that goes on dedicated slot on the motherboard. The circuitry that redirects memory address references from B8000 down to the first 128K of memory doesn't have the wiring to access more memory. The wiring is on a specific piece of the motherboard, and doesn't extend down the I/O bus. There are also a limited number of bits in the register that controls which 16K chunk of memory will be used.

Both the Jr and the Tandy 1000 'grow' the video memory downward from the top of installed memory. The difference is that the Tandy 1000 is designed with 512 or 640K in mind, so it pulls from the top of memory. (Probably just up to 128K like the Jr to stay compatible with the register setup on the Jr.) The Tandy probably puts all of it's memory on the motherboard, and the circuitry can probably access the top 128K of memory no matter how much is installed.

Jr memory expansion products came later, and they sit on the I/O bus.

Let's compare the two machines, both with a hypothetical 384. The Jr's video memory has to come from the bottom 128K because of the wiring limitations. DOS interrupt vectors will be in the lowest 16K. Then will come space for video memory. At the 128K mark DOS and apps will start, giving you 16K for interrupt areas, 96K for video memory, and 128K for DOS and apps.

On a Tandy1000 you have the same 16K at the bottom of memory for interrupts. But right after that, you can have DOS and apps, and then the video memory at the very top of memory.

The Tandy 1000 setup is better because you can make a bigger contiguous chunk of memory for DOS and apps. On the PCJr because of the goofy wiring, the first 128K is best left for the interrupt vector, video memory, and a ram disk. The first 128K of memory has to give access to the video controller on a regular basis, so if you use it for programs and code (as originally designed), the processor gets lower priority and it runs slower than a normal PC clone.

I love these hardware tradeoffs - that's what makes each old machine unique. Nobody has to sweat stuff like this anymore ...

CP/M User
January 26th, 2004, 12:02 AM
So it looks like the Tandy people have looked at the
issues concerning the PC Jnr & came up with an
solution! :-)

Cheers,
CP/M User.

nodoubt73
March 8th, 2004, 01:16 AM
Here another way.... :

Sin function

10 INPUT X#
20 GOSUB 1000
30 PRINT Y#
40 END
1000 REM SIN(X#). X# IN RADIANTS. OUTPUT IN Y#
1010 RESULT# = 0 : SIGN%=-1
1020 DOUBLEPI#=6.283185307#
1030 PRECISION = 50
1040 TEMP% = X#/DOUBLEPI#
1050 X#=X#-TEMP%*DOUBLEPI#
1060 FOR K=1 TO PRECISION
1070 ADDENDUM#=X#
1080 FOR SCANIT=2 TO 2*K+1
1090 PARTQUOT#=X#/SCANIT
1100 ADDENDUM#=ADDENDUM#*PARTQUOT#
1110 NEXT SCANIT
1120 RESULT#=RESULT#+(ADDENDUM#*SIGN%)
1130 SIGN%=SIGN%*-1
1140 NEXT K
1150 Y#=X#+RESULT#
1160 RETURN


and Cos function

10 INPUT X#
20 GOSUB 1000
30 PRINT Y#
40 END
1000 REM COS(X#). X# IN RADIANTS. OUTPUT IN Y#
1010 RESULT# = 0 : SIGN%=-1
1020 DOUBLEPI#=6.283185307#
1030 PRECISION = 50
1040 TEMP% = X#/DOUBLEPI#
1050 X#=X#-TEMP%*DOUBLEPI#
1060 FOR K=1 TO PRECISION
1070 ADDENDUM#=X#
1080 FOR SCANIT=2 TO 2*K
1090 PARTQUOT#=X#/SCANIT
1100 ADDENDUM#=ADDENDUM#*PARTQUOT#
1110 NEXT SCANIT
1120 RESULT#=RESULT#+(ADDENDUM#*SIGN%)
1130 SIGN%=SIGN%*-1
1140 NEXT K
1150 Y#=1+RESULT#
1160 RETURN

CP/M User
March 8th, 2004, 09:59 PM
"nodoubt73" wrote:

> Here another way.... :

> Sin function
10 INPUT X#
20 GOSUB 1000
30 PRINT Y#
40 END
1000 REM SIN(X#). X# IN RADIANTS. OUTPUT IN Y#
1010 RESULT# = 0 : SIGN%=-1
1020 DOUBLEPI#=6.283185307#
1030 PRECISION = 50
1040 TEMP% = X#/DOUBLEPI#
1050 X#=X#-TEMP%*DOUBLEPI#
1060 FOR K=1 TO PRECISION
1070 ADDENDUM#=X#
1080 FOR SCANIT=2 TO 2*K+1
1090 PARTQUOT#=X#/SCANIT
1100 ADDENDUM#=ADDENDUM#*PARTQUOT#
1110 NEXT SCANIT
1120 RESULT#=RESULT#+(ADDENDUM#*SIGN%)
1130 SIGN%=SIGN%*-1
1140 NEXT K
1150 Y#=X#+RESULT#
1160 RETURN

> and Cos function
10 INPUT X#
20 GOSUB 1000
30 PRINT Y#
40 END
1000 REM COS(X#). X# IN RADIANTS. OUTPUT IN Y#
1010 RESULT# = 0 : SIGN%=-1
1020 DOUBLEPI#=6.283185307#
1030 PRECISION = 50
1040 TEMP% = X#/DOUBLEPI#
1050 X#=X#-TEMP%*DOUBLEPI#
1060 FOR K=1 TO PRECISION
1070 ADDENDUM#=X#
1080 FOR SCANIT=2 TO 2*K
1090 PARTQUOT#=X#/SCANIT
1100 ADDENDUM#=ADDENDUM#*PARTQUOT#
1110 NEXT SCANIT
1120 RESULT#=RESULT#+(ADDENDUM#*SIGN%)
1130 SIGN%=SIGN%*-1
1140 NEXT K
1150 Y#=1+RESULT#
1160 RETURN

Does that work in DEGrees or RADians?

For example, SIN 1 in DEGrees is
0.017452406 & COS 1 in DEGrees
is 0.999847695. In RADians SIN 1
is 0.841470984 & COS 1 is
0.540302305.

So if that works in DEGrees, then that
could be something I could port to TP.

Cheers,
CP/M User.

carlsson
March 8th, 2004, 11:33 PM
1000 REM SIN(X#). X# IN RADIANTS. OUTPUT IN Y#
Does that work in DEGrees or RADians?
Radians it seems. Otherwise it is fairly easy to convert degrees into radians or the other way:

DEG = RAD * (180/pi) : REM 180/pi ~= 57.29578
RAD = DEG / (180/pi)

nodoubt73
March 9th, 2004, 12:02 AM
Does that work in DEGrees or RADians?
For example, SIN 1 in DEGrees is
0.017452406 & COS 1 in DEGrees
is 0.999847695. In RADians SIN 1
is 0.841470984 & COS 1 is
0.540302305.
So if that works in DEGrees, then that
could be something I could port to TP.
Cheers,
CP/M User.

Hi there. IT's all in RADIANTS.
indeed lines 1040 and 1050, as you see, are there to "normalize"
the parameter, that means it will "reduce" it to 0-6.28 range that's
the angle (as you see before and afterward it all repeats to infinite).
I had to use 2 lines to do that in basic (or better 2 statements, could
stay all in one line). In C (language in which I originally wrote
this serie method to implement trigonom. functions) the normalization
was:

x = x-((unsigned long)(x/DoublePI))*DoublePI;

where x and DoublePI are defined as "double".
I could probably do that with a remainder function, but I needed
top performance (this is a real life application, gotta control a 4
stepper motor interpolation, real time stuff).

Just to give coupla info more:
PRECISION identifier is something up to you and your machine power.
The bigger that value is the better result you get. As you may guess
the serie method to calculate these function tends to be perfect as long
as the serie is infinite. Ofcourse this ain't possible, so you gotta tell
the machine how many serie item you wanna evaluate.

This serie method is simply the Mac Laurin one.
To put it in coupla lines, it says:

sin(x) = x - (x^3) + (x^5)+..+(-1)^(n-1)*( x^(2n-1))
------- -------- --------------
3! 5! (2n-1)!


Using the same principle, I've the coding for the functions
Tan, ArcSin, ArcCos.

Ciao

CP/M User
March 11th, 2004, 10:37 PM
"carlsson" wrote:

>> Does that work in DEGrees or RADians?

> Radians it seems. Otherwise it is fairly easy
> to convert degrees into radians or the other
> way:

> DEG = RAD * (180/pi) : REM 180/pi ~= 57.29578
> RAD = DEG / (180/pi)

Carlsson, if you say it's easy to covert, could you
(or someone here) at least show me what I'm doing
wrong, because I seem to be missing something:

Set Calculator to DEGrees:

SIN 1 = 0.017452406
Put in Memory

Now I'm calculating it like this:

Memory Recall (0.017452406)/ (180/3.141592654) =
57.29577951, I'm sorry, but this just isn't the RAD
value of SIN 1! Or 'am I doing something wrong?

Cheer,
CP/M User.

CP/M User
March 11th, 2004, 10:44 PM
"nodoubt73" wrote:

> Hi there. IT's all in RADIANTS.
> indeed lines 1040 and 1050, as
> you see, are there to "normalize"
> the parameter, that means it will
> "reduce" it to 0-6.28 range that's
> the angle (as you see before and
> afterward it all repeats to infinite).

> I had to use 2 lines to do that in
> basic (or better 2 statements, could
> stay all in one line). In C (language
> in which I originally wrote this serie
> method to implement trigonom.
> functions) the normalization
> was:
x = x-((unsigned long)(x/DoublePI))*DoublePI;

> where x and DoublePI are defined as
> "double".
> I could probably do that with a
> remainder function, but I needed
> top performance (this is a real life
> application, gotta control a 4 stepper
> motor interpolation, real time stuff).

> Just to give coupla info more:
> PRECISION identifier is something
> up to you and your machine power.
> The bigger that value is the better
> result you get. As you may guess
> the serie method to calculate these
> function tends to be perfect as long
> as the serie is infinite. Ofcourse
> this ain't possible, so you gotta tell
> the machine how many serie item
> you wanna evaluate.

> This serie method is simply the Mac
> Laurin one.
> To put it in coupla lines, it says:
sin(x) = x - (x^3) + (x^5)+..+(-1)^(n-1)*( x^(2n-1))
------- -------- --------------
3! 5! (2n-1)!

> Using the same principle, I've the
> coding for the functions Tan, ArcSin,
> ArcCos.

Hi there, it makes for interesting reading,
unfortunately my maths isn't so sofisicated
as I'd like it to be.

For the machine I'm using, I'm finding that
my values don't need to be highly accurate
because they are being used for graphical
purposes. Sure if the resolution of the screen
was more than 16k bigger numbers would be
required.

Cheers,
CP/M User.

nodoubt73
March 11th, 2004, 11:42 PM
"nodoubt73" wrote:
Hi there, it makes for interesting reading,
unfortunately my maths isn't so sofisicated
as I'd like it to be.

For the machine I'm using, I'm finding that
my values don't need to be highly accurate
because they are being used for graphical
purposes. Sure if the resolution of the screen
was more than 16k bigger numbers would be
required.

Cheers,
CP/M User.

just decrease the PRECISION 8)

carlsson
March 12th, 2004, 01:38 AM
> DEG = RAD * (180/pi) : REM 180/pi ~= 57.29578
> RAD = DEG / (180/pi)
Set Calculator to DEGrees: SIN 1 = 0.017452406
Memory Recall (0.017452406)/ (180/3.141592654) = 57.29577951
Try push ENTER once more, as 180/pi = 57.295. I think your calculator has a surprise in store for you.

Remember than sinus of one radian (57 degrees) will be 0.84, while sinus of one degree (0.017 radians) will also be 0.017. Somewhere around pi/6 (30 degrees), there will be a difference between the input argument and the sinus result.

CP/M User
March 12th, 2004, 12:40 PM
"carlsson" wrote:

>>> DEG = RAD * (180/pi) : REM 180/pi ~= 57.29578
>>> RAD = DEG / (180/pi)

>> Set Calculator to DEGrees: SIN 1 = 0.017452406
>> Memory Recall (0.017452406)/ (180/3.141592654) =
>> 57.29577951

> Try push ENTER once more, as 180/pi = 57.295. I
> think your calculator has a surprise in store for you.

> Remember than sinus of one radian (57 degrees) will
> be 0.84, while sinus of one degree (0.017 radians)
> will also be 0.017. Somewhere around pi/6 (30
> degrees), there will be a difference between the input
> argument and the sinus result.

Strewth, I did something which got me a value of
0.999949231 & I then did the (180/pi) which got me
the .017452406.

Oh now I got it, SIN 1 * (180/pi) = 0.999949231. Oh but
wait, no I've got this horribly wrong because the value
I'm after here is 0.841470984.

Help!! :-(
CP/M User.

carlsson
March 14th, 2004, 01:55 PM
SIN 1 * (180/pi) = 0.999949231.
Oh but wait, no I've got this horribly wrong because the value
I'm after here is 0.841470984.
Hmm.. not sure what you're trying to do. Does your calculator or computer really work with radians or degrees? Four scenarios:

1. SIN 1 * (180/pi) will calculate sinus of 1 (something) and then multiply with 57.295. OK?

2. Sinus of 1 degree is 0.017, while sinus of 1 radian is 0.841, so either you get 0.999949 or 48.21273601. OK?

3. SIN (1*(180/pi)) will give you the sinus of 57.295 (something). OK?

4. Sinus of 57.295 degrees is 0.84 as I wrote. Sinus of 57.295 radians wraps around many times and ends in 0.679522. OK?

CP/M User
March 14th, 2004, 06:49 PM
Hi carlsson,

I've just come from a maths Usenet group
which showed me what I did wrong.

I was going into Radians for example &
doing a SIN 1 first, got the result from that
& then tried to convert that result into
Degrees.

I didn't realise it was the number after SIN
which needed to be converted.

Having said that I did this to get the right
result.

1 * PI/180 = 0.017453292
SIN 0.017453292 = 0.017452406 (which is
the answer to SIN 1 in Degrees! :-)

Just for good measure I tried SIN 2 just to
make sure it wasn't a fluke:

2 * PI/180 = 0.034906585 &
SIN 0.034906585 = 0.034899496!

Oh well, the main thing is I got it eventually
with some help! ;-)

Thanks,
CP/M User.

carlsson
March 16th, 2004, 05:58 AM
I didn't realise it was the number after SIN which needed to be converted.
You mean the argument to SIN, or the result after applying SIN?

Just for good measure I tried SIN 2 just to
make sure it wasn't a fluke:
Try 30, 60, 90 etc and see if you still get the right results. As I wrote above, around pi/6 radians (30 degrees), the difference between input angle and the SIN function is getting so large that you can deduct what "happened". 8)

CP/M User
March 16th, 2004, 04:15 PM
"carlsson" wrote:

>> I didn't realise it was the number after
>> SIN which needed to be converted.

> You mean the argument to SIN, or the
> result after applying SIN?

Originally, I was trying to convert the result
from SIN 1 into Degrees! ;-)

>> Just for good measure I tried SIN 2
>> just to make sure it wasn't a fluke:

> Try 30, 60, 90 etc and see if you still
> get the right results. As I wrote above,
> around pi/6 radians (30 degrees), the
> difference between input angle and the
> SIN function is getting so large that you
> can deduct what "happened". 8)

Yes, SIN 30 while it's not 0.5 the result was
0.499999999 seems close enough! ;-)
The other two provided the correct answers
in both cases (SIN 60 = 0.866025403 &
SIN 90 = 1).
While I'm using a calculator which can do
upto 9 decimal places, in case of SIN 30
if you did need the persise answer (of 0.5)
you'd perhaps need a calculator to support
more decimal places (don't ask me how
many), but more so that PI is accurate
enough (some people say that they know
PI to the 100th decimal place - that's 3.
<followed by 100 numbers!> I've always
wondered why, so perhaps this is it - but
that would mean building a calculator
which would have to be of a large figure
in order to fit those 101 digits! ;-)

Cheers,
CP/M User.

carlsson
March 17th, 2004, 02:34 AM
Yup, Pi is a story on its own. I once read an article about a mathematician where he quoted someone who had said that Pi lately had changed from a mysterious number into something you wash your mouth with, when calcuation of Pi had moved from people's hand work to powerful computers doing one million of decimals just for fun.

CP/M User
March 17th, 2004, 03:20 AM
"carlsson" wrote:

> Yup, Pi is a story on its own. I
> once read an article about a
> mathematician where he
> quoted someone who had
> said that Pi lately had changed
> from a mysterious number into
> something you wash your mouth
> with, when calcuation of Pi had
> moved from people's hand work
> to powerful computers doing one
> million of decimals just for fun.

Maybe for the serious mathematician
it maybe critical that they get the
most accurate read out, but for the
purpose of programming, it may not
be as critical (well maybe not in to
area of graphics). My Demonstration
that I posted earlier, which calculates
the Degrees to draw up a circle, is
only using Pi to 6 decimal places.
While the answer wouldn't be as
accurate (verus a 9 decimal place),
the image seems to be correct (or
to the effect that it looks right. There
maybe a few little gaps in it, but
that just happens to be the way this
draws itself out (even on the Ol'
Amstrad it happens).

Cheers,
CP/M User.

carlsson
March 18th, 2004, 01:43 AM
The gaps are probably due to other reasons than Pi accuracy, i.e. you would need some addition to the drawing algorithm that decides which pixels between addressed pixels should also be lit. Off-hand I don't know how to make those decisions, but maybe there can be straight lines between two dots which happen to have a distance of more than one pixel in between.

Barry
March 18th, 2004, 06:53 AM
There is the Bresneham circle drawing algorithm, which I've just heard of but don't know how to code, that follows a pattern of pixels, pixel to pixel, forming a circle. It's not made from endpoints of radii.

If you use a formula involving PI I think you're probably stuck with drawing lines from pixel to pixel to be sure the circle is closed.

One method I read about years ago that speeds the drawing of a circle is to only calculate a segment and replicate it. I don't remember the details of this. I'm not sure but it might have been part of the Bresneham circle algorithm.

It shouldn't be hard to google some information on this.

Barry

CP/M User
March 18th, 2004, 12:20 PM
"carlsson" wrote:

> The gaps are probably due to other reasons
> than Pi accuracy, i.e. you would need some
> addition to the drawing algorithm that decides
> which pixels between addressed pixels should
> also be lit. Off-hand I don't know how to make
> those decisions, but maybe there can be
> straight lines between two dots which happen
> to have a distance of more than one pixel in
> between.

To be honest, it's not something I've considered
doing, because it's such a variable effect, in
which is varys depending on the size of the circle
& the resolution for which it's been drawn in. In
320x200 for example, there are fewer gaps.

It's not really something I'd worry about, in a way
I'm glad it's happened, cause it's more like the
circles drawn on an Amstrad. Since I've written an
equivalent program for the IBMs, it would have
been unusual if this gap effect didn't happen! :-)

Cheers,
CP/M User.

CP/M User
March 18th, 2004, 12:24 PM
"Barry" wrote:

> There is the Bresneham circle drawing algorithm,
> which I've just heard of but don't know how to
> code, that follows a pattern of pixels, pixel to
> pixel, forming a circle. It's not made from
> endpoints of radii.

Think I've got a BASIC example somewhere for
the Amstrad. I'll try & find it & port it over. I know
I've got one which plots a pixel by pixel around the
edge of the circle, but I'm sure there was another
one which draws a solid line around the edge too.

Cheers,
CP/M User.

CP/M User
March 18th, 2004, 01:11 PM
"CP/M User" wrote:

>> There is the Bresneham circle drawing algorithm,
>> which I've just heard of but don't know how to
>> code, that follows a pattern of pixels, pixel to
>> pixel, forming a circle. It's not made from
>> endpoints of radii.

> Think I've got a BASIC example somewhere for
> the Amstrad. I'll try & find it & port it over. I know
> I've got one which plots a pixel by pixel around the
> edge of the circle, but I'm sure there was another
> one which draws a solid line around the edge too.

Yeah, basically you modify my program in line 40,
so instead of saying you want to draw a line from
the centre of the circle, you tell it to draw around:

Basically, it would look like this:
40 LINE (320+XPOS-1,100+YPOS-1)-(320+XPOS,100+YPOS)


I don't think they call this the Bresneham drawning
algorithm though, some of the code I've seen which
demonstrates this, goes into some of the more
advance math.

Cheers,
CP/M User.

Barry
March 19th, 2004, 04:06 PM
Basically, it would look like this:
Code:
40 LINE (320+XPOS-1,100+YPOS-1)-(320+XPOS,100+YPOS)



I don't think they call this the Bresneham drawning
algorithm though, some of the code I've seen which
demonstrates this, goes into some of the more
advance math.

That's not the bresneham algorithm. Bresneham wrote a method by for calculating each pixel. Line drawing isn't needed. Line drawing around the circle using radii is a simpler method. Bresneham is used when speed is needed. It's unique in that it doesn't need division or multiplcation. Only addition or subtraction, which are much faster in most processors.

There's also a bresneham line drawing algorithm.

Barry

CP/M User
March 19th, 2004, 07:48 PM
"Barry"

>> I don't think they call this the Bresneham drawning
>> algorithm though, some of the code I've seen which
>> demonstrates this, goes into some of the more
>> advance math.

> That's not the bresneham algorithm. Bresneham
> wrote a method by for calculating each pixel. Line
> drawing isn't needed. Line drawing around the
> circle using radii is a simpler method. Bresneham
> is used when speed is needed. It's unique in that
> it doesn't need division or multiplcation. Only
> addition or subtraction, which are much faster in
> most processors.

> There's also a bresneham line drawing algorithm.

I know where you should be able to find some
Turbo Pascal examples & an Assembly example
I think of the Bresneham algorithm.

The Turbo Pascal examples are available at the
SWAG archive (in the Graphics) area. SWAG is
here:
http://www.gdsoft.com/swag/swag.html

you'll need to also download a viewer though,
cause the archives are in a special file format
(specific to what they have the archives in).

For memory I'm pretty sure there are some
Bresneham examples in there.

Also, just check out the CP/M-86 Software
Repository at http://www.seanet.com/~klaw/
cause I'm sure there's an assembly example
in there. Even if you're not into CP/M-86, the
source code may give you a good idea on
how it's done! :-)

Cheers,
CP/M User.