870 |
|
return(1); |
871 |
|
if (miga[i] != NULL) |
872 |
|
continue; |
873 |
– |
while (i > 0 && miga[i-1] > mig_grid[px][py]) { |
874 |
– |
miga[i] = miga[i-1]; |
875 |
– |
--i; /* order vertices by pointer */ |
876 |
– |
} |
873 |
|
miga[i] = mig_grid[px][py]; |
874 |
|
return(1); |
875 |
|
} |
998 |
|
return(NULL); /* pro forma return */ |
999 |
|
} |
1000 |
|
|
1001 |
+ |
/* Insert vertex in ordered list */ |
1002 |
+ |
static void |
1003 |
+ |
insert_vert(RBFNODE **vlist, RBFNODE *v) |
1004 |
+ |
{ |
1005 |
+ |
int i, j; |
1006 |
+ |
|
1007 |
+ |
for (i = 0; vlist[i] != NULL; i++) { |
1008 |
+ |
if (v == vlist[i]) |
1009 |
+ |
return; |
1010 |
+ |
if (v < vlist[i]) |
1011 |
+ |
break; |
1012 |
+ |
} |
1013 |
+ |
for (j = i; vlist[j] != NULL; j++) |
1014 |
+ |
; |
1015 |
+ |
while (j > i) { |
1016 |
+ |
vlist[j] = vlist[j-1]; |
1017 |
+ |
--j; |
1018 |
+ |
} |
1019 |
+ |
vlist[i] = v; |
1020 |
+ |
} |
1021 |
+ |
|
1022 |
+ |
/* Sort triangle edges in standard order */ |
1023 |
+ |
static void |
1024 |
+ |
order_triangle(MIGRATION *miga[3]) |
1025 |
+ |
{ |
1026 |
+ |
RBFNODE *vert[4]; |
1027 |
+ |
MIGRATION *ord[3]; |
1028 |
+ |
int i; |
1029 |
+ |
/* order vertices, first */ |
1030 |
+ |
memset(vert, 0, sizeof(vert)); |
1031 |
+ |
for (i = 0; i < 3; i++) { |
1032 |
+ |
insert_vert(vert, miga[i]->rbfv[0]); |
1033 |
+ |
insert_vert(vert, miga[i]->rbfv[1]); |
1034 |
+ |
} |
1035 |
+ |
/* identify edge 0 */ |
1036 |
+ |
for (i = 0; i < 3; i++) |
1037 |
+ |
if (miga[i]->rbfv[0] == vert[0] && |
1038 |
+ |
miga[i]->rbfv[1] == vert[1]) { |
1039 |
+ |
ord[0] = miga[i]; |
1040 |
+ |
break; |
1041 |
+ |
} |
1042 |
+ |
/* identify edge 1 */ |
1043 |
+ |
for (i = 0; i < 3; i++) |
1044 |
+ |
if (miga[i]->rbfv[0] == vert[1] && |
1045 |
+ |
miga[i]->rbfv[1] == vert[2]) { |
1046 |
+ |
ord[1] = miga[i]; |
1047 |
+ |
break; |
1048 |
+ |
} |
1049 |
+ |
/* identify edge 2 */ |
1050 |
+ |
for (i = 0; i < 3; i++) |
1051 |
+ |
if (miga[i]->rbfv[0] == vert[0] && |
1052 |
+ |
miga[i]->rbfv[1] == vert[2]) { |
1053 |
+ |
ord[2] = miga[i]; |
1054 |
+ |
break; |
1055 |
+ |
} |
1056 |
+ |
miga[0] = ord[0]; miga[1] = ord[1]; miga[2] = ord[2]; |
1057 |
+ |
} |
1058 |
+ |
|
1059 |
|
/* Partially advect between recorded incident angles and allocate new RBF */ |
1060 |
|
static RBFNODE * |
1061 |
|
advect_rbf(const FVECT invec) |
1062 |
|
{ |
1063 |
|
MIGRATION *miga[3]; |
1064 |
|
RBFNODE *rbf; |
1065 |
< |
int n, i, j; |
1065 |
> |
float mbfact, mcfact; |
1066 |
> |
int n, i, j, k; |
1067 |
> |
FVECT v0, v1, v2; |
1068 |
|
double s, t; |
1069 |
|
|
1070 |
|
if (!get_interp(miga, invec)) /* can't interpolate? */ |
1071 |
|
return(NULL); |
1072 |
|
if (miga[1] == NULL) /* along edge? */ |
1073 |
|
return(e_advect_rbf(miga[0], invec)); |
1074 |
+ |
/* put in standard order */ |
1075 |
+ |
order_triangle(miga); |
1076 |
|
/* figure out position */ |
1077 |
< |
|
1077 |
> |
fcross(v0, miga[2]->rbfv[0]->invec, miga[2]->rbfv[1]->invec); |
1078 |
> |
normalize(v0); |
1079 |
> |
fcross(v2, miga[1]->rbfv[0]->invec, miga[1]->rbfv[1]->invec); |
1080 |
> |
normalize(v2); |
1081 |
> |
fcross(v1, invec, miga[1]->rbfv[1]->invec); |
1082 |
> |
normalize(v1); |
1083 |
> |
s = acos(DOT(v0,v1)) / acos(DOT(v0,v2)); |
1084 |
> |
geodesic(v1, miga[0]->rbfv[0]->invec, miga[0]->rbfv[1]->invec, |
1085 |
> |
s, GEOD_REL); |
1086 |
> |
t = acos(DOT(v1,invec)) / acos(DOT(v1,miga[1]->rbfv[1]->invec)); |
1087 |
> |
n = 0; /* count migrating particles */ |
1088 |
> |
for (i = 0; i < mtx_nrows(miga[0]); i++) |
1089 |
> |
for (j = 0; j < mtx_ncols(miga[0]); j++) |
1090 |
> |
for (k = (miga[0]->mtx[mtx_ndx(miga[0],i,j)] > FTINY) * |
1091 |
> |
mtx_ncols(miga[2]); k--; ) |
1092 |
> |
n += (miga[2]->mtx[mtx_ndx(miga[2],i,k)] > FTINY && |
1093 |
> |
miga[1]->mtx[mtx_ndx(miga[1],j,k)] > FTINY); |
1094 |
> |
|
1095 |
|
rbf = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(n-1)); |
1096 |
|
if (rbf == NULL) { |
1097 |
|
fputs("Out of memory in advect_rbf()\n", stderr); |
1099 |
|
} |
1100 |
|
rbf->next = NULL; rbf->ejl = NULL; |
1101 |
|
VCOPY(rbf->invec, invec); |
1027 |
– |
rbf->vtotal = 0; |
1102 |
|
rbf->nrbf = n; |
1103 |
< |
|
1103 |
> |
n = 0; /* compute RBF lobes */ |
1104 |
> |
mbfact = s * miga[0]->rbfv[1]->vtotal/miga[0]->rbfv[0]->vtotal * |
1105 |
> |
(1.-t + t*miga[1]->rbfv[1]->vtotal/miga[1]->rbfv[0]->vtotal); |
1106 |
> |
mcfact = (1.-s) * |
1107 |
> |
(1.-t + t*miga[2]->rbfv[1]->vtotal/miga[2]->rbfv[0]->vtotal); |
1108 |
> |
for (i = 0; i < mtx_nrows(miga[0]); i++) { |
1109 |
> |
const RBFVAL *rbf0i = &miga[0]->rbfv[0]->rbfa[i]; |
1110 |
> |
const float w0i = rbf0i->peak; |
1111 |
> |
const double rad0i = R2ANG(rbf0i->crad); |
1112 |
> |
ovec_from_pos(v0, rbf0i->gx, rbf0i->gy); |
1113 |
> |
for (j = 0; j < mtx_ncols(miga[0]); j++) { |
1114 |
> |
const float ma = miga[0]->mtx[mtx_ndx(miga[0],i,j)]; |
1115 |
> |
const RBFVAL *rbf1j; |
1116 |
> |
double rad1j, srad2; |
1117 |
> |
if (ma <= FTINY) |
1118 |
> |
continue; |
1119 |
> |
rbf1j = &miga[0]->rbfv[1]->rbfa[j]; |
1120 |
> |
rad1j = R2ANG(rbf1j->crad); |
1121 |
> |
srad2 = (1.-s)*(1.-t)*rad0i*rad0i + s*(1.-t)*rad1j*rad1j; |
1122 |
> |
ovec_from_pos(v1, rbf1j->gx, rbf1j->gy); |
1123 |
> |
geodesic(v1, v0, v1, s, GEOD_REL); |
1124 |
> |
for (k = 0; k < mtx_ncols(miga[2]); k++) { |
1125 |
> |
float mb = miga[1]->mtx[mtx_ndx(miga[1],j,k)]; |
1126 |
> |
float mc = miga[2]->mtx[mtx_ndx(miga[2],i,k)]; |
1127 |
> |
const RBFVAL *rbf2k; |
1128 |
> |
double rad2k; |
1129 |
> |
FVECT vout; |
1130 |
> |
int pos[2]; |
1131 |
> |
if ((mb <= FTINY) | (mc <= FTINY)) |
1132 |
> |
continue; |
1133 |
> |
rbf2k = &miga[2]->rbfv[1]->rbfa[k]; |
1134 |
> |
rbf->rbfa[n].peak = w0i * ma * (mb*mbfact + mc*mcfact); |
1135 |
> |
rad2k = R2ANG(rbf2k->crad); |
1136 |
> |
rbf->rbfa[n].crad = RAD2R(sqrt(srad2 + t*rad2k*rad2k)); |
1137 |
> |
ovec_from_pos(v2, rbf2k->gx, rbf2k->gy); |
1138 |
> |
geodesic(vout, v1, v2, t, GEOD_REL); |
1139 |
> |
pos_from_vec(pos, vout); |
1140 |
> |
rbf->rbfa[n].gx = pos[0]; |
1141 |
> |
rbf->rbfa[n].gy = pos[1]; |
1142 |
> |
++n; |
1143 |
> |
} |
1144 |
> |
} |
1145 |
> |
} |
1146 |
> |
rbf->vtotal = miga[0]->rbfv[0]->vtotal * (mbfact + mcfact); |
1147 |
|
return(rbf); |
1148 |
|
} |
1149 |
|
|