#include <stdio.h>
#include <math.h>
#define M_PI 3.141592653589793
void gsi_gauss_kruger(double lat, double lon, double lat0, double lon0, double k0, double *x, double *y) {
/* GRS80 楕円体定数 */
const double a = 6378137.0;
const double f = 1.0 / 298.257222101;
const double e2 = 2.0 * f - f * f;
const double e4 = e2 * e2;
const double e6 = e4 * e2;
/* 子午線弧長 M(φ)(国土地理院の近似式) */
const double A0 = 1.0 - e2/4.0 - 3.0*e4/64.0 - 5.0*e6/256.0;
const double A2 = 3.0/8.0 * (e2 + e4/4.0 + 15.0*e6/128.0);
const double A4 = 15.0/256.0 * (e4 + 3.0*e6/4.0);
const double A6 = 35.0 * e6 / 3072.0;
/* 度 → ラジアン */
double phi = lat * M_PI / 180;
double phi0 = lat0 * M_PI / 180;
double M
= a
* (A0
*phi
- A2
*sin(2*phi
) + A4
*sin(4*phi
) - A6
*sin(6*phi
)); double M0
= a
* (A0
*phi0
- A2
*sin(2*phi0
) + A4
*sin(4*phi0
) - A6
*sin(6*phi0
)); double N
= a
/ sqrt(1.0 - e2
* sinp
* sinp
); /* 卯酉線曲率半径 */ double eta2 = e2 * cosp * cosp / (1.0 - e2); /* η^2 = e'^2 cos^2 φ */
/* 近似式の級数展開 */
double A = cosp * (lon - lon0) * M_PI / 180; /* 経度差 */
double A2p = A*A;
double A3p = A2p*A;
double A4p = A2p*A2p;
double A5p = A4p*A;
double A6p = A4p*A2p;
/* 北向き x */
*x = k0 * (M - M0 + N * tanp * ( A2p/2.0 + (5.0 - tanp*tanp + 9.0*eta2 + 4.0*eta2*eta2) * A4p / 24.0 + (61.0 - 58.0*tanp*tanp + tanp*tanp*tanp*tanp + 270.0*eta2 - 330.0*tanp*tanp*eta2) * A6p / 720.0 ));
/* 東向き y */
*y = k0 * N * ( A + (1.0 - tanp*tanp + eta2) * A3p / 6.0 + (5.0 - 18.0*tanp*tanp + tanp*tanp*tanp*tanp + 14.0*eta2 - 58.0*tanp*tanp*eta2) * A5p / 120.0 );
}
int main(void) {
double x, y;
gsi_gauss_kruger(36.103774791666666, 140.08785504166664, 36.0, 139.8333333333333, 0.9999, &x, &y);
printf("x=%lf, y=%lf\n", x
, y
); return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+CgojZGVmaW5lIE1fUEkgMy4xNDE1OTI2NTM1ODk3OTMKCnZvaWQgZ3NpX2dhdXNzX2tydWdlcihkb3VibGUgbGF0LCBkb3VibGUgbG9uLCBkb3VibGUgbGF0MCwgZG91YmxlIGxvbjAsIGRvdWJsZSBrMCwgZG91YmxlICp4LCBkb3VibGUgKnkpIHsgCgkvKiBHUlM4MCDmpZXlhobkvZPlrprmlbAgKi8KCWNvbnN0IGRvdWJsZSBhID0gNjM3ODEzNy4wOwoJY29uc3QgZG91YmxlIGYgPSAxLjAgLyAyOTguMjU3MjIyMTAxOwoJY29uc3QgZG91YmxlIGUyID0gMi4wICogZiAtIGYgKiBmOwoJY29uc3QgZG91YmxlIGU0ID0gZTIgKiBlMjsKCWNvbnN0IGRvdWJsZSBlNiA9IGU0ICogZTI7CgkKCS8qIOWtkOWNiOe3muW8p+mVtyBNKM+GKe+8iOWbveWcn+WcsOeQhumZouOBrui/keS8vOW8j++8iSAqLwoJY29uc3QgZG91YmxlIEEwID0gMS4wIC0gZTIvNC4wIC0gMy4wKmU0LzY0LjAgLSA1LjAqZTYvMjU2LjA7Cgljb25zdCBkb3VibGUgQTIgPSAzLjAvOC4wICogKGUyICsgZTQvNC4wICsgMTUuMCplNi8xMjguMCk7Cgljb25zdCBkb3VibGUgQTQgPSAxNS4wLzI1Ni4wICogKGU0ICsgMy4wKmU2LzQuMCk7Cgljb25zdCBkb3VibGUgQTYgPSAzNS4wICogZTYgLyAzMDcyLjA7CgkKCS8qIOW6piDihpIg44Op44K444Ki44OzICovIAoJZG91YmxlIHBoaSA9IGxhdCAqIE1fUEkgLyAxODA7Cglkb3VibGUgcGhpMCA9IGxhdDAgKiBNX1BJIC8gMTgwOwoJCglkb3VibGUgc2lucCA9IHNpbihwaGkpOwoJZG91YmxlIGNvc3AgPSBjb3MocGhpKTsKCWRvdWJsZSB0YW5wID0gdGFuKHBoaSk7CgkKCWRvdWJsZSBNID0gYSAqIChBMCpwaGkgLSBBMipzaW4oMipwaGkpICsgQTQqc2luKDQqcGhpKSAtIEE2KnNpbig2KnBoaSkpOwoJZG91YmxlIE0wID0gYSAqIChBMCpwaGkwIC0gQTIqc2luKDIqcGhpMCkgKyBBNCpzaW4oNCpwaGkwKSAtIEE2KnNpbig2KnBoaTApKTsKCWRvdWJsZSBOID0gYSAvIHNxcnQoMS4wIC0gZTIgKiBzaW5wICogc2lucCk7CS8qIOWNr+mFiee3muabsueOh+WNiuW+hCAqLwoJZG91YmxlIGV0YTIgPSBlMiAqIGNvc3AgKiBjb3NwIC8gKDEuMCAtIGUyKTsJLyogzrdeMiA9IGUnXjIgY29zXjIgz4YgKi8KCQoJLyog6L+R5Ly85byP44Gu57Sa5pWw5bGV6ZaLICovIAoJZG91YmxlIEEgPSBjb3NwICogKGxvbiAtIGxvbjApICogTV9QSSAvIDE4MDsJLyog57WM5bqm5beuICovCglkb3VibGUgQTJwID0gQSpBOwoJZG91YmxlIEEzcCA9IEEycCpBOwoJZG91YmxlIEE0cCA9IEEycCpBMnA7Cglkb3VibGUgQTVwID0gQTRwKkE7Cglkb3VibGUgQTZwID0gQTRwKkEycDsKCQoJLyog5YyX5ZCR44GNIHggKi8gCgkqeCA9IGswICogKE0gLSBNMCArIE4gKiB0YW5wICogKCBBMnAvMi4wICsgKDUuMCAtIHRhbnAqdGFucCArIDkuMCpldGEyICsgNC4wKmV0YTIqZXRhMikgKiBBNHAgLyAyNC4wICsgKDYxLjAgLSA1OC4wKnRhbnAqdGFucCArIHRhbnAqdGFucCp0YW5wKnRhbnAgKyAyNzAuMCpldGEyIC0gMzMwLjAqdGFucCp0YW5wKmV0YTIpICogQTZwIC8gNzIwLjAgKSk7CgkKCS8qIOadseWQkeOBjSB5ICovCgkqeSA9IGswICogTiAqICggQSArICgxLjAgLSB0YW5wKnRhbnAgKyBldGEyKSAqIEEzcCAvIDYuMCArICg1LjAgLSAxOC4wKnRhbnAqdGFucCArIHRhbnAqdGFucCp0YW5wKnRhbnAgKyAxNC4wKmV0YTIgLSA1OC4wKnRhbnAqdGFucCpldGEyKSAqIEE1cCAvIDEyMC4wICk7Cn0KCmludCBtYWluKHZvaWQpIHsKCWRvdWJsZSB4LCB5OwoJCglnc2lfZ2F1c3Nfa3J1Z2VyKDM2LjEwMzc3NDc5MTY2NjY2NiwgMTQwLjA4Nzg1NTA0MTY2NjY0LCAzNi4wLCAxMzkuODMzMzMzMzMzMzMzMywgMC45OTk5LCAmeCwgJnkpOwoJCglwcmludGYoIng9JWxmLCB5PSVsZlxuIiwgeCwgeSk7CglyZXR1cm4gMDsKfQo=