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
    }
}