Error compiling fortran77 code with gfortran - fortran
I have a fortran77 code (public domain) when compile with gfortran on Cygwin generated the following error. How can I fix this problem?
gfortran -o GR3DSTR GR3DSTR.f77
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/../../../../x86_64-pc-cygwin/bin/ld:GR3DSTR. f77: file format not recognized; treating as linker script
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/../../../../x86_64-pc-cygwin/bin/ld:GR3DSTR. f77:2: syntax error
collect2: error: ld returned 1 exit status
when I tread it as a free format, more errors are produced.
*************************************************************************
* PROGRAM GR3DSTR TO DEDUCE THE 3-D STRUCTURE OF *
* SEDIMENTARY BASIN FROM ITS GRAVITY ANOMALIES WITH A *
* QUADRATIC DENSITY FUNCTION. *
* *
* INPUT *
* ------ *
* GOBS : OBSERVED GRAVITY ANOMALIES (MGALS) *
* NX : NUMBER OF OBSERVATIONS IN X-DIRECTION *
* NY : NUMBER OF OBSERVATIONS IN Y-DIRECTION *
* DX : STATION INTERVAL IN X-DIRECTION (KM) *
* DY : STATION INTERVAL IN Y-DIRECTION (KM) *
* A0,A1 : COEFFICIENTS OF QUADRATIC DENSITY FUNCTION *
* &A2 : FUNCTION (GM/CC) *
* ITER1 : TOTAL NUMBER OF ITERATIONS REQUIRED *
* ITR1 : NUMBER OF ITERATIONS REQUIRED IN FIRST STAGE *
* ITR2 : NUMBER OF ITERATIONS REQUIRED IN SECOND STAGE *
* LT1 : LIMITING VALUE OF THE DOMAIN IN WHICH EXACT *
* EQUATION IS USED FOR ANOMALY CALCULATION *
* *
* OUTPUT *
* ------ *
* GCAL : CALCULATED GRAVITY ANOMALIES (MGALS) *
* Z2 : DEPTH TO THE BOTTOM (BASEMENT) (KM) *
* *
* SUPPORTING SUBROUTINES AND SUBPROGRAMS: *
* --------------------------------------- *
* : INIT, STRUC, BOTT, RESUL, ANOM1, & ANOM2 *
*************************************************************************
DIMENSION X(50),Y(50),GOBS(50,50),GCAL(50,50),Z(50,50),LT1(3)
PI=3.14159265
CONST=PI*40.0/3.0
READ(*,801)NX,NY,DX,DY,ITER1,A0,A1,A2
READ(*,802)ITR1,ITR2
READ(*,803)(LT1(I),I=1,3)
WRITE(*,901)NX,NY,DX,DY,ITER1,A0,A1,A2
WRITE(*,902)ITR1,ITR2
WRITE(*,903)(LT1(1),I=1,3)
DO 100 I=1,NX
100 X(I)=FLOAT(I-1)*DX
DO 110 J=1,NY
110 Y(J)=FLOAT(J-1)*DY
DO 120 J=1,NY
READ(*,804)(GOBS(I,J),I=1,NX)
WRITE(*,904)(GOBS(I,J),I=1,NX)
110 CONTINUE
CALL INIT(NX,NY,A0,X,Y,GOBS,CONST,Z)
DO 130 ITER=1,ITER1
CALL STRUC(NX,NY,DX,DY,A0,A1,A2,X,Y,Z,ITER,ITR1,ITR2,LT1,GCAL)
CALL RESUL(NX,NY,ITER,X,Y,Z,GOBS,GCAL)
CALL BOTT(NX,NY,CONST,A0,A1,A2,GOBS,GCAL,Z)
130 CONTINUE
801 FORMAT(2I10,2F10.4,I10,3F10.4)
802 FORMAT(2I10)
803 FORMAT(3I10)
804 FORMAT(11F7.3)
901 FORMAT(2I10,2F10.5,I10,3F10.5)
902 FORMAT(2110)
903 FORMAT(3I10)
904 FORMAT(1X,20F6.1)
STOP
END
*************************************************************************
* SUBROUTINE INIT: CALCULATES THE INITIAL ESTIMATES OF
* THE STRUCTURE.
*
* INPUT
* -----
* NX : NUMBER OF OBSERVATIONS IN X-DIRECTION
* NY : NUMBER OF OBSERVATIONS IN Y-DIRECTION
* A0 : CONSTANT DENSITY CONTRAST (GM/CC)
* X : DISTANCE TO THE ANOMALY POINT IN X-DIRECTION
* Y : DISTANCE TO THE ANOMALY POINT IN Y-DIRECTION
* GOBS : OBSERVED GRAVITY ANOMALIES (MGALS)
* CONST : PI*40.0/3.0
*
* OUTPUT
* ------
* Z : DEPTH TO THE BOTTOM (KM)
*************************************************************************
SUBROUTINE INIT(NX,NY,A0,X,Y,GOBS,CONST,Z)
DIMENSION X(50),(Y50),GOBS(50,50),Z(50,50)
DO 100 J=1,NY
DO 100 I=1,NX
Z(I,J)=GOBS(I,J)/(CONST*A0)
IF (Z(I,J).LE.0.0)THEN
Z(I,J)=0.001
ENDIF
100 CONTINUE
WRITE(*,905)
D0 110 J=1,NY
WRITE(*,906)(Z(I,J),I=1,NX)
110 CONTINUE
905 FORMAT(//5X, 'INITIAL ESTIMATES OF THE STRUCTURE'/)
906 FORMAT(20F6.2)
RETURN
END
*************************************************************************
* SUBROUTINE STRUC: CALCULATES THE GRAVITY ANOMALIES OF A
* SEDIMENTARY BASIN BY THE COMBINED USE
* OF EXACT AND APPROXIMATE EQUATIONS OF
* PRISMATIC MODEL
*
* INPUT
* -----
* NX : NUMBER OF OBSERVATIONS IN X-DIRECTION
* NY : NUMBER OF OBSERVATIONS IN Y-DIRECTION
* DX : STATION INTERVAL IN X-DIRECTION (KM) *
* DY : STATION INTERVAL IN Y-DIRECTION (KM) *
* A0,A1 : COEFFICIENTS OF QUADRATIC DENSITY FUNCTION *
* &A2 : FUNCTION (GM/CC) *
* X : DISTANCE TO THE ANOMALY POINT IN X-DIRECTION
* Y : DISTANCE TO THE ANOMALY POINT IN Y-DIRECTION
* Z : DEPTH TO THE BOTTOM (KM)
* ITER : ITERATION NUMBER *
* ITR1 : NUMBER OF ITERATIONS REQUIRED IN FIRST STAGE *
* ITR2 : NUMBER OF ITERATIONS REQUIRED IN SECOND STAGE *
* LT1 : LIMITING VALUE OF THE DOMAIN IN WHICH EXACT *
* EQUATION IS USED FOR ANOMALY CALCULATION
* T : HALF THICKNESS OF THE PRISM (KM)
* W : HALF WIDTH OF THE PRISM (KM)
*
* OUTPUT
* ------
* GCAL : CALCULATED GRAVITY ANOMALIES (MGALS)
*************************************************************************
SUBROUTINE STRUC(NX,NY,DX,DY,A0,A1,A2,X,Y,Z,ITER,ITR1,ITR2,LT1,GCAL)
DIMENSION X(50),Y(50),Z(50,50),GCAL(50,50),LT1(3)
T=DX/2.0
W=DY/2.0
Z1=0.001
DO 100 I=1,NX
DO 100 J=1,NY
100 GCAL(I,J)=0.0
IF (ITER.LT.ITR1)THEN
LT=LT1(1)
GOTO 110
ELSE
IF (ITER.LE.ITR2)THEN
LT=LT1(2)
GOTO 110
ELSE
LT=LT1(3)
ENDIF
ENDIF
110 DO 140 I=1,NX
DO 140 M=1,NX
XX1=X(I)-X(M)
DO 140 J=1,NY
DO 140 N=1,NY
YY1=Y(J)-Y(N)
Z2=Z(M,N)
IF(ABS(I-M).LE.LT)THEN
IF(ABS(J-N).LE.LT)THEN
GCAL1=ANOM1(A0,A1,A2,XX1,YY1,T,W,Z1,Z2)
GOTO 130
ELSE
GOTO 120
ENDIF
ELSE
GOTO 120
ENDIF
120 GCAL1=ANOM2(A0,A1,A2,DX,DY,XX1,XX2,Z1,Z2)
130 CONTINUE
140 GCAL(I,J)=GCAL(I,J)+GCAL1
RETURN
END
*************************************************************************
* FUNCTION SUBPROGRAM ANOM1: CALCULATES THE ANOMALY OF
* PRISMATIC MODEL WITH EXACT
* EQUATION
* INPUT
* -----
* A0,A1 : COEFFICIENTS OF QUADRATIC DENSITY *
* &A2 : FUNCTION (GM/CC) *
* XX1 : DISTANCE TO THE POINT OF CALCULATION
* IN X-DIRECTION WITH REFERENCE TO THE
* EPICENTRE OF THE PRISM UNDER CONSIDERATION
* YY1 : DISTANCE TO THE POINT OF CALCULATION
* IN Y-DIRECTION WITH REFERENCE TO THE
* EPICENTRE OF THE PRISM UNDER CONSIDERATION
* T : HALF THICKNESS OF THE PRISM (KM)
* W : HALF WIDTH OF THE PRISM (KM)
* Z1 : DEPTH TO THE TOP OF THE PRISM (KM)
* Z2 : DEPTH TO THE BOTTOM OF THE PRISM (KM)
* GAMA : GRAVITATIONAL CONSTANT
*************************************************************************
FUNCTION ANOM1(A0,A1,A2,XX1,YY1,T,W,Z1,Z2)
GAMA=20.0/3.0
X1=XX1+T
X2=XX1-T
Y1=YY1+W
Y2=YY1-W
IF(X1.EQ.0.0)THEN
X1=0.0001
ENDIF
IF(X2.EQ.0.0)THEN
X2=0.0001
ENDIF
IF(Y1.EQ.0.0)THEN
Y1=0.0001
ENDIF
IF(Y2.EQ.0.0)THEN
Y2=0.0001
ENDIF
R1=SQRT(X2*X2+Y2*Y2+Z1*Z1)
R2=SQRT(X2*X2+Y2*Y2+Z2*Z2)
R3=SQRT(X2*X2+Y1*Y1+Z1*Z1)
R4=SQRT(X2*X2+Y1*Y1+Z2*Z2)
R5=SQRT(X1*X1+Y2*Y2+Z1*Z1)
R6=SQRT(X1*X1+Y2*Y2+Z2*Z2)
R7=SQRT(X1*X1+Y1*Y1+Z1*Z1)
R8=SQRT(X1*X1+Y1*Y1+Z2*Z2)
F11=X2*Y2/(Z2*R2)
F12=X2*Y1/(Z2*R4)
F13=X1*Y2/(Z2*R6)
F14=X1*Y1/(Z2*R8)
B1=ATAN(F11)-ATAN(F12)-ATAN(F13)+ATAN(F14)
F21=X2*Y2/(Z1*R1)
F22=X2*Y1/(Z1*R3)
F23=X1*Y2/(Z1*R5)
F24=X1*Y1/(Z1*R7)
B2=ATAN(F21)-ATAN(F22)-ATAN(F23)+ATAN(F24)
F31=(R2-Y2)/(R2+Y2)
F32=(R1-Y2)/(R1+Y2)
F33=(R4-Y1)/(R4+Y1)
F34=(R3-Y1)/(R3+Y1)
B3=ALOG(F31*F34/(F32*F33))
F41=(R5-Y2)/(R5+Y2)
F42=(R6-Y2)/(R6+Y2)
F43=(R7-Y1)/(R7+Y1)
F44=(R8-Y1)/(R8+Y1)
B4=ALOG(F41*F44/(F42*F43))
F51=(R2-X2)/(R2+X2)
F52=(R1-X2)/(R1+X2)
F53=(R6-X1)/(R6+X1)
F54=(R5-X1)/(R5+X1)
B5=ALOG(F51*F54/(F52*F53))
F61=(R3-X2)/(R3+X2)
F62=(R4-X2)/(R4+X2)
F63=(R7-X1)/(R7+X1)
F64=(R8-X1)/(R8+X1)
B6=ALOG(F61*F64/(F62*F63))
F71=Y2*Z2/(R2*X2)
F72=Y2*Z1/(R1*X2)
F73=Y1*Z2/(R4*X2)
F74=Y1*Z1/(R3*X2)
H71=(F71-F72)/(1.0+F71*F72)
H72=(F73-F74)/(1.0+F73*F74)
B7=ATAN((H71-H72)/(1.0+H71*H72))
F81=Y2*Z2/(R6*X1)
F82=Y2*Z1/(R5*X1)
F83=Y1*Z2/(R8*X1)
F84=Y1*Z1/(R7*X1)
H81=(F81-F82)/(1.0+F81*F82)
H82=(F83-F84)/(1.0+F83*F84)
B8=ATAN((H81-H82)/(1.0+H81*H82))
F91=X2*Z2/(R2*Y2)
F92=X2*Z1/(R1*Y2)
F93=X1*Z2/(R6*Y2)
F94=X1*Z1/(R5*Y2)
H91=(F91-F92)/(1.0+F91*F92)
H92=(F93-F94)/(1.0+F93*F94)
B9=ATAN((H91-H92)/(1.0+H91*H92))
F101=X2*Z2/(R4*Y1)
F102=X2*Z1/(R3*Y1)
F103=X1*Z2/(R8*Y1)
F104=X1*Z1/(R7*Y1)
H101=(F101-F102)/(1.0+F101*F102)
H102=(F103-F104)/(1.0+F103*F104)
B10=ATAN((H101-H102)/(1.0+H101*H102))
B11=ALOG((R2+Z2)/(R1+Z1))
B12=ALOG((R3+Z1)/(R4+Z2))
B13=ALOG((R5+Z1)/(R6+Z2))
B14=ALOG((R8+Z2)/(R7+Z1))
G1=GAMA*A0*(Z2*B1-Z1*B2+X2/2.0*B3+X1/2.0*B4+Y2/2.0*B5+Y1/2.0*B6)
G2=GAMA/2.0*A1*(Z2*Z2*B1-Z1*Z1*B2-X2*X2*B7+X1*X1*B8-Y2*Y2*B9+Y1*Y1*B10+2.0*(X2*Y2*B11+X2*Y1*B12+X1*Y2*B13+X1*Y1*B14))
G3=GAMA/3.0*A2*(Z2*Z2*Z2*B1-Z1*Z1*Z1*B2-(X2*X2*X2)/2.0*B3-(X1*X1*X1)/2.0*B4-(Y2*Y2*Y2)/2.0*B5-((Y1*Y1*Y1)/2.0*B6
+2.0*(X2*Y2*(R2-R1)+X2*Y1*(R3-R4)+X1*Y2(R5-R6)+X1*Y1(R8-R7)))
ANOM1=G1+G2+G3
RETURN
END
*************************************************************************
* FUNCTION SUBPROGRAM ANOM2: CALCULATES THE ANOMALY OF
* PRISMATIC MODEL WITH APPROXIMATE EQUATION
*
* INPUT
* -----
* A0,A1 : COEFFICIENTS OF QUADRATIC DENSITY *
* &A2 : FUNCTION (GM/CC)
* DX : STATION INTERVAL IN X-DIRECTION (KM) *
* DY : STATION INTERVAL IN Y-DIRECTION (KM) *
* XX1 : DISTANCE TO THE POINT OF CALCULATION
* IN X-DIRECTION WITH REFERENCE TO THE
* EPICENTRE OF THE PRISM UNDER CONSIDERATION
* YY1 : DISTANCE TO THE POINT OF CALCULATION
* IN Y-DIRECTION WITH REFERENCE TO THE
* EPICENTRE OF THE PRISM UNDER CONSIDERATION
* Z2 : DEPTH TO THE BOTTOM OF THE PRISM (KM)
* GAMA : GRAVITATIONAL CONSTANT
*************************************************************************
FUNCTION ANOM2(A0,A1,A2,DX,DY,XX1,YY1,Z1,Z2)
GAMA=20.0/3.0
A=DX*DY
X1=XX1
Y1=YY1
IF(X1.EQ.0.0)THEN
X1=0.0001
ENDIF
IF(Y1.EQ.0.0)THEN
Y1=0.0001
ENDIF
R1=SQRT(X1*X1+Y1*Y1+Z1*Z1)
R2=SQRT(X1*X1+Y1*Y1+Z2*Z2)
IF(R1.EQ.0.0)THEN
R1=0.0001
ENDIF
IF(R2.EQ.0.0)THEN
R2=0.0001
ENDIF
PI=A0*(1.0/R1-1.0/R2)
P2=A1*(Z1/R1-Z2/R2+ALOG((R2+Z2)/(R1+Z1)))
P3=A2*(2.0*(R2-R1)+Z1*Z1/R1-Z2*Z2/R2)
ANOM2=GAMA*A*(P1+P2+P3)
RETURN
END
*************************************************************************
* SUBROUTINE BOTT: CALCULATES THE STRUCTURE OF A SEDIMENTARY BASIN
* USING THE BOTT'S METHOD.
*
* INPUT
* -----
* NX : NUMBER OF OBSERVATIONS IN X-DIRECTION
* NY : NUMBER OF OBSERVATIONS IN Y-DIRECTION
* A0,A1 : COEFFICIENTS OF QUADRATIC DENSITY *
* &A2 : FUNCTION (GM/CC)
* GOBS : OBSERVED GRAVITY ANOMALIES (MGALS)
* GCAL : CALCULATED GRAVITY ANOMALIES (MGALS)
* CONST : PI*40.0/3.0
*
* OUTPUT
* ------
* Z : DEPTHS TO THE BASEMENT (KM)
*************************************************************************
SUBROUTINE BOTT(NX,NY,CONST,A0,A1,A2,GOBS,GCAL,Z)
DIMENSION GOBS(50,50),GCAL(50,50),Z(50,50),DZ(50,50)
DO 100 I=1,NX
DO 100 J=1,NY
R2=A0+A1*Z(I,J)+A2*Z(I,J)*Z(I,J)
CONST1=CONST*R2
100 DZ(I,J)=(GOBS(I,J)-GCAL(I,J))/CONST1
DO 110 I=1,NX
DO 110 J=1,NY
Z(I,J)=Z(I,J)+DZ(I,J)
IF (Z(I,J).LE.0.0) THEN
Z(I,J)=0.001
END
110 CONTINUE
RETURN
END
*************************************************************************
* SUBROUTINE RESUL: GIVES THE RESULTS SUCH AS DEPTHS TO THE BASEMENT
* AND RESIDUAL ANOMALIES
*
* INPUT
* -----
* NX : NUMBER OF OBSERVATIONS IN X-DIRECTION
* NY : NUMBER OF OBSERVATIONS IN Y-DIRECTION
* ITER : ITERATION NUMBER
* X : DISTANCE TO THE ANOMALY POINT IN X-DIRECTION
* Y : DISTANCE TO THE ANOMALY POINT IN Y-DIRECTION
* Z : DEPTHS TO THE BASEMENT (KM)
* GOBS : OBSERVED GRAVITY ANOMALIES (MGALS)
*
*
* OUTPUT
* ------
* GCAL : CALCULATED GRAVITY ANOMALIES (MGALS)
*************************************************************************
SUBROUTINE RESUL(NX,NY,ITER,X,Y,Z,GOBS,GCAL)
DIMENSION X(50),Y(50),GOBS(50,50),GCAL(50,50),RESD(50,50),Z(50,50)
DO 100 I=1,NX
DO 100 J=1,NY
100 RESD(I,J)=GOBS(I,J)-GCAL(I.J)
WRITE(*,907) ITER
WRITE(*,908)
DO 110 J=1,NY
WRITE(*,909)(Z(I,J),I=1,NX)
110 CONTINUE
WRITE(*,910)
DO 120 J=1,NY
WRITE(*,911)(RESD(I,J),I=1,NX)
120 CONTINUE
907 FORMAT(//5X,'ITERATION NO.=',I3)
908 FORMAT(/10X,'DEPTHS TO THE BASEMENT')
909 FORMAT(/20F6.2)
910 FORMAT(//10X,'RESIDUAL ANOMALY'/)
911 FORMAT(20F6.2)
RETURN
END
*************************************************************************
* A CONCISE FUNCTION
* SUBPROGRAM ANOM1: CALCULATES THE ANOMALY OF PRISMATIC
* MODEL WITH EXACT EQUATION.
*
* INPUT
* -----
* A0,A1 : COEFFICIENTS OF QUADRATIC DENSITY
* &A2 : FUNCTION (GM/CC)
* XX1 : DISTANCE TO THE POINT OF CALCULATION
* IN X-DIRECTION WITH REFERENCE TO THE
* EPICENTRE OF THE PRISM UNDER CONSIDERATION
* YY1 : DISTANCE TO THE POINT OF CALCULATION
* IN Y-DIRECTION WITH REFERENCE TO THE
* EPICENTRE OF THE PRISM UNDER CONSIDERATION
* T : HALF THICKNESS OF THE PRISM (KM)
* W : HALF WIDTH OF THE PRISM (KM)
* Z1 : DEPTH TO THE TOP OF THE PRISM (KM)
* Z2 : DEPTH TO THE BOTTOM OF THE PRISM (KM)
* GAMA : GRAVITATIONAL CONSTANT
*************************************************************************
FUNCTION ANOM1(A0,A1,A2,XX1,YY1,T,W,Z1,Z2)
DIMENSION X(2),Y(2),Z(2),R(2,2,2)
GAMA=20.0/3.0
X(1)=XX1+T
X(2)=XX1-T
Y(1)=YY1+W
Y(2)=YY1-W
Z(1)=Z1
Z(2)=Z2
IF(X(1).EQ.0.0)THEN
X(1)=0.0001
ENDIF
IF(X(2).EQ.0.0)THEN
X(2)=0.001
ENDIF
IF(Y(1).EQ.0.0)THEN
Y(1)=0.0001
ENDIF
IF(Y(2).EQ.0.0)THEN
Y(2)=0.0001
ENDIF
G1=0.0
G2=0.0
G3=0.0
DO 100 I=1,2
DO 100 J=1,2
DO 100 K=1,2
J1=I+J+K
J2=J1/2
IF(2*J2.EQ.J1)THEN
J3=1
ELSE
J3=-1
ENDIF
R(I,J,K)=SQRT(X(I)*X(I)+Y(J)*Y(J)+Z(K)*Z(K))
F1=ATAN(X(I)*Y(J)/(Z(K)*R(I,J,K)))
F2=ALOG((R(I,J,K)-Y(J))/(R(I,J,K)+Y(J)))
F3=ALOG((R(I,J,K)-X(I))/(R(I,J,K)+X(I)))
F4=ATAN(Y(J)*Z(K)/(X(I)*R(I,J,K)))
F5=ATAN(X(I)*Z(K)/(Y(J)*R(I,J,K)))
F6=X(I)*Y(J)*ALOG(2.0*R(I,J,K)+2.0*Z(K))
F7=2.0/3.0*X(I)*Y(J)*R(I,J,K)
G1=G1+J3*A0*(Z(K)*F1+X(I)/2.0*F2+Y(J)/2.0*F3)
G2=G2+J3*A1*(Z(K)*Z(K)/2.0*F1-X(I)*X(I)/2.0*F4-Y(J)*Y(J)/2.0*F5+F6)
G3=G3+J3*A2*(Z(K)*Z(K)*Z(K)/3.0*F1-X(I)*X(I)*X(I)/6.0*F2-Y(J)*Y(J)*Y(J)/6.0*F3+F7)
100 CONTINUE
ANOM1=GAMA*(G1+G2+G3)
RETURN
END
You need to rename the file to "GR3DSTR.f" because gfortran doesn't recognize .f77 file extensions. However, I get a large number of compiler errors due to invalid language constructs when I attempt to compile the code you posted (the least of which being the omittion of PROGRAM and END PROGRAM. You'll need to correct those before it will compile.
Looks very much like a line termination problem. Basically there is an unrecognized character starting from line 2. Question is why only line 2 and nothing else?
Check your line terminations. Since you are running cygwin, have a look in vi - set list. Maybe you need to change CR or LF to CR LF.
How to change to the correct line terminations:
linux utility called unix2dos.
Use Word. Cut your entire program, paste it in Word. Don't worry about line wraps etc. Cut it from Word and paste back. Word will fill in all the line terminations correctly. This is an obscure use of Word but it does work.
This could answer why only line 2 - it is taking your entire program as 1 line and the last line is blank.
Related
Average value from 2d space
I'm currently working on a pice of software that interpolates data from existing measurements and makes estimates from this. The data is arranged in a 2D environment where we've got a wind speed on one axis and a wind angle on the other and each point represents a target speed. For an example I've got three points: p1: wind speed 6 knots, wind angle 90 degrees => target speed 5 p2: wind speed 6 knots, wind angle 70 degrees => target speed 6 p3: wind speed 8 knots, wind angle 70 degrees => target speed 7 Now I want to interpolate the point of wind speed 6 knots and wind angle 80 degrees. I would like an algorithm that uses all of these points and gives me an average of these three points. Ages ago I made a 3D renderer and I think I used a technique there to color a polygon and I think this can be useful in this scenario. All the examples that I've found on the internet rely on OpenGL and such and that won't work for me as I want this solution to be pure c/c++ for an embedded environment. Since i run in an embedded environment I've got limited resources mainly in terms of program size. Do any of you guys have any pointers to help me get past this problem? Thanks!
After diving into my old calculus i found a mathematical answer to this problem. Given that I've got three points in the space I can form a plane: P: (Px, Py, Pz) Q: (Qx, Qy, Qz) R: (Rx, Ry, Rz) These points and the math described in here http://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfPlanes.aspx allowed me to move forward. Vector(PQ) = (PQx, PQy, PQz) Vector(PR) = (PRx, PRy, PRz) Now I apply the cross product to these two vectors and this gives the normal vector of the plane (Cross product math described here: http://tutorial.math.lamar.edu/Classes/CalcII/CrossProduct.aspx#Vectors_CrossProd_Ex2) Vector(PQ) x Vector(PR) = Vector(PQy * PRz - PQz * PRy, PQz * PRx - PQx * PRz, PQx * PRy - PQy * PRx) So, this is what I've got as a plane equation, without respect to that it has to pass trough one of the points: x(PQy * PRz - PQz * PRy) + y(PQz * PRx - PQx * PRz) + z(PQx * PRy - PQy * PRx) = 0 To get the full equation of my plane that passes trough all of the points, I have to apply one point, as described in example 1 in the first link. x(PQy * PRz - PQz * PRy) + y(PQz * PRx - PQx * PRz) + z(PQx * PRy - PQy * PRx) = Px(PQy * PRz - PQz * PRy) + Py(PQz * PRx - PQx * PRz) + Pz(PQx * PRy - PQy * PRx) To apply my example to this formula I get the following equation: P: (90, 6, 5) Q: (70, 6, 6) R: (70, 8, 7) Vector(PQ) = (20, 0, -1) Vector(PR) = (20, -2, -2) Cross product of these gives me this formula: -2x + 20y - 40z = 0 If I now apply the point P to this I can get the full equatio of my plane: -2x + 20y - 40z = -2 * 90 + 20 * 6 - 40 * 5 -2x + 20y - 40z = -260 z = (-2x + 20y + 260) / 40 As I seek the z value where x = 6 and y = 80 I put these values into the equation. x = 80 y = 6 z = (-2 * 80 + 20 * 6 + 260) / 40 z = 5.5 5.5 is the expected answer for this example as it exactly in the middle of P and Q. The final implementation of this algorithm: float TargetSpeed::PlaneInterpolation(Point3D p, Point3D q, Point3D r, int x, int y) { Point3D pq = Point3D(p.X - q.X, p.Y - q.Y, p.Z - q.Z); Point3D pr = Point3D(p.X - r.X, p.Y - r.Y, p.Z - r.Z); Point3D n = Point3D(pq.Y * pr.Z - pq.Z * pr.Y, pq.Z * pr.X - pq.X * pr.Z, pq.X * pr.Y - pq.Y * pr.X); float d = n.X * p.X + n.Y * p.Y + n.Z * p.Z; float z = (d - n.X * (float)x - n.Y * (float)y) / n.Z; return z; }
Is the data on a regular grid? If so, I would just use something like linear interpolation. If not, then look at something like qhull.
Converting a sine or triangle wave into a sawtooth wave
I'm trying to generate different wave forms in c++. So far I managed the sine, triangle and square wave, but I fail to get an idea how to generate a sawtooth wave. This is how my sine wave looks like: uint8_t sample = (amp * envelope * sin(2 * M_PI * phase)) + 128; And this is the triangle wave: double sinevalue = sin(2 * M_PI * phase); uint8_t sample = (envelope * 2 * amp) / M_PI * asin(sinevalue) + 128; How can I convert it into a sawtooth wave?
You can't do a sample-by-sample conversion of a sine wave to a sawtooth wave. That's because the sine wave is symmetric in time: if you reverse time, then except for some possible phase shift you get the same wave. For a swatooth wave a time reversal has to be combined with a sign reversal, the only time-reversed version will look qualitatively different. You need some additional information, like e.g. the slope at the current position. Or you need access to the raw parameter value, in which case the formula would be very easy: uint8_t sample = (amp * envelope * (phase - floor(phase));
Fill Ellipses with Gradiant Color on Matlab
I have a code on matlab that allows me to plot a series of ellipses, what I am trying to do it to fill each of them with a gradiant color based on 'arcsin(b/a)' The number will go from 0° (straight line) to 90° (pure circle). So each ellipse will have a uniform color, but the colors of each ellipse will be different if that makes sense. That's my code clearvars -except data colheaders data(:,9)=data(:,9)*pi/180; % Convers Column 9 (angle of rotation) in rad data(:,6)=1196-data(:,6); % Reset the Y coordinate axis to bottom left theta = 0 : 0.01 : 2*pi; for i=1:size(data,1) x = data(i,7)/2 * cos(theta) * cos(data(i,9)) - data(i,8)/2 * sin(theta) * sin(data(i,9)) + data(i,5); y = data(i,8)/2 * sin(theta) * cos(data(i,9)) + data(i,7)/2 * cos(theta) * sin(data(i,9)) + data(i,6); plot(x, y, 'LineWidth', 1); hold on % Columns (5,6) are the centre (x,y) of the ellipse % Columns (7,8) are the major and minor axes (a,b) % Column 9 is the rotation angle with the x axis text(data(i,5),data(i,6),[num2str(i)]) % Assigns number to each ellipse end axis equal; xlim([0 1592]); ylim([0 1196]); grid on; Let me know if I need explain in a different way. Thank you guys Dorian
what does this C++ code to create a triangle mean?
What does this c++ code mean? i am trying to figure out what this code means but being new to programming iv not had much luck. This is code to create an equilateral triangle. static const float COS_60 = 0.5f; static const float COS_30 = 0.5f * sqrt(3.f); const float side = radius * 2.f * COS_30; const float bottomHeight = point.getY() - COS_60 * radius; this->vertices.push_back(Vertex(point.getX(), point.getY() + radius)); this->vertices.push_back(Vertex(point.getX() + COS_60 * side, bottomHeight)); this->vertices.push_back(Vertex(point.getX() - COS_60 * side, bottomHeight));
A equilateral triangle has three sides of equal length. The angle (on the inside) of the corners is 60 degrees, hence needing COS_60. It just so happens that COS 60 = 0.5, so the programmer didn't write code to calculate it, but just used this "known value". The length of the side is radius * 2.f * COS_30 (that is the distance from the center to the furthest corner times cosine of 30 degrees). COS_30 happens to be sqrt(3)/2 or 0.5f * sqrt(3.f). Again, you can calculate this, using for example a calculator instead of writing it out as 0.5 * sqrt(3). Or if you want to use C++ functions, you could use sin(30.0f * 2.f * pi / 180.0f) [this is because math on computers is, nearly always, done in radians, rather than degrees]. The distance from the bottom to the center is COS_60 * radius (half the radius). If we manually apply this math, given a X, Y center of 400, 400 and a radius of 100, we get: side = 100 * 2 * COS_30 => 200*0.866 = 173; bottomheight = 400 - COS_60 * radius = 400 - 50 = 350 and then the following coordinate: 400, (400 + radius) => 400, 500 400 + COS_60 * side, 350 => 400 + 173 * 0.5, 350 => 486, 350 400 - COS_60 * side, 350 => 400 - 173 * 0.5, 350 => 314, 350
OpenGL - Creating a circle, change radius?
I must be the worst person on the planet when it comes to math because i can't figure out how to change this circle radius: from math import * posx, posy = 0,0 sides = 32 glBegin(GL_POLYGON) for i in range(100): cosine=cos(i*2*pi/sides)+posx sine=sin(i*2*pi/sides)+posy glVertex2f(cosine,sine) I'm not entirely sure how or why this becomes a circle because the *2 confuses me a bit. Note that this is done in Pyglet under Python2.6 calling OpenGL libraries. Followed Example 4-1: http://fly.cc.fer.hr/~unreal/theredbook/chapter04.html Clarification: This works, i'm interested in why and how to modify the radius.
This should do the trick :) from math import * posx, posy = 0,0 sides = 32 radius = 1 glBegin(GL_POLYGON) for i in range(100): cosine= radius * cos(i*2*pi/sides) + posx sine = radius * sin(i*2*pi/sides) + posy glVertex2f(cosine,sine) But I would pick another names for variables. cosine and sine is not exactly what these variables are. And as far as I see, you son't need a loop from 1 to 100 (or from 0 to 99, I'm not too good at Python), you just need a loop from 1 to sides. Explanation: When you calculate x = cos (angle) y = sin(angle) you get a point on a circle with radius = 1, and centre in the point (0; 0) (because sin^2(angle) + cos^2(angle) = 1). If you want to change a radius to R, you simply multiply cos and sin by R. x = R * cos (angle) y = R * sin(angle) If you want to transfer the circle to another location (for example, you want the circle to have it's centre at (X_centre, Y_centre), you add X_centre and Y_xentre to x and y accordingly: x = R * cos (angle) + X_centre y = R * sin(angle) + Y_centre When you need to loop through N points (in your case N = sides) on your circle, you should change the angle on each iteration. All those angles should be equal and their sum should be 2 * pi. So each angle should be equal to 2 * pi/ N. And to get i-th angle you multiply this value by i: i * 2 * pi / N.
math : P=pr^2=p*r*r= p*r*2 programming i*2*pi/sides together : i = p i*2, *2=r^2 this should help you