Circular Motion using sin&cos?
Root / Programming Questions / [.]
KrondeloCreated:
So I figured out circular motion, pretty simple really. However I can't figure out how to CONTROL it. Like if you hold up you will travel along the circle CCW, and down for CW movement. I imagine you could easily code being able to move in and out as well by simply adjusting the radius.
TPI=6.2831855 '(2*PI) DEF CIRC D WHILE A<TPI CX=399/2+COS(A)*D CY=239/2+SIN(A)*D GCIRCLE CX,CY,CR,RGB(R,G,B) A=A+.05 VSYNC GCLS WEND ENDSo there is the function, but which variable would you manipulate to move along that path or is it not that simple? I tried only increasing A on button press, or only updating the CX and CY positions with pressing DOWN, then for UP simply switch CX to be minus COS. Nothing happens though? Any thoughts?
Here's how I learned circular trajectories.
DEF CIRC X,Y,RX,RY,C VAR I,T=PI()*2 FOR(I)=(0)TO(T)STEP(T/(T*MAX(RX,RY))) GPSET(COS(I)*RX+X),(SIN(I)*RY+Y),(C) NEXT(I) ENDThis function draws an ellipse centered at X,Y with a width of 2*RX and a height 2*RY (with color C). However, you seem to want circular motion. If you follow the math behind drawing an ellipse, you should be able to plot the thing-that's-in-motion at it's position along it's circular path per time.
Thanks @Hanzo and @MZ952, I will study these further. I reset A at the end of the loop but it can cause an object in rotation to suddenly snap back to it's initial position.
I think I need to learn more how to implement logical arguments such as the one Hanzo mentioned rather than using weird flags or resets at times that don't always make sense.
Here's how I learned circular trajectories.You've got a lot of unnecessary parentheses there... Note also that while older BASICs required putting the variable name after NEXT, SmileBASIC actually just ignores it. Also, x/(x*y) simplifies to 1/y, so your step can be simplified.DEF CIRC X,Y,RX,RY,C VAR I,T=PI()*2 FOR(I)=(0)TO(T)STEP(T/(T*MAX(RX,RY))) GPSET(COS(I)*RX+X),(SIN(I)*RY+Y),(C) NEXT(I) ENDThis function draws an ellipse centered at X,Y with a width of 2*RX and a height 2*RY (with color C). However, you seem to want circular motion. If you follow the math behind drawing an ellipse, you should be able to plot the thing-that's-in-motion at it's position along it's circular path per time.
DEF CIRC X,Y,RX,RY,C VAR I,T=PI()*2 FOR I=0 TO T STEP 1/MAX(RX,RY) GPSET COS(I)*RX+X,SIN(I)*RY+Y,C NEXT END
Ah, good catch with my flawed math there. I came up with it on the fly, didn't think much about rounding it out. The parenthesis I like to put there for structure. My eye catches and reads the code better that way, and it's basically a habit now. And it doesn't exactly affect the performance of the code, either. Oh, and I'm aware of the ignoring thing, too. Sometimes, just for kicks, I'll toss a SQR(-1) in there.Here's how I learned circular trajectories.You've got a lot of unnecessary parentheses there... Note also that while older BASICs required putting the variable name after NEXT, SmileBASIC actually just ignores it. Also, x/(x*y) simplifies to 1/y, so your step can be simplified.DEF CIRC X,Y,RX,RY,C VAR I,T=PI()*2 FOR(I)=(0)TO(T)STEP(T/(T*MAX(RX,RY))) GPSET(COS(I)*RX+X),(SIN(I)*RY+Y),(C) NEXT(I) ENDThis function draws an ellipse centered at X,Y with a width of 2*RX and a height 2*RY (with color C). However, you seem to want circular motion. If you follow the math behind drawing an ellipse, you should be able to plot the thing-that's-in-motion at it's position along it's circular path per time.DEF CIRC X,Y,RX,RY,C VAR I,T=PI()*2 FOR I=0 TO T STEP 1/MAX(RX,RY) GPSET COS(I)*RX+X,SIN(I)*RY+Y,C NEXT END
Like you have already noticed, an increase of argument of sin and cos stands for CW rotation, and a decrease stands for CCW rotation. And I recommend you to add the following code in order to avoid overflow/underflow of A variable.Actually can someone explain to me what this part does exactly?((A<0)-(A>=(2*PI()))))
Okay, take this example:
You have a program that prints things to the screen, but it obviously can't print outside the screen coordinates, because that would produce an error, and the function can print on any screen.
DEF PRNT X,Y,S$ VAR D=DISPLAY() (X)=MAX(49*!D,39*D) (Y)=MIN(Y,29) LOCATE(X),(Y)?S$;I used a logical argument to set the value of X by saying: X will be the largest of either 49*(logical NOT of D) or 39*(logical value of D). Logically, D will be either 0 or 1, so I could use it for this purpose. If the display was set to 0, then 49*(!0) = 49*(1) which is 49, while 39*(0) is 0. MAX(49,0) is 49. But if D was 1, the opposite would occur. MAX(0,39) is 39. This works for any logical argument ==, <=, >=, !, !=, &&, ¦ ¦ , etc. That's how IF statements work. They're checking for logical TRUE. By saying IF(A==B)THEN you're not checking if A is equal to B, you're checking if A equals B is TRUE. If it is true, it returns 1, otherwise, 0, and because they return a tangible binary value, you can use these logical statements in your mathematics if you'd like.
It takes somewhere around 2,867,092,000,000,000 degrees before there's an error of even 1 degree between N and DEG(RAD(N)), so I don't think wrapping is really necessary.
OPTION STRICT VAR DEGREES=0,ERROR REPEAT ERROR=ABS(DEG(RAD(DEGREES)) - DEGREES) INC DEGREES,1000000000 UNTIL ERROR>=1 ?DEGREES,ERRORPut another way, if something could do a full 360-degree rotation in one second, and rotated in one direction forever, it would take about 252374 years before its rotation was off by one degree.