util.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. function isTwoLine(arr) {
  2. var max = 0,
  3. min = 1;
  4. for (var i = 0; i < arr.length; i++) {
  5. if (arr[i][0] > max) {
  6. max = arr[i][0];
  7. }
  8. if (arr[i][0] < min) {
  9. min = arr[i][0];
  10. }
  11. }
  12. return [min === 0, max];
  13. }
  14. /*
  15. @function: 加载3D线段,需要根据平台自行实现
  16. @info: 这里生成一个3D单位CUBE的所有线段
  17. */
  18. function _3dLine(r2x, r3x, ret) {
  19. // 坐标点长度
  20. var r1x = 0.5;
  21. // 矩形的各个定点
  22. var r2x_t = [
  23. [-r1x, -r1x, +r1x],
  24. [-r1x, +r1x, +r1x],
  25. [+r1x, +r1x, +r1x],
  26. [+r1x, -r1x, +r1x],
  27. [-r1x, -r1x, -r1x],
  28. [-r1x, +r1x, -r1x],
  29. [+r1x, +r1x, -r1x],
  30. [+r1x, -r1x, -r1x]
  31. ];
  32. // 线段的坐标
  33. // z轴
  34. var r3x_t = [
  35. [0, 1],
  36. [1, 2],
  37. [2, 3],
  38. [3, 0],
  39. [4, 5],
  40. [5, 6],
  41. [6, 7],
  42. [7, 4],
  43. [0, 4],
  44. [1, 5],
  45. [2, 6],
  46. [3, 7]
  47. ];
  48. // 各个线段的坐标
  49. var ret_t = [
  50. ["", ""],
  51. ["", ""],
  52. ["", ""],
  53. ["", ""],
  54. ["", ""],
  55. ["", ""],
  56. ["", ""],
  57. ["", ""],
  58. ["", ""],
  59. ["", ""],
  60. ["", ""],
  61. ["", ""]
  62. ];
  63. ret[0][0] = r2x[r3x[0][0]];
  64. for (var i = 0; i < r3x.length; i++) {
  65. ret[i] = {
  66. "3d_id":i,
  67. "3d_point1":r2x[r3x[i][0]],
  68. "3d_point2":r2x[r3x[i][1]]
  69. }
  70. // ret[i][0] = r2x[r3x[i][0]];
  71. // ret[i][1] = r2x[r3x[i][1]];
  72. }
  73. ret_t[0][0] = r2x_t[r3x_t[0][0]];
  74. for (var i = 0; i < r3x_t.length; i++) {
  75. ret_t[i][0] = r2x_t[r3x_t[i][0]];
  76. ret_t[i][1] = r2x_t[r3x_t[i][1]];
  77. }
  78. console.log(ret)
  79. return ret;
  80. }
  81. function fix3dLineArr(arr,faceArr) {
  82. var ret = []
  83. for (let i = 0; i < faceArr.length; i++) {
  84. var item = {
  85. faceLine:[],
  86. index:[],
  87. verticalLine:[]
  88. }
  89. for (let j = 0; j < faceArr[i].length; j++) {
  90. for (let k = 0; k < arr.length; k++) {
  91. if (faceArr[i][j]==arr[k]['3d_id']) {
  92. item.faceLine.push({
  93. id:faceArr[i][j],
  94. points:[arr[k]["3d_point1"],arr[k]["3d_point1"]]
  95. })
  96. item.index.push(faceArr[i][j])
  97. }
  98. }
  99. }
  100. ret.push(item)
  101. }
  102. console.log('====================================');
  103. console.log('ret',ret);
  104. console.log('====================================');
  105. }
  106. // 归一化
  107. function normalize(xyz, isFixed) {
  108. var _mo_ = Math.sqrt(xyz[0] * xyz[0] + xyz[1] * xyz[1] + xyz[2] * xyz[2]);
  109. var x = xyz[0] / _mo_;
  110. var y = xyz[1] / _mo_;
  111. var z = xyz[2] / _mo_;
  112. var r1x;
  113. if (isFixed) {
  114. r1x = [-y, -x, z];
  115. } else {
  116. r1x = [x, y, z];
  117. }
  118. return r1x;
  119. }
  120. /*
  121. @function: 相机在坐标原点上,返回空间点在球目图片上的投影点,和'_calculate3dPoint'互逆
  122. @param {xyz}: 空间中的3D点,不需要先进行归一化
  123. @return {ret}: 纹理空间的2D点,范围为[0 ,1]
  124. */
  125. function _calculate2dPoint(xyz) {
  126. var ret = ["", ""];
  127. //@info: 这一步是为了兼容我们所用的球目相机的正方向,并且进行归一化
  128. // const auto r1x = Vector<VAL64> {-xyz[1] ,-xyz[0] ,xyz[2] ,0}.normalize () ;
  129. var r1x = normalize(xyz, true);
  130. // var r1x = xyz
  131. ret[0] = Math.atan2(r1x[1], r1x[0]) / (Math.PI * 2) + 0.5;
  132. ret[1] = (Math.acos(r1x[2]) / (Math.PI * 2)) * 2;
  133. return ret;
  134. // ARRAY2<VAL64> ret ;
  135. // //@info: 这一步是为了兼容我们所用的球目相机的正方向,并且进行归一化
  136. // const auto r1x = Vector<VAL64> {-xyz[1] ,-xyz[0] ,xyz[2] ,0}.normalize () ;
  137. // //@info: 分别计算投影点坐标
  138. // //@info: 反三角函数,缩放,平移
  139. // ret[0] = _ATAN_ (r1x[1] , r1x[0]) / VAL64 (VALX_PI * 2) + VAL64 (0.5) ;
  140. // ret[1] = _ACOS_ (r1x[2]) / VAL64 (VALX_PI * 2) * 2 ;
  141. // return std::move (ret) ;
  142. }
  143. /*
  144. @function: 相机在坐标原点上,返回球目图片上的投影点所在单位球上的原点,和'_calculate2dPoint'互逆
  145. @param {txy}: 纹理空间的2D点,范围为[0 ,1]
  146. @return {ret}: 空间中的3D点,在单位球上
  147. */
  148. function _calculate3dPoint(txy) {
  149. var ret = ["", "", ""];
  150. var r1x = (txy[1] / 2) * (Math.PI * 2);
  151. var r2x = (txy[0] - 0.5) * (Math.PI * 2);
  152. ret[0] = -Math.sin(r1x) * Math.sin(r2x);
  153. ret[1] = -Math.sin(r1x) * Math.cos(r2x);
  154. ret[2] = Math.cos(r1x);
  155. return ret;
  156. }
  157. /*
  158. @function: 计算栅格化所有线段后最大生成点的数量
  159. @param {line}: 线段的数组,line[i][0]为第一个点,line[i][1]为第二个点
  160. @param {gap}: 栅格化所需的步长,既每多长生成一个点
  161. @return {ret}: 最大生成点的数量
  162. */
  163. function _calculateMaxPoint(line, gap) {
  164. var ret = 0;
  165. for (var i = 0; i < line.length; i++) {
  166. var r1x = line[i][0];
  167. var r2x = line[i][1];
  168. // Math.hypot(x1 - x0, y1 - y0);
  169. ret += Math.ceil(
  170. Math.hypot(r1x[0] - r2x[0], r1x[1] - r2x[1], r1x[2] - r2x[2]) / gap + 0.5
  171. );
  172. }
  173. return ret;
  174. }
  175. /*
  176. @function: 计算3D线段在球目图片上的栅格化投影
  177. @param {camera_pose_matrix}: 相机位置,外参矩阵
  178. @param {line}: 线段的数组,line[i][0]为第一个点,line[i][1]为第二个点
  179. @param {gap}: 栅格化所需的步长,既每多长生成一个点
  180. @return {ret}: 栅格化投影投影后的2D线段,点坐标属于纹理空间,范围为[0 ,1]
  181. */
  182. function _3dTo2d(camera_pose_matrix, line, gap) {
  183. var ret = [];
  184. var ret_t = [];
  185. var item;
  186. var r10x = numbers.matrix.inverse(camera_pose_matrix);
  187. for (var i = 0; i < line.length; i++) {
  188. ret_t.push({ line: [] });
  189. item = []
  190. var r1x_temp = [[line[i]["3d_point1"][0]], [line[i]['3d_point1'][1]], [line[i]['3d_point1'][2]], [1]];
  191. var r2x_temp = [[line[i]['3d_point2'][0]], [line[i]['3d_point2'][1]], [line[i]['3d_point2'][2]], [1]];
  192. var r1x = numbers.matrix.multiply(r10x, r1x_temp);
  193. var r2x = numbers.matrix.multiply(r10x, r2x_temp);
  194. var r3x = Math.hypot(r2x[0] - r1x[0], r2x[1] - r1x[1], r2x[2] - r1x[2]) / gap
  195. var r2r1 = [r2x[0] - r1x[0], r2x[1] - r1x[1], r2x[2] - r1x[2]];
  196. var hasNormalize = normalize(r2r1, false);
  197. var r5x = [
  198. hasNormalize[0] * gap,
  199. hasNormalize[1] * gap,
  200. hasNormalize[2] * gap
  201. ];
  202. for (var j = 0; j < r3x; j++) {
  203. var r6x = [
  204. parseFloat(r1x[0]) + parseFloat(r5x[0]) * j,
  205. parseFloat(r1x[1]) + parseFloat(r5x[1]) * j,
  206. parseFloat(r1x[2]) + parseFloat(r5x[2]) * j
  207. ];
  208. var r7x = _calculate2dPoint(r6x);
  209. if (r7x[0] > maxX) {
  210. maxX = r7x[0];
  211. }
  212. ret_t[i].line.push(toDecimal(r7x));
  213. item.push(toDecimal(r7x))
  214. }
  215. var r6x_t = [
  216. parseFloat(r1x[0]) + parseFloat(r5x[0]) * r3x,
  217. parseFloat(r1x[1]) + parseFloat(r5x[1]) * r3x,
  218. parseFloat(r1x[2]) + parseFloat(r5x[2]) * r3x
  219. ];
  220. var r7x_t = _calculate2dPoint(r6x_t);
  221. ret_t[i].line.push(toDecimal(r7x_t));
  222. item.push(toDecimal(r7x_t))
  223. ret.push({
  224. "3d_id":[line[i]["3d_id"]][0],
  225. '2d_arr':fixLine(item)
  226. })
  227. }
  228. // ret2dObj(ret)
  229. return {
  230. drawArr:ret_t,
  231. to3d:ret2dObj(ret)
  232. };
  233. // return ret_t;
  234. }
  235. function ret2dObj(arr) {
  236. var ret =[];
  237. var count = 0
  238. for (var i = 0; i < arr.length; i++) {
  239. for (var j = 0; j < arr[i]["2d_arr"].length; j++) {
  240. ret.push({
  241. "2d_id":count,
  242. "3d_id":i,
  243. "2d_point1":arr[i]["2d_arr"][j]["2d_point1"],
  244. "2d_point2":arr[i]["2d_arr"][j]["2d_point2"]
  245. })
  246. count++
  247. }
  248. }
  249. return {
  250. panorama_line_2d:ret
  251. }
  252. }
  253. function fixLine(arr) {
  254. var obj,
  255. t_arr = [];
  256. for (var i = 0; i < arr.length; i++) {
  257. obj = {
  258. "2d_point1": arr[i],
  259. "2d_point2": arr[i + 1]
  260. };
  261. if (obj["2d_point2"]&&obj["2d_point2"]!=obj["2d_point1"]) {
  262. t_arr.push(obj);
  263. }
  264. }
  265. return t_arr;
  266. }
  267. /**
  268. * 四舍五入保留6位小数
  269. * @param {数组} arr
  270. */
  271. function toDecimal(arr) {
  272. var xf = parseFloat(arr[0]);
  273. var yf = parseFloat(arr[1]);
  274. if (isNaN(xf) || isNaN(yf)) {
  275. return;
  276. }
  277. tx = Math.round(xf * 10e5) / 10e5;
  278. ty = Math.round(yf * 10e5) / 10e5;
  279. return [tx, ty];
  280. }
  281. function make_matrix_from_quat(quat) {
  282. var ret = numbers.matrix.identity(4);
  283. var r1x =
  284. quat[0] * quat[0] +
  285. quat[1] * quat[1] +
  286. quat[2] * quat[2] +
  287. quat[3] * quat[3];
  288. if (r1x != 0) {
  289. var x2 = (2 / r1x) * quat[0];
  290. var y2 = (2 / r1x) * quat[1];
  291. var z2 = (2 / r1x) * quat[2];
  292. var xx = quat[0] * x2;
  293. var xy = quat[0] * y2;
  294. var xz = quat[0] * z2;
  295. var yy = quat[1] * y2;
  296. var yz = quat[1] * z2;
  297. var zz = quat[2] * z2;
  298. var wx = quat[3] * x2;
  299. var wy = quat[3] * y2;
  300. var wz = quat[3] * z2;
  301. ret[0][0] = 1 - (yy + zz);
  302. ret[1][0] = xy - wz;
  303. ret[2][0] = xz + wy;
  304. ret[0][1] = xy + wz;
  305. ret[1][1] = 1 - (xx + zz);
  306. ret[2][1] = yz - wx;
  307. ret[0][2] = xz - wy;
  308. ret[1][2] = yz + wx;
  309. ret[2][2] = 1 - (xx + yy);
  310. }
  311. // ret = numbers.matrix.multiply([[1, 0, 0], [0, 1, 0], [0, 0, 1]], transpose(ret))
  312. var tran = [
  313. [1, 0, 0, quat[4]],
  314. [0, 1, 0, quat[5]],
  315. [0, 0, 1, quat[6]],
  316. [0, 0, 0, 1]
  317. ];
  318. ret = numbers.matrix.multiply(tran, transpose(ret));
  319. return ret;
  320. // [
  321. // [1, 0, 0, quat[4]],
  322. // [0, 1, 0, quat[5]],
  323. // [0, 0, 1, quat[6]],
  324. // [0 ,0 ,0 ,1]
  325. // ]
  326. }
  327. /**
  328. * 矩阵转置
  329. * @param {矩阵} arr
  330. */
  331. function transpose(arr) {
  332. var arr2 = [];
  333. for (var i = 0; i < arr[0].length; i++) {
  334. arr2[i] = [];
  335. }
  336. for (var i = 0; i < arr.length; i++) {
  337. for (var j = 0; j < arr[i].length; j++) {
  338. arr2[j][i] = arr[i][j];
  339. }
  340. }
  341. return arr2;
  342. }
  343. /**
  344. * 画线
  345. * @param {*画布} context
  346. * @param {*画布宽度 } w
  347. * @param {*画布高度} h
  348. * @param {*水平缩放倍数} scaleTime
  349. * @param {*垂直缩放倍数} scaleTimeH
  350. * @param {*线条数组} lineArr
  351. * @param {*是否重画} isclear
  352. */
  353. function drawSingleLine(
  354. context,
  355. w,
  356. h,
  357. scaleTime,
  358. scaleTimeH,
  359. lineArr,
  360. isclear
  361. ) {
  362. context.beginPath();
  363. if (isclear) {
  364. context.clearRect(0, 0, w, h);
  365. context.drawImage(img, 0, 0, w, h);
  366. }
  367. context.moveTo(
  368. lineArr[0].line[0][0] * scaleTime,
  369. lineArr[0].line[0][1] * scaleTimeH
  370. );
  371. for (var i = 0; i < lineArr.length; i++) {
  372. if (isTwoLine(lineArr[i].line)[0]) {
  373. for (var k = 0; k < lineArr[i].line.length; k++) {
  374. if (lineArr[i].line[k][0] < 0.5) {
  375. var temp = lineArr[i].line[k][0] + isTwoLine(lineArr[i].line)[1];
  376. if (temp <= 1) {
  377. lineArr[i].line.push([temp, lineArr[i].line[k][1]]);
  378. }
  379. }
  380. }
  381. }
  382. context.moveTo(
  383. lineArr[i].line[0][0] * scaleTime,
  384. lineArr[i].line[0][1] * scaleTimeH
  385. );
  386. for (var j = 0; j < lineArr[i].line.length; j++) {
  387. if (j + 1 < lineArr[i].line.length) {
  388. // Math.hypot(
  389. // lineArr[i].line[j+1][0] - lineArr[i].line[j][0],
  390. // lineArr[i].line[j+1][1] - lineArr[i].line[j][1]
  391. // ) < 0.05
  392. if (Math.abs(lineArr[i].line[j + 1][0] - lineArr[i].line[j][0]) > 0.5) {
  393. context.moveTo(
  394. lineArr[i].line[j + 1][0] * scaleTime,
  395. lineArr[i].line[j + 1][1] * scaleTimeH
  396. );
  397. } else {
  398. context.lineTo(
  399. lineArr[i].line[j][0] * scaleTime,
  400. lineArr[i].line[j][1] * scaleTimeH
  401. );
  402. }
  403. }
  404. if (j + 1 === lineArr[i].line.length) {
  405. context.lineTo(
  406. lineArr[i].line[j][0] * scaleTime,
  407. lineArr[i].line[j][1] * scaleTimeH
  408. );
  409. }
  410. }
  411. }
  412. context.stroke();
  413. }
  414. /**
  415. * 选中伸缩的墙进行画线
  416. * @param {画布} context
  417. * @param {画布宽度} w
  418. * @param {画布高度} h
  419. * @param {水平缩放倍数} scaleTime
  420. * @param {垂直缩放倍数} scaleTimeH
  421. * @param {线条数组} lineArr
  422. */
  423. function selectDragLine(context, w, h, scaleTime, scaleTimeH, lineArr, test) {
  424. context.strokeStyle = "#ff0000";
  425. drawSingleLine(context, w, h, scaleTime, scaleTimeH, lineArr, true);
  426. context.strokeStyle = "#00ff00";
  427. drawSingleLine(context, w, h, scaleTime, scaleTimeH, test, false);
  428. }
  429. /**
  430. * 找到面得中心坐标
  431. * @param {线段数组} lineArr
  432. * @param {水平缩放倍数} scaleTime
  433. * @param {垂直缩放倍数} scaleTimeH
  434. */
  435. function _calculateMiddlePoint(test, scaleTime, scaleTimeH) {
  436. var minX = 1,
  437. minY = 1,
  438. maxX = 0,
  439. maxY = 0;
  440. for (var i = 0; i < test.length; i++) {
  441. for (var j = 0; j < test[i].line.length; j++) {
  442. minX = Math.min(minX, test[i].line[j][0]);
  443. minY = Math.min(minY, test[i].line[j][1]);
  444. maxX = Math.max(maxX, test[i].line[j][0]);
  445. maxY = Math.max(maxY, test[i].line[j][1]);
  446. }
  447. }
  448. return [
  449. ((maxX - minX) / 2 + minX) * scaleTime,
  450. ((maxY - minY) / 2 + minY) * scaleTimeH
  451. ];
  452. }
  453. /**
  454. * 计算墙体中心和鼠标坐标点的距离
  455. * @param {当前鼠标点击的坐标点} current
  456. * @param {墙体的中心点坐标} middle
  457. */
  458. function _calculateMiddlePointDistance(current, middle) {
  459. return _calculateDistance(current, middle);
  460. }
  461. /**
  462. * 计算两点之间的距离
  463. * @param {坐标点} p1
  464. * @param {坐标点} p2
  465. */
  466. function _calculateDistance(p1, p2) {
  467. return Math.sqrt(Math.pow(p2[1] - p1[1], 2) + Math.pow(p2[0] - p1[0], 2));
  468. }
  469. /**
  470. * 判断点是否在墙体上
  471. * @param {鼠标当前坐标点} current
  472. * @param {墙体线段} lineArr
  473. * @param {水平缩放倍数} scaleTime
  474. * @param {垂直缩放倍数} scaleTimeH
  475. */
  476. function isInFace(current, test, scaleTime, scaleTimeH) {
  477. var fixArr = [];
  478. var selectYArr = [];
  479. var minX = 1,
  480. minY = 1,
  481. maxX = 0,
  482. maxY = 0;
  483. for (var i = 0; i < test.length; i++) {
  484. for (var j = 0; j < test[i].line.length; j++) {
  485. minX = Math.min(minX, test[i].line[j][0]);
  486. // minY = Math.min(minY, test[i].line[j][1]);
  487. maxX = Math.max(maxX, test[i].line[j][0]);
  488. // maxY = Math.max(maxY, test[i].line[j][1]);
  489. fixArr.push({
  490. id: parseFloat(test[i].line[j][0]).toFixed(1),
  491. y: test[i].line[j][1]
  492. });
  493. }
  494. }
  495. for (var i = 0; i < fixArr.length; i++) {
  496. if (fixArr[i].id == parseFloat(current[0] / scaleTime).toFixed(1)) {
  497. selectYArr.push(fixArr[i].y);
  498. }
  499. }
  500. for (var i = 0; i < selectYArr.length; i++) {
  501. minY = Math.min(minY, selectYArr[i]);
  502. maxY = Math.max(maxY, selectYArr[i]);
  503. }
  504. return (
  505. current[0] > minX * scaleTime &&
  506. current[0] < maxX * scaleTime &&
  507. current[1] > minY * scaleTimeH &&
  508. current[1] < maxY * scaleTimeH
  509. );
  510. }
  511. /**
  512. * 更新墙体线段的位置
  513. * @param {缩放的大小} distance
  514. * @param {墙体线段} lineArr
  515. */
  516. function updateLineArr(distance, lineArr,_3dPoint,tag) {
  517. // deltaX:值为负的(-1),则表示滚轮向左滚动。值为正的(1),则表示滚轮向右滚动。
  518. // deltaY:值为负的(-1),则表示滚轮向下滚动。值为正的(1),则表示滚轮向上滚动。
  519. // deltaFactor:增量因子。通过 deltaFactor * deltaX 或者 deltaFactor * deltaY 可以得到浏览器实际的滚动距离。
  520. // distance = -10
  521. if (tag) {
  522. _3dPoint[2][0]+=distance
  523. _3dPoint[3][0]+=distance
  524. _3dPoint[((_3dPoint.length)/2+2)][0]+=distance
  525. _3dPoint[((_3dPoint.length)/2+3)][0]+=distance
  526. } else{
  527. _3dPoint[1][1]+=distance
  528. _3dPoint[2][1]+=distance
  529. _3dPoint[((_3dPoint.length)/2+1)][1]+=distance
  530. _3dPoint[((_3dPoint.length)/2+2)][1]+=distance
  531. }
  532. rx1 = _3dLine(r2x, r3x, ret);
  533. lineArr = _3dTo2d(
  534. make_matrix_from_quat([
  535. 0.008515,
  536. -0.014279,
  537. 0.016179,
  538. 0.999731,
  539. -5.438891,
  540. 2.167653,
  541. 0.165233
  542. ]),
  543. rx1,
  544. 0.05
  545. )["drawArr"];
  546. return lineArr;
  547. }
  548. function updateSelectArr(lineArr,idxArr) {
  549. var ret = [];
  550. for (var i = 0; i < idxArr.length; i++) {
  551. ret.push(lineArr[idxArr[i]])
  552. }
  553. return ret
  554. }
  555. function _culaculateFaceArr(lineArr, faceArr) {
  556. var ret = [];
  557. for (var i = 0; i < faceArr.length; i++) {
  558. var item = [];
  559. for (var j = 0; j < faceArr[i].length; j++) {
  560. item.push(lineArr[faceArr[i][j]]);
  561. }
  562. ret.push({
  563. id:i,
  564. arr:item
  565. });
  566. }
  567. return ret;
  568. }
  569. function selectWhichFace(lineArr, faceArr, current, scaleTime, scaleTimeH) {
  570. var allFaceArr = _culaculateFaceArr(lineArr, faceArr);
  571. var ret = 0;
  572. var tempRet = 0;
  573. var minDist =
  574. faceArr &&
  575. _calculateMiddlePointDistance(
  576. current,
  577. _calculateMiddlePoint(allFaceArr[0].arr, scaleTime, scaleTimeH)
  578. );
  579. for (var i = 0; i < allFaceArr.length; i++) {
  580. if (isInFace(current, allFaceArr[i].arr, scaleTime, scaleTimeH)) {
  581. // tempRet = i
  582. ret = i
  583. if (
  584. _calculateMiddlePointDistance(
  585. current,
  586. _calculateMiddlePoint(allFaceArr[i].arr, scaleTime, scaleTimeH)
  587. ) < minDist
  588. ) {
  589. minDist = _calculateMiddlePointDistance(
  590. current,
  591. _calculateMiddlePoint(allFaceArr[i].arr, scaleTime, scaleTimeH)
  592. );
  593. }else{
  594. ret = i
  595. }
  596. }
  597. }
  598. return allFaceArr[ret];
  599. }
  600. /**
  601. * 根据sta查找点
  602. * @param {array} line1 第一条线段的点坐标
  603. * @param {array} line2 第二条线段的点坐标
  604. * @param {Boolean} sta 决定查找相同的点或不相同的点
  605. */
  606. function findPoint(line1, line2, sta) {
  607. if (!line1 || !line2) {
  608. console.log('线段未定义' + line1 + ' ' + line2);
  609. return null;
  610. }
  611. if (line1.length < 2 || line2.length < 2) {
  612. console.log('线段点坐标个数小于3, 请检查')
  613. return
  614. }
  615. if (sta === null || typeof sta === 'undefined') {
  616. sta = true;
  617. }
  618. // 根据sta值寻找当前线段与下一线段中符合要求的点
  619. for (let i = 0; i < line1.length; i++) {
  620. // sta为false, 寻找与下一线段都不相同的点
  621. if (!sta && sta === arrayEquals(line1[i], line2[0]) && sta === arrayEquals(line1[i], line2[1])) {
  622. return line1[i];
  623. }
  624. // sta为true, 寻找与下一线段相交的点
  625. if (sta && (sta === arrayEquals(line1[i], line2[0]) || sta === arrayEquals(line1[i], line2[1]))) {
  626. return line1[i];
  627. }
  628. }
  629. return null;
  630. }
  631. /**
  632. * 判断两个数组是否相等
  633. * @param {array} array1
  634. * @param {array} array2
  635. */
  636. function arrayEquals(array1, array2) {
  637. if (!array1 || !array2) {
  638. return false;
  639. }
  640. if (array1.length !== array2.length) {
  641. return false;
  642. }
  643. for (let i = 0, len = array1.length; i < len; i++) {
  644. if (array1[i] instanceof Array && array2[i] instanceof Array) {
  645. if (!equals(array1[i], array2[2])) {
  646. return false;
  647. }
  648. } else if (array1[i] !== array2[i]) {
  649. return false;
  650. }
  651. }
  652. return true;
  653. }
  654. /**
  655. * 判断一个数组中的元素是否都包含在另一个数组中
  656. * @param {array} arrays
  657. * @param {array} array2
  658. * @returns {boolean} true-表示数组元素唯一, false表示数组元素不唯一
  659. */
  660. function arrayOnly(array1, array2) {
  661. if(!array1 || !array2) {
  662. console.log('数组未定义, 请检查');
  663. return;
  664. }
  665. if(!array1.length || !array2.length || array1.length === 0) {
  666. return false;
  667. }
  668. for(let i = 0; i < array1.length; i++) {
  669. let num = 0;
  670. for(let j = 0; j < array1[i].length; j++) {
  671. if(array2.indexOf(array1[i][j]) >= 0) {
  672. // return false;
  673. num++;
  674. }
  675. }
  676. if(num === array1[i].length) {
  677. return true;
  678. }
  679. }
  680. return false;
  681. }
  682. function fix3dData(arr) {
  683. var ret = []
  684. var idxItem
  685. var idxArr = []
  686. for (var i = 0; i < arr.length; i++) {
  687. idxItem = []
  688. for (var j = 0; j < arr[i].length; j++) {
  689. ret.push(arr[i][j].points[0])
  690. idxItem.push(arr[i][j].id)
  691. }
  692. idxArr.push(idxItem)
  693. }
  694. // return idxArr;
  695. var r2x_t = [
  696. [-0.5, -0.5, +0.5],
  697. [-0.5, +0.5, +0.5],
  698. [+0.5, +0.5, +0.5],
  699. [+0.5, -0.5, +0.5],
  700. [-0.5, -0.5, -0.5],
  701. [-0.5, +0.5, -0.5],
  702. [+0.5, +0.5, -0.5],
  703. [+0.5, -0.5, -0.5]
  704. ];
  705. // 线段的坐标
  706. // z轴
  707. var r3x_t = [
  708. [0, 1],
  709. [1, 2],
  710. [2, 3],
  711. [3, 0],
  712. [4, 5],
  713. [5, 6],
  714. [6, 7],
  715. [7, 4],
  716. [0, 4],
  717. [1, 5],
  718. [2, 6],
  719. [3, 7]
  720. ];
  721. // 各个线段的坐标
  722. var ret_t = [
  723. ["", ""],
  724. ["", ""],
  725. ["", ""],
  726. ["", ""],
  727. ["", ""],
  728. ["", ""],
  729. ["", ""],
  730. ["", ""],
  731. ["", ""],
  732. ["", ""],
  733. ["", ""],
  734. ["", ""]
  735. ];
  736. }