123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- let faceAry = [];
- let keys = ['2d_point1', '2d_point2'];
- let lineKey = 'panorama_line_2d';
- let startPoint = [];
- let face = [];
- let negativeXVec = [-0.01, 0] // 以相同点为起点, 0.01为单位长度, 沿x轴负半轴求出单位向量
- let num = 0;
- let startLine = null;
- // rx1 = _3dLine(r2x, r3x, ret);
- var line_2d = _3dTo2d(
- make_matrix_from_quat([
- 0.008515,
- -0.014279,
- 0.016179,
- 0.999731,
- -5.438891,
- 2.167653,
- 0.165233
- ]),
- rx1,
- 0.05
- )['to3d']
- // console.log('====================================');
- // console.log('line_2d',line_2d);
- // console.log('====================================');
- /**
- * 寻找所有通过point相交的线段
- * @param {array} pointAry
- */
- function findIntersectLine() {
- let lineLen = line_2d.panorama_line_2d.length;
- console.time();
- // 对数组中的每条线段进行循环, 从第一个点开始
- for (let i = 0; i < lineLen; i++) {
- let curline = line_2d[lineKey][i];
- if (startLine && curline['3d_id'] === startLine['3d_id']) {
- continue;
- }
- // console.log(i);
- startLine = curline;
- let curPoint = startPoint = curline['2d_point1'];
- let nextPoint = null;
- let faceLine = [];
- while (true) {
- let data = find2dSamePoint(curPoint);
- let samePointNum = data.samePointNum; // 记录相同点的个数;
- let samePointLineAry = data.samePointLineAry; // 具有相同点的线段集合
- if (samePointNum === 1|| faceLine.length > 4) {
- // faceLine.indexOf(curline['3d_id']) < 0 && faceLine.push(curline['3d_id']); // 记录最后一条线段的3d_id
- // !arrayOnly(faceAry, faceLine) && faceAry.push(faceLine);
- // console.log(faceLine)
- break;
- }
- if (samePointNum === 2) { // 仅有两条线段相交于该点
- faceLine.indexOf(curline['3d_id']) < 0 && faceLine.push(curline['3d_id']);
- curline = findLineBesideTwoId(samePointLineAry, curline['2d_id']); // 寻找下一线段, 并设为当前线段
- // curPoint = curline['2d_point2']; // 下一线段终点
- curPoint = findNextPoint(curline, curPoint); // 查找线段中与当前点不同的另一端点
- // console.log(curline);
- if (arrayEquals(startPoint, curPoint)) { // 如果下一线段的终点为起始点, 则已形成闭环, 本次查找结束
- faceLine.indexOf(curline['3d_id']) < 0 && faceLine.push(curline['3d_id']); // 记录最后一条线段的3d_id
- !arrayOnly(faceAry, faceLine) && faceAry.push(faceLine);
- // console.log(faceLine)
- break;
- }
- }
- if (samePointNum >= 3) { // 有3条及3条以上的线段相交于该点
- let standardLine = findLineContainKey(samePointLineAry, curline['3d_id']); // 获取反向线段并作为基准线段
- let endPoint = findNextPoint(standardLine, curPoint); // 查找线段中与当前点不同的另一端点
- // if (arrayEquals(startPoint, curPoint)) { // 如果下一线段的终点为起始点, 则已形成闭环, 本次查找结束
- // faceLine.indexOf(curline['3d_id']) < 0 && faceLine.push(curline['3d_id']); // 记录最后一条线段的3d_id
- // console.log(faceLine)
- // break;
- // }
- let standardVec = getVector(standardLine, curPoint);
- let standardAngle = getAngle(negativeXVec, standardVec, standardLine);
- let positiveLines = findLineBesideKey(samePointLineAry, standardLine['3d_id']); // 获取正向线段的集合
- let min_s_c_angle = 500; // 最小的标准线与比较线夹角
- let rightLine = null; // 最右线段
- for (let j = 0; j < positiveLines.length; j++) { // 分别求出正向线段的向量
- let postiveVec = getVector(positiveLines[j], curPoint);
- let postiveAngle = getAngle(negativeXVec, postiveVec);
- if (standardAngle < postiveAngle) {
- // let s_c_angle = 360 - (postiveAngle - standardAngle);
- let s_c_angle = 360 - (postiveAngle - standardAngle);
- // 查找最大夹角并记录最右线段
- s_c_angle < min_s_c_angle && (min_s_c_angle = s_c_angle, rightLine = positiveLines[j]);
- }
- if (standardAngle > postiveAngle) {
- // let s_c_angle = 360 - (standardAngle - postiveAngle);
- let s_c_angle = standardAngle - postiveAngle;
- s_c_angle < min_s_c_angle && (min_s_c_angle = s_c_angle, rightLine = positiveLines[j]);
- }
- }
- faceLine.indexOf(rightLine['3d_id']) < 0 && faceLine.push(rightLine['3d_id']);
- curline = rightLine; // 寻找下一线段, 并设为当前线段
- // curPoint = curline['2d_point2']; // 下一线段终点
- curPoint = findNextPoint(curline, curPoint); // 查找线段中与当前点不同的另一端点
- // console.log(standardVec);
- // return;
- }
- }
- // num++;
- // console.log(num)
- // console.log(faceLine)
- // console.log(num)
- if (num === 500) {
- console.log(faceLine);
- return;
- }
- }
- console.log('faceAry',faceAry);
- console.timeEnd();
- }
- /**
- * 求两向量之间的夹角
- * @param {array} standardVec 标准向量
- * @param {array} comparativeVec 被比较向量
- * @param {object} comparativeLine 被比较线段, 用于判断线段属于第几象限
- */
- function getAngle(standardVec, comparativeVec, comparativeLine) {
- if (!standardVec || !comparativeVec) {
- console.log('standardVec或comparativeVec未定义, 请检查');
- return;
- }
- if (standardVec.length < 2 || comparativeVec.length < 2) {
- console.log('standardVec或comparativeVec长度小于2, 请检查');
- return;
- }
- let s_x = standardVec[0];
- let s_y = standardVec[1];
- let c_x = comparativeVec[0];
- let c_y = comparativeVec[1];
- // 求内积
- let productValue = s_x * c_x + s_y * c_y;
- // 求向量的模
- let vs_val = Math.sqrt(s_x * s_x + s_y * s_y);
- let vc_val = Math.sqrt(c_x * c_x + c_y * c_y);
- // 求两向量间的cos值
- let cos_val = productValue / (vs_val * vc_val);
- let minAngle = Math.acos(cos_val) * 180 / Math.PI; // 求出的是与x轴负半轴之间的最小夹角
- // console.log(angle);
- comparativeVec[1] < 0 && (minAngle = 360 - minAngle);
- return minAngle;
- }
- /**
- * 获取线段象限
- * @param {object} line
- * @returns {Boolean} true-表示正半轴, false-表示负半轴
- */
- function getQuadrant(line) {
- if (!line) {
- console.log('line未定义, 请检查');
- return;
- }
- (line.reversed = null || typeof line.reversed === 'undefined') && (line.reversed = false);
- if ((line.reversed && line[keys[0]][1] > line[keys[1]][1]) || (!line.reversed && line[keys[1]][1] > line[keys[0]][1])) { // 翻转, 为point1-point2
- return true; // true-表示正半轴
- }
- if ((line.reversed && line[keys[0]][1] < line[keys[1]][1]) || (!line.reversed && line[keys[1]][1] < line[keys[0]][1])) {
- return false; // false-表示负半轴
- }
- }
- /**
- * 根据标准线段, 比较线段所处的象限来翻转角度(即360 - 最小angle)
- * @param {object} standardLine 标准线段
- * @param {object} comparativeLine 比较线段
- * @param {array} samePoint 相同点
- */
- function angleReverse(standardLine, comparativeLine, samePoint) {
- let origin_x = samePoint[0]; // 取相同点作为原点
- let origin_y = samePoint[1];
- let s_x = standardLine[keys[0]][0]; // 标准线段的终点是point1
- let s_y = standardLine[keys[0]][1];
- let c_x = comparativeLine[keys[1]][0]; // 比较线段的终点是point2
- let c_y = comparativeLine[keys[1]][1];
- // 标准线段位于第一象限, 或位于x轴负半轴
- if ((s_x < origin_x && s_y < origin_y) || (s_x < origin_x && s_y === origin_y)) {
- // 比较线段位于第一象限标准线的上方, 或位于第二象限, 或位于第三象限-s_y的上面
- if (c_y > s_y || (c_x > origin_x) || (c_x > origin_x && c_y > -s_y)) {
- return false; // 不用进行角度翻转
- }
- return true;
- }
- }
- /**
- * 根据相同点samePoint在线段中的位置来求对应的向量
- * @param {object} line
- * @param {array} samePoint
- */
- function getVector(line, samePoint) {
- if (!line) {
- console.log('line未定义, 请检查');
- return;
- }
- if (!samePoint || samePoint.length < 2) {
- console.log('samePoint未定义或长度小于2, 请检查');
- return;
- }
- for (let i = 0; i < keys.length; i++) {
- let key = keys[i];
- // 相同点是线段的第一个点, 则 point2 - point1 为该线段向量
- if (key === keys[0] && arrayEquals(line[key], samePoint)) {
- let vec_x = line[keys[1]][0] - line[keys[0]][0];
- let vec_y = line[keys[1]][1] - line[keys[0]][1];
- let vec = [vec_x, vec_y];
- line['vector2'] = vec;
- return vec;
- }
- // 相同点是线段的第二个点, 则 point1 - point2 为该线段向量
- if (key === keys[1] && arrayEquals(line[key], samePoint)) {
- let vec_x = line[keys[0]][0] - line[keys[1]][0];
- let vec_y = line[keys[0]][1] - line[keys[1]][1];
- let vec = [vec_x, vec_y];
- line['vector2'] = vec;
- return vec;
- }
- }
- }
- /**
- * 查找线段除point外的另一定点
- * @param {object} line
- * @param {array} point
- */
- function findNextPoint(line, point) {
- for (let i = 0; i < keys.length; i++) {
- if (!arrayEquals(line[keys[i]], point)) {
- return line[keys[i]];
- }
- }
- }
- /**
- * 仅有两个相同点的情况下调用, 查找含指定twoId之外的线段
- * @param {*} lineAry
- * @param {*} twoDId
- */
- function findLineBesideTwoId(lineAry, twoDId) {
- if (!lineAry) {
- console.log('lineAry未定义, 请检查');
- return null;
- }
- if (typeof twoDId !== 'number') {
- console.log('threeDId未定义, 请检查');
- return null;
- }
- for (let i = 0; i < lineAry.length; i++) {
- if (lineAry[i]['2d_id'] !== twoDId) {
- return lineAry[i];
- }
- }
- }
- /**
- * 在集合中寻找除了含threeDId之外的其他线段
- * @param {array} lineAry 线段集合
- * @param {number} threeDId 表示寻找正向还是反向线段
- */
- function findLineBesideKey(lineAry, threeDId) {
- if (!lineAry) {
- console.log('lineAry未定义, 请检查');
- return null;
- }
- if (typeof threeDId !== 'number') {
- console.log('threeDId未定义, 请检查');
- return null;
- }
- let positiveLines = [];
- for (let i = 0; i < lineAry.length; i++) {
- if (lineAry[i]['3d_id'] === threeDId) {
- continue;
- } else {
- positiveLines.push(lineAry[i]);
- }
- // if (reversed && lineAry[i].reversed === reversed) {
- // return lineAry[i];
- // }
- // if (!reversed && lineAry[i].reversed === reversed) {
- // positiveLines.push(lineAry[i]);
- // }
- }
- return positiveLines;
- }
- /**
- * 在集合中查找含有threeDId的线段
- * @param {array} lineAry 线段集合
- * @param {number} threeDId
- */
- function findLineContainKey(lineAry, threeDId) {
- if (!lineAry) {
- console.log('lineAry未定义, 请检查');
- return null;
- }
- if (typeof threeDId !== 'number') {
- console.log('threeDId未定义, 请检查');
- return null;
- }
- for (let i = 0; i < lineAry.length; i++) {
- if (lineAry[i]['3d_id'] === threeDId) {
- return lineAry[i];
- }
- }
- }
- /**
- * 寻找2D线段中的相同点
- * @param {array} curPoint 寻找与该点相交的其他点
- */
- function find2dSamePoint(curPoint) {
- let lineLen = line_2d.panorama_line_2d.length;
- let samePointNum = 0; // 记录相同点的个数;
- let samePointLineAry = []; // 具有相同点的线段集合
- // 对于指定点, 在集合的所有线段中寻找相同点
- for (let j = 0; j < lineLen; j++) {
- let comparativeLine = line_2d[lineKey][j];
- // 在线段中的两个点中寻找是否有相同点
- for (let k = 0; k < keys.length; k++) {
- let key = keys[k]
- if (arrayEquals(comparativeLine[key], curPoint)) {
- key === keys[0] ? comparativeLine.reversed = false : comparativeLine.reversed = true;
- samePointNum++;
- samePointLineAry.push(comparativeLine); // 记录具有相同点的线段
- }
- }
- }
- return {
- samePointNum: samePointNum,
- samePointLineAry: samePointLineAry
- }
- }
|