util.js 20 KB

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