T O P I C R E V I E W |
AbbDresden |
Posted - 08/09/2004 : 03:32:06 AM Hello,
I have data in cartesian. Thanks.
sincerely, Honghai |
6 L A T E S T R E P L I E S (Newest First) |
Mike Buess |
Posted - 08/13/2004 : 2:29:37 PM quote: Also, Mike made a slight error also. Strangely, ORIGIN wants the theta column before the r column, not after, as you might expect.
Thanks for correcting the script. I don't use Origin's polar plot so the column order in my original script was tailored for my own purposes. Before Origin 7.0 I used a LabTalk script similar to the one I posted but without the quadrant correction. Since Origin 7.0 I convert (cartesian to polar and back) with the following simple OC function. (Angles in radians.)void ONMR_Convert(string wksName, bool bPolar) { waitCursor junk; Dataset dRe(wksName,0); Dataset dIm(wksName,1); if( bPolar ) { vector<complex> vv(dRe,dIm); vv.GetAmplitude(dRe); vv.GetPhase(dIm); } else { dRe *= cos(dIm); dIm = dRe * tan(dIm); } }
Mike Buess Origin WebRing Member |
verrallr@a |
Posted - 08/13/2004 : 12:27:04 PM Since I initially had problems with my use of combining logical operators, I couldn't try out my solution. Now that I can, using Mike's message above, I find that there was a mistake.
My 360-atan(y/x) should have been 360+atan(y/x). And both forms of the part using 180, should have been 180+atan(y/x).
Also, Mike made a slight error also. Strangely, ORIGIN wants the theta column before the r column, not after, as you might expect.
So now the equation should be:
cc1=selc1; cc2=selc2; // get indices of selected columns tempx=%(%H,cc1); // make copy of 1st col tempy=%(%H,cc2); // make copy of 2nd col tempy*=tempy; tempx*=tempx; tempx+=tempy; // this is r^2 tempy=atan(%(%H,cc2)/%(%H,cc1)); // this is theta. now must apply the correction discussed above and put in 2nd col %(%H,cc1)=%(%H,cc1)>=0?(%(%H,cc2)>=0?tempy:360+tempy):180+tempy; %(%H,cc2)=sqrt(tempx); // put r in 2nd col del tempx; del tempy; // delete temporary data sets |
verrallr@a |
Posted - 08/12/2004 : 2:48:26 PM Hello Mike,
Obviously, I do not do much programming, especially in ORIGIN, but I like looking at some of the questions and answers. And, for a long time, it seemed no one was going to reply to AbbDresden.
I didn't think to apply && to combine operators. And, your statement to apply logical operators to mathematical operators, reproduced below, was simple and good.
q=x>=0?(y>=0?atan(x/y):360-atan(x/y)):(y>=0?180-atan(x/y):180+atan(x/y));
I was wanting to create a simple line that one could use in "Set Column Values" if one wanted. (You can only use If ELSE in "SET Column Values" if you can do it in one statement, can't you". That is, you can't put multiple lines there.) And you have an additional plus in that you can use "AutoUpdate" if you want.
I agree that it was not a "bug" in ORIGIN. I, at least, might call it a minor "design flaw" - that you can't simply combine logical operators and other logical operators or math functions, in the way I tried do. My line that didn't work, would have been clear and easily checkable, if it had worked. And, I think various other programs would have allowed it.
RLEWIS's C solution is good, and one can put that into "Set Column Values" if one wanted. This probably also avoids the problem that is inherent in my solution, that if x=0, atan(y/x) may not be defined. The angle q would, of course, be 90 degrees, but atan may not find it. Your knew solution is also good, and completes the transformation in one fell swoop. I guess you could even create a button for that in the worksheet file, if you wanted. AbbDresden should be happy now.
R. Verrall |
Mike Buess |
Posted - 08/12/2004 : 10:28:27 AM quote: But there seems to be a bug in ORIGIN. When you calculate a logical operator, it works as long as there is no other function (logical or otherwise) attached. But, when you put another function there, it doesn't give any results.
Logical expressions can certainly be combined logically... (x>=0 && y>=0) produces the same result that (x>=0)*(y>=0) would if the latter were allowed.
Logical and arithmetic expressions can also be combined logically. (I'm not sure that the inability to combine them arithmetically can be called a bug.) Since only one of the four terms in your expression contributes to the final value it makes as much sense to write it as if-then statements as it does to write it as a single arithmetic equation. If you must have a single equation you can use the ternary operator like this...
q=x>=0?(y>=0?atan(x/y):360-atan(x/y)):(y>=0?180-atan(x/y):180+atan(x/y));
...For the sake of the original poster, here is a complete Labtalk solution (in case he doesn't have access to Origin C). First, copy and paste the code below to the script window. Next, select the two columns containing the Cartesian data (x and y). Finally, select all lines of code in the script window and press Enter. The x and y data will be converted to r and theta.
cc1=selc1; cc2=selc2; // get indices of selected columns tempx=%(%H,cc1); // make copy of 1st col tempy=%(%H,cc2); // make copy of 2nd col tempy*=tempy; tempx*=tempx; tempx+=tempy; // this is r^2 tempy=atan(%(%H,cc2)/%(%H,cc1)); // this is theta. now must apply the correction discussed above and put in 2nd col %(%H,cc2)=%(%H,cc1)>=0?(%(%H,cc2)>=0?tempy:360-tempy):(%(%H,cc2)>=0?180-tempy:180+tempy); // if you don't want to make that correction use %(%H,cc2)=tempy; instead of the line above %(%H,cc1)=sqrt(tempx); // put r in 1st col del tempx; del tempy; // delete temporary data sets
This assumes your angular unit is degree (Tools->Options->Numeric Format->Angular Unit).
Mike Buess Origin WebRing Member
Edited by - Mike Buess on 08/12/2004 11:15:38 AM
Edited by - Mike Buess on 08/12/2004 12:50:55 PM
Edited by - Mike Buess on 08/12/2004 1:15:59 PM |
rlewis |
Posted - 08/11/2004 : 4:44:32 PM If you are using Origin 7.0 or higher ... the OriginC coded functions below should do the trick ...
bool Cartesian_to_Polar(double &x1, double &y1, int AngUnit) { /* Converts the cartesian coordinates x1, y1 into polar coordinates R and Theta On exit the scalar component R is returned in x1 (x1 >= 0) and the angular component theta is returned in y1 (0<= y1 <=2*pi) AngUnit determines the units of the angular component as coded by Origin's System.Math.AngularUnits */ if(x1==NANUM || y1==NANUM) return (false); if(AngUnit<0 || AngUnit>2) return (false); if(x1==0 && y1==0) return (true); double PiFact; switch (AngUnit) { case 1: PiFact=180; break case 2: PiFact=200; break; default: PiFact=pi; break; } if (x1==0) { if(y1>0) { x1=y1; y1=PiFact/2; } else { x1=abs(y1); y1=PiFact*3/2; } return (true); } if (y1==0) { if(x1<0) { x1=abs(x1); y1=PiFact; } return (true); } double R=sqrt((x1*x1)+(y1*y1)); double theta=acos(abs(y1)/R); if(AngUnit==1) theta*=(180/pi); if(AngUnit==2) theta*=(200/pi); if(y1>0 && x1<0) { x1=R; y1=theta+(PiFact/2); return (true); } if(y1<0 && x1<0) { x1=R; y1=theta+PiFact; return (true); } if(y1<0 && x1>0) { x1=R; y1=theta+(PiFact*3/2); return (true); } x1=R; y1=theta; return (true); }
bool Polar_to_Cartesian(double &rVal, double &theta, int AngUnit) { /* Converts the polar coordinates rVal, theta into cartesian coordinates x and y On exit the x-coordinate is returned in rVal and the y-coordinate theta is returned in theta AngUnit determines the units of the angular component as coded by Origin's System.Math.AngularUnits */ if(rVal==NANUM || theta==NANUM) return (false); if(AngUnit<0 || AngUnit>2) return (false); double Psi; switch (AngUnit) { case 1: Psi=theta*pi/180; break; case 2: Psi=theta*pi/200; break; default: Psi=theta; break; } Psi=rmod(Psi,(2*pi)); if(Psi<0) Psi=(2*pi)+Psi; double x=rVal*cos(Psi); double y=rVal*sin(Psi); rVal=x; theta=y; return (true); }
|
verrallr@a |
Posted - 08/11/2004 : 2:05:13 PM Hello AbbDresden,
Using A and B for x and y, add two more columns, C and D, for r and theta (will use q for theta).
For the r coordinate, use the D column:
r = SQRT(Col(A)^2 + Col(B)^2))
And, q is given by:
q = atan(Col(B)/Col(A)
This would be it, except for the fact that we only need two quadrants. All values from minus infinity to plus infinity need only the angles -90 to +90 degrees. So, we need to use the x and y to put the angle q into the right quadrant.
We do this by using logical operators to see whether x and y are positive or negative. Here's how (I will use q and x and y, for convenience. You must use Col(C), Col(A) and Col(B)). Also put multiplications symbols between the parentheses.
q = (x>=0) (y>=0) atan(y/x) + (x<0) (y>=0) (180-atan(y/x) + (x<0) (y<0) (180+atan(y/x) + (x>=0) (y<0) (360-atan(y/x)
Now, this should work. Use polar coordinates for C and D. But there seems to be a bug in ORIGIN. When you calculate a logical operator, it works as long as there is no other function (logical or otherwise) attached. But, when you put another function there, it doesn't give any results. You can still do it, but you must create another two functions to evaluate the logical operators by themselves. Then, and only then, you can multiply them together using the extra columns, Col(E) and Col(F), and add atan function and put it into col(C).
Perhaps, ORIGIN wishes to look at why we can't use logical operators with other functions. |
|
|