求两条直线的交点坐标
求交点坐标方法(涉及求线段交点的几何计算)
参考:谈谈"求线段交点"的几种算法(js实现,完整版)

/*** 顺序无关,ab,cd为线段* @param {*} a 线段ab起点坐标* @param {*} b 线段ab终点坐标* @param {*} c 线段cd起点坐标* @param {*} d 线段ab终点坐标*/function segmentsIntr(a, b, c, d) {// 三角形abc 面积的2倍const area_abc = (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);// 三角形abd 面积的2倍const area_abd = (a.x - d.x) * (b.y - d.y) - (a.y - d.y) * (b.x - d.x);// 面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理(==0则对点));// 对点也当作相交则 > 0 即可if (area_abc * area_abd > 0) {return false;}// 三角形cda 面积的2倍const area_cda = (c.x - a.x) * (d.y - a.y) - (c.y - a.y) * (d.x - a.x);// 三角形cdb 面积的2倍// 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出.const area_cdb = area_cda + area_abc - area_abd;if (area_cda * area_cdb > 0) {return false;}// 计算交点坐标const t = area_cda / (area_abd - area_abc);// eslint-disable-next-line one-varconst dx = t * (b.x - a.x),dy = t * (b.y - a.y);// const x = Math.trunc(a.x + dx);const x = +(a.x + dx).toFixed(2);const y = +(a.y + dy).toFixed(2);return { x, y };}// 平行
const a = { x: 10, y: 20 };
const b = { x: 40, y: 20 };
const c = { x: 10, y: 20 };
const d = { x: 40, y: 40 };
// 一个点相同
const a1 = { x: 10, y: 20 };
const b1 = { x: 40, y: 20 };
const c1 = { x: 10, y: 20 };
const d1 = { x: 40, y: 40 };
// 没有点相同
const a2 = { x: 10, y: 20 };
const b2 = { x: 40, y: 40 };
const c2 = { x: 10, y: 50 };
const d2 = { x: 40, y: 30 };
const test = segmentsIntr2(a1, b1, c1, d1);
console.log(test);
结合折线图获取坐标的方法:
计算两条折线图的交点坐标,假设折线图仅有一个交点的情况,先求出x轴上y的位置差最小(绝对值)的坐标,再分别拿前一个节点(交点在左侧),求出坐标,如果没有求出,则取下一个节点进行计算(交点在右侧)
// 折线图mock数据
const list1 = [{ legend: '比较便宜', percent: 100, price: 50 },{ legend: '比较便宜', percent: 100, price: 75 },{ legend: '比较便宜', percent: 100, price: 100 },{ legend: '比较便宜', percent: 83.33, price: 125 },{ legend: '比较便宜', percent: 33.33, price: 150 },{ legend: '比较便宜', percent: 16.67, price: 175 },{ legend: '比较便宜', percent: 16.67, price: 200 },{ legend: '比较便宜', percent: 16.67, price: 225 }
];
const list2 = [{ legend: '非常贵', percent: 0, price: 50 },{ legend: '非常贵', percent: 0, price: 75 },{ legend: '非常贵', percent: 0, price: 100 },{ legend: '非常贵', percent: 16.67, price: 125 },{ legend: '非常贵', percent: 50, price: 150 },{ legend: '非常贵', percent: 66.67, price: 175 },{ legend: '非常贵', percent: 66.67, price: 200 },{ legend: '非常贵', percent: 100, price: 225 }
]
function getCoordinate(list1, list2, type) {const arr = [];// const index = 0;list1.forEach((element, index) => {const value = Math.abs(element.percent - list2[index].percent);arr.push(value);});const min = Math.min(...arr);const index = arr.findIndex(item => item === min);const a = { x: list1[index].price, y: list1[index].percent };const b =type === 'prev'? { x: list1[index - 1].price, y: list1[index - 1].percent }: { x: list1[index + 1].price, y: list1[index + 1].percent };const c = { x: list2[index].price, y: list2[index].percent };const d =type === 'prev'? { x: list2[index - 1].price, y: list2[index - 1].percent }: { x: list2[index + 1].price, y: list2[index + 1].percent };// console.log(arr, index, min, a, b, c, d);return [a, b, c, d];
}const abcdPrev = getCoordinate(list1, list2, 'prev');
const abcdNext = getCoordinate(list1, list2, 'next');
const p = segmentsIntr(...abcdPrev) || segmentsIntr(...abcdNext);console.log(abcdPrev, abcdNext, p);
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
