util.js 22 KB

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