github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/SHADOW.go (about)

     1  //This file is part of EESLISM.
     2  //
     3  //Foobar is free software : you can redistribute itand /or modify
     4  //it under the terms of the GNU General Public License as published by
     5  //the Free Software Foundation, either version 3 of the License, or
     6  //(at your option) any later version.
     7  //
     8  //Foobar is distributed in the hope that it will be useful,
     9  //but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
    11  //GNU General Public License for more details.
    12  //
    13  //You should have received a copy of the GNU General Public License
    14  //along with Foobar.If not, see < https://www.gnu.org/licenses/>.
    15  
    16  /*
    17   影の計算
    18   FILE=SHADOW.c
    19   Create Date=1999.6.7
    20  
    21  */
    22  
    23  package eeslism
    24  
    25  import "math"
    26  
    27  func SHADOW(
    28  	g int,
    29  	DE float64,
    30  	opn int,
    31  	lpn int,
    32  	ls float64,
    33  	ms float64,
    34  	ns float64,
    35  	s *bekt,
    36  	t *bekt,
    37  	op *P_MENN,
    38  	OP []P_MENN,
    39  	LP []P_MENN,
    40  	wap *float64,
    41  	wip []float64,
    42  	nday int,
    43  ) {
    44  	var Am, Bm, Amx, Amy, Amz, Bmx, Bmy, Bmz, A, B float64
    45  	var i, j, h, k int
    46  	var Px, Py, Pz, Qx, Qy, Qz, OX, OY, OZ, OX1, OY1, OZ1, SHITA float64
    47  	var rp, rp2 int /*--多角形ループ-*/
    48  	var naibu int   /*--壁面の内部かフラグ*/
    49  	var naibuw int  /*--窓面の内部かフラグ*/
    50  	var omote int   /*--面から見えるかフラグ 0:見えない 1:見える--*/
    51  	var DEM float64
    52  	var S, T float64
    53  	var flg int
    54  	var tau float64 /*--透過率(合計)--*/
    55  
    56  	var loopA, loopB int /* ループカウンター 横・縦  20170821 higuchi*/
    57  	var AMAX, BMAX int   /* 分割数 幅・高さ*/
    58  
    59  	DEM = DE / 1000. /*--mmをmに変換--*/
    60  	rp = op.polyd - 2
    61  
    62  	for i = 0; i < rp; i++ {
    63  		Amx = op.P[i+1].X - op.P[0].X
    64  		Amy = op.P[i+1].Y - op.P[0].Y
    65  		Amz = op.P[i+1].Z - op.P[0].Z
    66  		Am = math.Sqrt(Amx*Amx + Amy*Amy + Amz*Amz)
    67  		Bmx = op.P[i+2].X - op.P[0].X
    68  		Bmy = op.P[i+2].Y - op.P[0].Y
    69  		Bmz = op.P[i+2].Z - op.P[0].Z
    70  		Bm = math.Sqrt(Bmx*Bmx + Bmy*Bmy + Bmz*Bmz)
    71  
    72  		/* 20170821 higuchi add*/
    73  		AMAX = int(math.Ceil(Am / DEM))
    74  		BMAX = int(math.Ceil(Bm / DEM))
    75  
    76  		for loopA = 0; loopA < AMAX-1; loopA++ {
    77  			for loopB = 0; loopB < BMAX-1; loopB++ {
    78  
    79  				A = (DEM / 2.0) + DEM*float64(loopA)
    80  				B = (DEM / 2.0) + DEM*float64(loopB)
    81  
    82  				//for (A = DEM / 2.; A < Am; A = A + DEM){
    83  				//for (B = DEM / 2.; B < Bm; B = B + DEM){
    84  				Px = 0.0
    85  				Py = 0.0
    86  				Pz = 0.0
    87  				Qx = 0.0
    88  				Qy = 0.0
    89  				Qz = 0.0
    90  				S = 0.0
    91  				T = 0.0
    92  				OX = 0.0
    93  				OY = 0.0
    94  				OZ = 0.0
    95  				OX1 = 0.0
    96  				OY1 = 0.0
    97  				OZ1 = 0.0
    98  				SHITA = 0.0
    99  
   100  				/*----
   101  				printf("DEM=%f,A=%f,B=%f\n",DEM,A,B) ;
   102  				----*/
   103  				/*--グリッドを移動するQ点の座標を求める---*/
   104  				OX = (A / Am) * Amx
   105  				OY = (A / Am) * Amy
   106  				OZ = (A / Am) * Amz
   107  				OX1 = (B / Bm) * Bmx
   108  				OY1 = (B / Bm) * Bmy
   109  				OZ1 = (B / Bm) * Bmz
   110  
   111  				Qx = op.P[0].X + OX + OX1
   112  				Qy = op.P[0].Y + OY + OY1
   113  				Qz = op.P[0].Z + OZ + OZ1
   114  
   115  				naibu = 0
   116  				/*------QがOPの内部にあるか------*/
   117  				rp2 = op.polyd - 2
   118  
   119  				for j = 0; j < rp2; j++ {
   120  					INOROUT(Qx, Qy, Qz, op.P[0], op.P[j+1], op.P[j+2], &S, &T)
   121  
   122  					if (S >= 0.0 && T >= 0.0) && ((S + T) <= 1.0) {
   123  						(*wap) = (*wap) + 1.0
   124  						naibu = 1   /*--壁内部--*/
   125  						naibuw = -1 /*--窓番号初期化--*/
   126  						/*---Qが窓面にあるか----*/
   127  						for k = 0; k < op.wd; k++ {
   128  							for h = 0; h < 2; h++ {
   129  								INOROUT(Qx, Qy, Qz, op.opw[k].P[0], op.opw[k].P[h+1], op.opw[k].P[h+2], &S, &T)
   130  								if (S >= 0.0 && T >= 0.0) && (S+T) <= 1.0 {
   131  									wip[k] = wip[k] + 1.0
   132  									naibuw = k
   133  									break
   134  								}
   135  							}
   136  							if naibuw != -1 {
   137  								break
   138  							}
   139  						}
   140  						break
   141  					}
   142  				}
   143  				if naibu == 0 {
   144  					continue
   145  				}
   146  
   147  				/*---建物自身による影を考慮----*/
   148  				for j = 0; j < opn; j++ {
   149  					omote = 0
   150  					for k = 0; k < OP[j].polyd; k++ {
   151  						if s.ps[j][k] > 0.0 {
   152  							omote = 1
   153  							break
   154  						}
   155  					}
   156  					if (g != j) && (omote > 0) {
   157  						KOUTEN(Qx, Qy, Qz, ls, ms, ns, &Px, &Py, &Pz, OP[j].P[0], OP[j].e)
   158  						YOGEN(Qx, Qy, Qz, Px, Py, Pz, &SHITA, op.e)
   159  						rp2 = OP[j].polyd - 2
   160  						for k = 0; k < rp2; k++ { /*--多角形ループ---*/
   161  
   162  							INOROUT(Px, Py, Pz, OP[j].P[0], OP[j].P[k+1], OP[j].P[k+2], &S, &T)
   163  							if ((S > 0.0 && T > 0.0) && ((S + T) < 1.0)) && (SHITA > 0) {
   164  
   165  								if naibu == 1 {
   166  									op.sum = op.sum + 1.0
   167  								}
   168  								if naibuw >= 0 {
   169  									op.opw[naibuw].sumw = op.opw[naibuw].sumw + 1.0
   170  								}
   171  								goto koko
   172  							}
   173  						}
   174  					}
   175  				}
   176  
   177  				/*-------------障害物による影を考慮----------------------*/
   178  				flg = 0 // 100703 higuchi add
   179  				for h = 0; h < lpn; h++ {
   180  					omote = 0
   181  					for k = 0; k < LP[h].polyd; k++ {
   182  						if t.ps[h][k] > 0.0 {
   183  							omote = 1
   184  							break
   185  						}
   186  					}
   187  					if omote > 0 {
   188  
   189  						//	    flg = 0 ;  100703 higuchi dell
   190  						KOUTEN(Qx, Qy, Qz, ls, ms, ns, &Px, &Py, &Pz, LP[h].P[0], LP[h].e)
   191  						YOGEN(Qx, Qy, Qz, Px, Py, Pz, &SHITA, op.e)
   192  
   193  						rp2 = LP[h].polyd - 2
   194  						for k = 0; k < rp2; k++ {
   195  
   196  							INOROUT(Px, Py, Pz, LP[h].P[0], LP[h].P[k+1], LP[h].P[k+2], &S, &T)
   197  							if ((S > 0.0 && T > 0.0) && ((S + T) < 1.0)) && (SHITA > 0) {
   198  
   199  								if flg == 0 {
   200  									tau = 1. - LP[h].shad[nday]
   201  									flg = 1
   202  								} else {
   203  									tau = tau * (1. - LP[h].shad[nday])
   204  								}
   205  
   206  								break //100703 higuchi add
   207  								//		    op.sum = op.sum + LP[h].shad[nday] ;
   208  								//            if(naibuw >= 0)
   209  								//		       op.opw[naibuw].sumw=op.opw[naibuw].sumw+LP[h].shad[nday] ;
   210  								//		    goto koko ;
   211  							}
   212  						} // for
   213  
   214  					}
   215  				} // for
   216  
   217  				op.sum = op.sum + (1. - tau)
   218  
   219  				if naibuw >= 0 {
   220  					op.opw[naibuw].sumw = op.opw[naibuw].sumw + (1 - tau)
   221  				}
   222  				tau = 1
   223  			koko:
   224  			}
   225  		}
   226  	}
   227  
   228  	for i = 0; i < op.wd; i++ {
   229  		(*wap) = (*wap) - wip[i]
   230  		op.sum = op.sum - op.opw[i].sumw
   231  		if wip[i] == 0 {
   232  			op.opw[i].sumw = 0
   233  		} else {
   234  			op.opw[i].sumw = (op.opw[i].sumw / wip[i])
   235  		}
   236  	}
   237  
   238  	if *wap == 0 {
   239  		op.sum = 0
   240  	} else {
   241  		op.sum = op.sum / (*wap)
   242  	}
   243  }
   244  
   245  /*----------------------------------------------------------------------*/
   246  func SHADOWlp(
   247  	g int,
   248  	DE float64,
   249  	lpn int,
   250  	mpn int,
   251  	ls float64,
   252  	ms float64,
   253  	ns float64,
   254  	s *bekt,
   255  	t *bekt,
   256  	lp *P_MENN,
   257  	LP []P_MENN,
   258  	MP []P_MENN,
   259  ) {
   260  	var Am, Bm, Amx, Amy, Amz, Bmx, Bmy, Bmz, A, B, wap float64
   261  	var i, j, k, h int
   262  	var Px, Py, Pz, Qx, Qy, Qz float64
   263  	var S, T float64
   264  	var OX, OY, OZ, OX1, OY1, OZ1, SHITA float64
   265  	var omote int   /*--面から見えるかフラグ-*/
   266  	var rp, rp2 int /*--多角形ループ回数--*/
   267  
   268  	var loopA, loopB int /* ループカウンター 横・縦  20170821 higuchi*/
   269  	var AMAX, BMAX int   /* 分割数 幅・高さ*/
   270  
   271  	var DEM float64         /*higuchi add 20180125*/
   272  	DEM = (DE * 5) / 1000.0 /*--mmをmに変換-- 粗目のグリッドにする higuchi add 20180125*/
   273  	rp = lp.polyd - 2
   274  	for i = 0; i < rp; i++ {
   275  
   276  		Amx = lp.P[i+1].X - lp.P[0].X
   277  		Amy = lp.P[i+1].Y - lp.P[0].Y
   278  		Amz = lp.P[i+1].Z - lp.P[0].Z
   279  		Am = math.Sqrt(Amx*Amx + Amy*Amy + Amz*Amz)
   280  		Bmx = lp.P[i+2].X - lp.P[0].X
   281  		Bmy = lp.P[i+2].Y - lp.P[0].Y
   282  		Bmz = lp.P[i+2].Z - lp.P[0].Z
   283  		Bm = math.Sqrt(Bmx*Bmx + Bmy*Bmy + Bmz*Bmz)
   284  		//AM = Am * 100.0;
   285  		//BM = Bm * 100.0;
   286  
   287  		//dea = AM / DE;
   288  		//deb = BM / DE;
   289  
   290  		/* 20180125 higuchi add*/
   291  		AMAX = int(math.Ceil(Am / DEM))
   292  		BMAX = int(math.Ceil(Bm / DEM))
   293  
   294  		/* 20170821 higuchi add*/
   295  		//AMAX = (int)ceil(Am / dea);
   296  		//BMAX = (int)ceil(Bm / deb);
   297  
   298  		for loopA = 0; loopA < AMAX-1; loopA++ {
   299  			for loopB = 0; loopB < BMAX-1; loopB++ {
   300  
   301  				/*--higuchi upd 20180125--*/
   302  				A = (DEM / 2.0) + DEM*float64(loopA)
   303  				B = (DEM / 2.0) + DEM*float64(loopB)
   304  
   305  				//for (A = (dea / 2); A < AM; A = A + dea){
   306  				//for (B = (deb / 2); B < BM; B = B + deb){
   307  				Px = 0.0
   308  				Py = 0.0
   309  				Pz = 0.0
   310  				Qx = 0.0
   311  				Qy = 0.0
   312  				Qz = 0.0
   313  				S = 0.0
   314  				T = 0.0
   315  				OX = 0.0
   316  				OY = 0.0
   317  				OZ = 0.0
   318  				OX1 = 0.0
   319  				OY1 = 0.0
   320  				OZ1 = 0.0
   321  				SHITA = 0.0
   322  
   323  				wap = wap + 1.0
   324  
   325  				OX = (A / Am) * Amx
   326  				OY = (A / Am) * Amy
   327  				OZ = (A / Am) * Amz
   328  				OX1 = (B / Bm) * Bmx
   329  				OY1 = (B / Bm) * Bmy
   330  				OZ1 = (B / Bm) * Bmz
   331  
   332  				//OX = (A / AM)*Amx;
   333  				//OY = (A / AM)*Amy;
   334  				//OZ = (A / AM)*Amz;
   335  				//OX1 = (B / BM)*Bmx;
   336  				//OY1 = (B / BM)*Bmy;
   337  				//OZ1 = (B / BM)*Bmz;
   338  
   339  				Qx = lp.P[0].X + OX + OX1
   340  				Qy = lp.P[0].Y + OY + OY1
   341  				Qz = lp.P[0].Z + OZ + OZ1
   342  
   343  				/*---------LPによる影を考慮------------------*/
   344  				for j = 0; j < lpn; j++ {
   345  					omote = 0
   346  					for k = 0; k < LP[j].polyd; k++ {
   347  						if s.ps[j][k] > 0.0 {
   348  							omote = 1
   349  							break
   350  						}
   351  					}
   352  					if (g != j) && (omote > 0) {
   353  						KOUTEN(Qx, Qy, Qz, ls, ms, ns, &Px, &Py, &Pz, LP[j].P[0], LP[j].e)
   354  						YOGEN(Qx, Qy, Qz, Px, Py, Pz, &SHITA, lp.e)
   355  						rp2 = LP[j].polyd - 2
   356  						for k = 0; k < rp2; k++ {
   357  							INOROUT(Px, Py, Pz, LP[j].P[0], LP[j].P[k+1], LP[j].P[k+2], &S, &T)
   358  							if ((S >= 0.0 && T >= 0.0) && ((S + T) <= 1.0)) && (SHITA > 0) {
   359  								lp.sum = lp.sum + 1.0
   360  								goto koko
   361  							}
   362  						}
   363  					}
   364  				}
   365  
   366  				/*-----------------MPによる影を考慮----------------------*/
   367  				for h = 0; h < mpn; h++ {
   368  					omote = 0
   369  					for k = 0; k < MP[h].polyd; k++ {
   370  						if t.ps[h][k] > 0.0 {
   371  							omote = 1
   372  							break
   373  						}
   374  					}
   375  					if omote > 0 {
   376  						KOUTEN(Qx, Qy, Qz, ls, ms, ns, &Px, &Py, &Pz, MP[h].P[0], MP[h].e)
   377  						YOGEN(Qx, Qy, Qz, Px, Py, Pz, &SHITA, lp.e)
   378  						rp2 = LP[h].polyd - 2
   379  						for k = 0; k < rp2; k++ {
   380  							INOROUT(Px, Py, Pz, LP[h].P[0], LP[h].P[k+1], LP[h].P[k+2], &S, &T)
   381  							if ((S >= 0.0 && T >= 0.0) && ((S + T) <= 1.0)) && (SHITA > 0) {
   382  								lp.sum = lp.sum + 1.0
   383  								goto koko
   384  							}
   385  						}
   386  					}
   387  				}
   388  			koko:
   389  			}
   390  		}
   391  	}
   392  	lp.sum = lp.sum / wap
   393  }