外部変形は データのやり取りをテキストファイルで行うので プログラム言語は 自由に選ぶことができます。図形は機能的かつシンプルなため、数多くのユーザーに受け入れられています。
gccで文字種を取得する(cn)
:gccで文字種を取得する(cn)
@echo off
if not exist %~dpn0.exe (
for /f "delims=:" %%n in ('findstr /n "^#!" %0') do (
more +%%n %0 > %~dpn0.c
gcc -Os %~dpn0.c -o %~dpn0.exe -s
)
)
%~dpn0
goto:eof
REM #jww
REM #e
#!この次の行からプログラムを書いてください
#include "jw.h"
int main(void)
{
FILE *f;
int n;
char S_[256], *F[20];
char SS[256];
char cn[20], pcn[20];
int flg = 0;
if ( (f = fopen("jwc_temp.txt", "r")) != NULL) {
while (fgets(S_, 256, f) != NULL) {
strcpy(SS, chomp(S_));
split(SS, F);
strcpy(S_, SS);
if (strncmp(S_, "cn", 2) == 0) {
n = strlen(S_);
substr(S_, 2, n-1, pcn);
if (flg == 0) { strcpy(cn, pcn); flg = 1; }
}
}
} else {
exit(MISSING_JWC_TEMP_TXT);
}
fclose(f);
f = fopen("jwc_temp.txt", "w");
if (strlen(cn) > 2) {
fprintf(f, "h#cn%s\n", cn);
} else {
fprintf(f, "h#cn=%s\n", cn);
}
fclose(f);
return 0;
}
○jw.h
/* jw.h : JW_CAD 外部変形 例題用ヘッダファイル
動作確認
MinGW + gcc / g++ 4.5.0
Borland C++ 5.5.1 for Win32
Visual C++ 2005 Express Edition
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI 3.1415926535897932384626433832795
#define MISSING_JWC_TEMP_TXT printf("jwc_temp.txt が 見当たりません\n")
#define NO_OPERATION printf("処理できませんでした\n")
double arc_l(double r, double p1, double p2, double w);
double __ee__[151], __hh__[151];
int split(char *S_, char **F)
{ /* char S_[256], *F[20]; */
int i, NF;
for (i = 0; i < 20; i++) {
if ( (F[i] = strtok(S_, " ")) == NULL) { NF = i; break; }
S_ = NULL;
}
return NF;
}
char *substr(char *src, int off, int len, char *buf)
{
return strncpy(buf, src+off, len);
}
char *chomp(char *str)
{
int l = strlen(str);
if ( l > 0 && str[l-1] == '\n' )
{
str[l-1] = '\0';
}
return str;
}
int __sgn(double x)
{
if (x == 0) { return 0;
} else if (x > 0) { return 1;
} else { return -1;
}
}
double __abs(double x)
{
return (x > 0) ? x : -x;
}
int __int(double a)
{
int b;
if (a < 0) { b = ceil(a); } else { b = floor(a); }
return b;
}
int angle_eql(double d1, double d2, double eps)
{
double dd = __abs(d1 - d2);
while (dd > PI - eps) dd -= PI;
return __abs(dd) < eps ? 0 : 1;
}
int length_eql(double l1, double l2, double eps)
{
return __abs(l1 - l2) < eps ? 0 : 1;
}
double deg(double x)
{
return x * 180.0 / PI;
}
double rad(double x)
{
return x * PI / 180.0;
}
double hypot(double x, double y)
{
return sqrt(x * x + y * y);
}
int htoi(char *x)
{
int y;
if (strcmp(x, "a") == 0) { y = 10;
} else if (strcmp(x, "b") == 0) { y = 11;
} else if (strcmp(x, "c") == 0) { y = 12;
} else if (strcmp(x, "d") == 0) { y = 13;
} else if (strcmp(x, "e") == 0) { y = 14;
} else if (strcmp(x, "f") == 0) { y = 15;
} else {
y = atoi(x);
}
return y;
}
void ln_reset(double *ln, double *p)
{
double x1, y1, x2, y2, xs, ys;
x1 = ln[0];
y1 = ln[1];
x2 = ln[2];
y2 = ln[3];
/* 指示線の角度を -PI/2 < d <= +PI/2 とする */
if (x1 > x2) {
xs = x1; x1 = x2; x2 = xs;
ys = y1; y1 = y2; y2 = ys;
}
if (x1 == x2 && y1 > y2) {
ys = y1; y1 = y2; y2 = ys;
}
p[0] = x1;
p[1] = y1;
p[2] = x2;
p[3] = y2;
}
void ci_reset(double *ci, double *p)
{
double r, p1, p2, w, d;
r = ci[2];
p1 = ci[3] ? ci[3] : 0;
p2 = ci[4] ? ci[4] : 360;
w = ci[5] ? ci[5] : 1;
d = ci[6] ? ci[6] : 0;
if (w > 1) {
w = 1.0 / w;
r /= w;
p1 -= 90.0;
p2 -= 90.0;
d += 90.0;
}
if (p1 == p2) { p1 = 0; p2 = 0; }
if (__abs(p1 - p2) < 1e-12) { p2 += 360; }
/* if (__abs(p1 - p2) < 1e-12) { p1 = 0; p2 = 360; d = 0; } */
p[0] = ci[0];
p[1] = ci[1];
p[2] = r;
p[3] = p1;
p[4] = p2;
p[5] = w;
p[6] = d;
}
void polar(double r, double d, double w, double *p) {
p[0] = r * cos(d);
p[1] = r * sin(d) * w;
}
void rot(double *x, double d, double *p) {
double x1, y1, co, si;
x1 = x[0];
y1 = x[1];
co = cos(d);
si = sin(d);
p[0] = x1 * co - y1 * si;
p[1] = x1 * si + y1 * co;
}
void offset(double w, double h, int pt, int opt, double *p) {
p[0] = w * ( (9 - pt) % 3 - (9 - opt) % 3) / 2;
p[1] = h * (__int( (9 - pt) / 3) - __int( (9 - opt) / 3)) / 2;
}
void moveto(double *pt, double x, double y, double *p)
{
p[0] = pt[0] + x;
p[1] = pt[1] + y;
}
void polarto(double *pt, double r, double d, double *p)
{
p[0] = pt[0] + r * cos(d);
p[1] = pt[1] + r * sin(d);
}
double ptdist(double *p1, double *p2)
{
return sqrt(pow(p2[0] - p1[0], 2.0) + pow(p2[1] - p1[1], 2.0));
}
double ptslope(double *p1, double *p2)
{ /* 2点の角度を返す */
return atan2(p2[1] - p1[1], p2[0] - p1[0]);
}
void ptspan(double *p1, double *p2, double d, double *p)
{ /* d : 角度rad */
double co, si, x1, y1, x2, y2;
si = sin(d);
co = cos(d);
x1 = p1[0];
y1 = p1[1];
x2 = p2[0];
y2 = p2[1];
p[0] = (x2 - x1) * co + (y2 - y1) * si;
p[1] = - (x2 - x1) * si + (y2 - y1) * co;
}
void ptcenter(double *p1, double *p2, double x, double *p)
{
polarto(p1, ptdist(p1, p2) * x, ptslope(p1, p2), p);
}
int ptsgn(double *x, double *y, double d)
{ /* 2点を結ぶ線の傾斜の判別 / : 1, \ : -1 */
double p[2];
ptspan(x, y, 0, p);
rot(p, rad(-d), p);
return __sgn(p[0] * p[1]);
}
void lnpoint(double *ln, int pm, double *p)
{
if (pm == -1) {
p[0] = ln[0];
p[1] = ln[1];
} else if (pm == 1) {
p[0] = ln[2];
p[1] = ln[3];
} else {
p[0] = (ln[0] + ln[2]) / 2;
p[1] = (ln[1] + ln[3]) / 2;
}
}
double lnlength(double *ln)
{ /* 線長を返す */
return sqrt(pow(ln[2] - ln[0], 2.0) + pow(ln[3] - ln[1], 2.0));
}
double lnslope(double *ln)
{ /* 線の角度を返す */
return atan2(ln[3] - ln[1], ln[2] - ln[0]);
}
void lnspan(double *ln, double d, double *p)
{ /* 線の dx, dy を返す */
/* d : 角度rad */
double co, si, x1, y1, x2, y2;
si = sin(d);
co = cos(d);
x1 = ln[0];
y1 = ln[1];
x2 = ln[2];
y2 = ln[3];
p[0] = (x2 - x1) * co + (y2 - y1) * si;
p[1] = - (x2 - x1) * si + (y2 - y1) * co;
}
void lncenter(double *s, double x, double *p)
{
lnpoint(s, -1, p);
polarto(p, lnlength(s) * x, lnslope(s), p);
}
void lnmove(double *ln, double b, double pmy, double *l)
{ /* 線 ln を直交距離 b だけ pmy の方向に平行移動する */
double x1, y1, x2, y2, d, co, si;
x1 = ln[0];
y1 = ln[1];
x2 = ln[2];
y2 = ln[3];
d = lnslope(ln);
co = b * cos(d) * pmy;
si = b * sin(d) * pmy;
l[0] = x1 - si;
l[1] = y1 + co;
l[2] = x2 - si;
l[3] = y2 + co;
}
double ln_hpdist(double *ln, double *hp)
{ /* 線と点の最短距離を返す */
double x[4];
x[0] = hp[0];
x[1] = hp[1];
x[2] = ln[0];
x[3] = ln[1];
return lnlength(x) * sin(lnslope(ln) - lnslope(x));
}
void ln_hpsnap(double *ln, double *hp, double *p)
{ /* 線の吸着点を返す */
double t, d;
t = ln_hpdist(ln, hp);
d = lnslope(ln);
p[0] = hp[0] + t * sin(d);
p[1] = hp[1] - t * cos(d);
}
int ln_hpends(double *ln, double *hp)
{
double p1[2], p2[2], l1, l2;
lnpoint(ln,-1, p1);
lnpoint(ln, 1, p2);
l1 = ptdist(hp, p1);
l2 = ptdist(hp, p2);
return l1 < l2 ? -1 : 1;
}
int ln_hpsens(double *ln, double *hp)
{
double p1[2], p2[2], p4[2], ll, l1, l2;
lnpoint(ln,-1, p1);
lnpoint(ln, 1, p2);
ln_hpsnap(ln, hp, p4);
ll = lnlength(ln);
l1 = ptdist(p1, p4);
l2 = ptdist(p2, p4);
return (l1 + l2 == ll && (l1 == ll || l2 == ll)) ? 0 : ( (l1 <= ll && l2 <= ll) ? -1 : 1); /* -1 : 内, 1 : 外 */
}
int ln_hpmens(double *s, double *p)
{
return __sgn(ln_hpdist(s, p));
}
void cipoint(double *ci, int pm, double *p)
{
double x, y, r, p1, p2, w, d;
double co, si, xr, yr, q;
x = ci[0];
y = ci[1];
r = ci[2];
p1 = ci[3] ? ci[3] : 0;
p2 = ci[4] ? ci[4] : 360;
w = ci[5] ? ci[5] : 1;
d = ci[6] ? ci[6] : 0;
d *= PI / 180;
co = cos(d) * r;
si = sin(d) * r;
if (pm == -1) { q = p1 * PI / 180; } else { q = p2 * PI / 180; }
xr = cos(q);
yr = sin(q) * w;
p[0] = x + xr * co - yr * si;
p[1] = y + xr * si + yr * co;
p[2] = atan2(yr / w, xr * w) + d;
}
int cicenter(double *c, double x, double *p) {
double nl, r, p1, p2, w, d;
double pc[2], cc, ep, pp, d1, d2, dd, __pl, __ml, l, eps, pr[2], ps[2], el;
int wflg;
pc[0] = c[0];
pc[1] = c[1];
r = c[2];
p1 = c[3] ? c[3] : 0;
p2 = c[4] ? c[4] : 360;
w = c[5] ? c[5] : 1;
d = c[6] ? c[6] : 0;
wflg = 0;
if (w > 1.0) {
w = 1.0 / w;
r /= w;
p1 -= 90.0;
p2 -= 90.0;
d += 90.0;
wflg = 1;
}
nl = arc_l(r, p1, p2, w) * x;
if (x == 0) {
cipoint(c, -1, p);
return 0;
}
cc = 10;
ep = r / pow(10, cc); /* 誤差 */
if (p1 == p2) p2 += 360;
/* if (__abs(p1 - p2) < 1e-12) { p1 = 0; p2 = 360; } */
pp = p2 - p1;
if (pp <= 0) pp += 360;
d1 = p1; d2 = p1; dd = pp * x;
__pl = nl + ep;
__ml = nl - ep;
if (w != 1) {
l = arc_l(1, 0, dd, w);
dd *= (rad(dd) / l);
} else {
l = nl;
}
eps = dd;
d2 += eps;
/* はさみうち法(ここから)*/
if (w != 1) {
l = arc_l(r, d1, d2, w);
while (l < __ml || __pl < l) {
eps /= 2.0;
if (eps < ep / r) break;
if (l < nl) { d2 += eps; } else { d2 -= eps; }
l = arc_l(r, d1, d2, w);
}
}
/* はさみうち法(ここまで)*/
if (l != 0) {
polar(r, rad(d2), w, pr);
rot(pr, rad(d), ps);
p[0] = ps[0] + pc[0];
p[1] = ps[1] + pc[1];
}
/* 誤差のチェック */
el = __abs(nl - l);
if (wflg == 1) d2 += 90;
p[2] = d2;
if (ep * 1e3 < el) { return -1; }
return 1;
}
void cimove(double *c, double b, double a, int pm, double *p)
{
double x, y, r, p1, p2, w, d, q[2];
x = c[0];
y = c[1];
r = c[2];
p1 = c[3] ? c[3] : 0;
p2 = c[4] ? c[4] : 360;
w = c[5] ? c[5] : 1;
d = c[6] ? c[6] : 0;
if (pm == 0) {
w = (r * w + b) / (r + b);
r = r + b;
} else if (pm == -1 || pm == 1) {
if (pm == -1) a = -a;
polar(r, a, 1, q);
x += q[0]; y += q[1];
} else if (pm == 2) {
d = d + deg(a);
}
p[0] = x;
p[1] = y;
p[2] = r;
p[3] = p1;
p[4] = p2;
p[5] = w;
p[6] = d;
}
void line_x_poi(double *ln1, double *ln2, double *p)
{ /* 線と線の交点 */
double x1, y1, x2, y2, dx1, dy1, m1;
double x3, y3, x4, y4, dx2, dy2, m2;
double aa, b1, b2;
x1 = ln1[0];
y1 = ln1[1];
x2 = ln1[2];
y2 = ln1[3];
dx1 = x2 - x1;
dy1 = y2 - y1;
m1 = (dx1 == 0) ? 1e20 : dy1 / dx1;
x3 = ln2[0];
y3 = ln2[1];
x4 = ln2[2];
y4 = ln2[3];
dx2 = x4 - x3;
dy2 = y4 - y3;
m2 = (dx2 == 0) ? 1e20 : dy2 / dx2;
aa = m1 - m2;
if (__abs(aa) < 1e-10) aa = 0;
if (aa != 0) {
b1 = y1 - m1 * x1;
b2 = y3 - m2 * x3;
p[0] = (b2 - b1) / aa;
p[1] = (m1 * b2 - m2 * b1) / aa;
} else {
int flg = 0;
double p1[2], p2[2], p3[2], p4[2];
p1[0] = x1;
p1[1] = y1;
p2[0] = x2;
p2[1] = y2;
p3[0] = x3;
p3[1] = y3;
p4[0] = x4;
p4[1] = y4;
if (ptdist(p2, p3) < 1e-12) { p[0] = p2[0]; p[1] = p2[1]; flg = 1; }
if (ptdist(p1, p4) < 1e-12) { p[0] = p1[0]; p[1] = p1[1]; flg = 1; }
if (ptdist(p2, p4) < 1e-12) { p[0] = p2[0]; p[1] = p2[1]; flg = 1; }
if (ptdist(p1, p3) < 1e-12) { p[0] = p1[0]; p[1] = p1[1]; flg = 1; }
if (flg == 0) exit(NO_OPERATION);
}
}
double apa(int o, double p) {
return (90.0 * (2 * __int( (o + 1) / 2.0) - 1) - p) * pow(-1.0, o - 1.0);
}
double __fx__(double x, double k) {
return sqrt(1.0 - pow(k * sin(x), 2.0));
}
void gauss(int n) {
int i, j, e1;
double t, x0, pkm1, pk, t1, pkp1;
double den, d1, dpn, d2pn, d3pn, d4pn;
double u, v, h, pp, dp, x, f, w;
int m = __int( (n + n % 2) / 2);
e1 = n * (n + 1);
for (i = 1; i <= m; i++) {
t = (4.0 * i - 1.0) * PI / (4.0 * n + 2.0);
x0 = (1.0 - (1.0 - 1.0 / n) / (8.0 * n * n)) * cos(t);
pkm1= 1.0;
pk = x0;
for (j = 2; j <= n; j++) {
t1 = x0 * pk;
pkp1 = t1 - pkm1 - (t1 - pkm1) / j + t1;
pkm1 = pk;
pk = pkp1;
}
den = 1.0 - x0 * x0;
d1 = n * (pkm1 - x0 * pk);
dpn = d1 / den;
d2pn = (2.0 * x0 * dpn - e1 * pk) / den;
d3pn = (4.0 * x0 * d2pn + (2.0 - e1) * dpn) / den;
d4pn = (6.0 * x0 * d3pn + (6.0 - e1) * d2pn) / den;
u = pk / dpn;
v = d2pn / dpn;
h = -1.0 * u * (1.0 + 0.5 * u * (v + u * (v * v - d3pn / (3.0 * dpn))));
pp = pk + h * (dpn + 0.5 * h * (d2pn + h / 3.0 * (d3pn + 0.25 * h * d4pn)));
dp = dpn + h * (d2pn + 0.5 * h * (d3pn + h * d4pn / 3.0));
h -= pp / dp;
x = x0 + h;
f = d1 - h * e1 * (pk + 0.5 * h * (dpn + h / 3.0 * (d2pn + 0.25 * h * (d3pn + 0.2 * h * d4pn))));
w = 2.0 * (1.0 - x * x) / (f * f);
__ee__[i] = x;
__hh__[i] = w;
}
}
double elliptic_f(double p, double k, int n) {
double l = 0.0;
int i;
int m = __int( (n + n % 2) / 2);
if (k == 0 || n < 1) {
return p;
}
for (i = 1; i <= __int(n / 2.0); i++) {
l += __hh__[i] / __fx__(__ee__[i] * p, k);
}
if (m == __int(n / 2.0) + 1) { /* 奇数個の場合 */
l += __hh__[m] / __fx__(__ee__[m] * p, k) / 2.0;
}
return l * p;
}
double elliptic_e(double p, double k, int n) {
double l = 0.0;
int i;
int m = __int( (n + n % 2) / 2);
if (k == 0 || n < 1) {
return p;
}
for (i = 1; i <= __int(n / 2.0); i++) {
l += __hh__[i] * __fx__(__ee__[i] * p, k);
}
if (m == __int(n / 2.0) + 1) { /* 奇数個の場合 */
l += __hh__[m] * __fx__(__ee__[m] * p, k) / 2.0;
}
return l * p;
}
double arc_l(double r, double p1, double p2, double w) {
double p, lp;
int n, n1, n2, n3;
double k, ek;
p = p2 - p1;
while (p <= 0 ) p += 360;
while (p > 360) p -= 360;
if (w == 1) {
lp = p * PI / 180.0;
} else {
if (w > 1) {
w = 1.0 / w;
r /= w;
p1 = p1 - 90.0;
p2 = p2 - 90.0;
}
k = sqrt(1.0 - w * w);
n = __int(12 * (1.5 / sqrt(w))); /* ガウス積分点の数 */
if (n > 300) n = 300;
if (__abs(__ee__[0]) > 1 || __abs(__ee__[0]) < 0.5) gauss(n);
/* gauss(n); */
ek = elliptic_e(PI / 2.0, k, n);
lp = __int(__abs(p2 - p1) / 360) * 4.0 * ek;
while (p1 < 0 ) p1 += 360;
while (p1 >= 360) p1 -= 360;
while (p2 < 0 ) p2 += 360;
while (p2 >= 360) p2 -= 360;
if (angle_eql(p1, p2, 1e-12) == 0) {
return 4 * ek * r;
} else {
n1 = 1 + __int(p1 / 90.0);
if (n1 > 4) n1 = 4;
lp += ek * ( (n1 + 1) % 2) + elliptic_e(apa(n1, p1) * PI / 180, k, n) * pow(-1.0, n1 - 1.0);
n2 = 1 + __int(p2 / 90.0);
if (n2 > 4) n2 = 4;
if (n1 == n2) n1 += 4;
n3 = 5 + 2 * __int( (n2 - 1) / 2.0);
lp += ek * ( (n3 - n1) % 4) + elliptic_e(apa(n2, p2) * PI / 180, k, n) * pow(-1.0, (double) n2);
if (lp < 0.0) lp += 4.0 * ek;
if (lp > 4.0 * ek) lp -= 4.0 * ek;
}
}
return lp * r;
}
void arrow(FILE *f, double *pt1, double d, double size, double xang, double xan2)
{
double l, a, c, pt2[2], pt3[2], pt4[2];
l = size;
a = xang * PI / 180 / 2.0;
polarto(pt1, l, d - a, pt2);
polarto(pt1, l, d + a, pt4);
if (xan2 == 180) {
fprintf(f, "sl %.15g %.15g %.15g %.15g %.15g %.15g\n", pt1[0], pt1[1], pt2[0], pt2[1], pt4[0], pt4[1]);
} else {
c = cos(a) - sin(a) * tan( (90.0 - xan2 / 2.0) * PI / 180);
polarto(pt1, l * c, d, pt3);
fprintf(f, "sl %.15g %.15g %.15g %.15g %.15g %.15g %.15g %.15g\n", pt1[0], pt1[1], pt2[0], pt2[1], pt3[0], pt3[1], pt4[0], pt4[1]);
}
}