回顾:项目中遇到的坐标转换与计算

这篇博客介绍了在SVG坐标系统中进行图形处理时的一些关键数学算法,包括两点间距离、角度计算、点到直线距离、垂直交点、线段交点判断、旋转坐标以及线段长度调整等。这些算法对于精确地操作SVG图形元素至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

公式适用于svg,坐标原点在左上角

1. 两点之间距离计算

  • 勾股定理
function radius(a, b, c, d) { //(a,b)(c,d)
   	var row = Math.pow(a - c, 2)
    var col = Math.pow(b - d, 2)
    return Math.sqrt(row + col)
}

2. 两点之间角度计算

  • 三角函数 atan
function angle(a, b, c, d) {
	var diff_x = a - c;
    var diff_y = b - d;
    //返回角度,不是弧度
    return 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI)
}

3. 点c到含有(a,b)两点的直线的距离

|A0x+B0y+C|/√(A²+B²)

function distance(a, b, c) {
     var k0 = (b.y - a.y) / (b.x - a.x) //1.求ab斜率
     var e = (b.y - k0 * b.x) //2.根据y=kx+e,已知k,求得e
     var fenmu = k0 * c.x - c.y + e  //3.公式的分母
     var fenzi = Math.pow(k0, 2) + 1 //4.公式的分子  y=kx+e  即A为K ,B为-1
     if (a.x == b.x) {//水平线
         return Math.abs(c.x - a.x)
     } else {
         return Math.abs(fenmu / Math.sqrt(fenzi))
     }
 }

4. 点c与含有(a,b)两点的直线的垂直交点

function point(a, b, c) {
    var k0 = (b.y - a.y) / (b.x - a.x)//1.求ab斜率
    var e = (b.y - k0 * b.x)//2.根据ab斜率,y=kx+e,求出e
    var k1 = -1 / k0 //3.垂直斜率相乘为-1,求出c点斜率
    var e1 = c.y - k1 * c.x //4.求出c点e
    var x = (e1 - e) / (k0 - k1) //5.交点y相同 k0x+e = k1x +e ,求出交点x 
    var y = k0 * x + e // 6.求出交点y
    if (a.x == b.x) { // 是否水平线
        return { x: a.x, y: c.y }
    } else if (a.y == b.y) { // 是否垂线
        return { x: c.x, y: a.y }
    } else {
        return { x: x, y: y }
    }
}

5. a,b两点所在线段与c,d两点所在线段的交点(前提条件:必相交[即只能有一条线斜率不存在],且c,d两点所在线段为垂线或水平线)

项目计算cd与ab交点,主要用于处理尾点在ab附近时吸附到ab上

function  line(a, b, c, d) {
    if (c.x == d.x) { //第二条线斜率不存在[垂直](即第一条斜率存在)
        var k0 = (b.y - a.y) / (b.x - a.x)
        var e = (b.y - k0 * b.x)
        return { x: c.x * 1, y: k0 * c.x + e }
    } else { //第二条线斜率存在[水平]
        if (a.x == b.x) { //第一条线斜率不存在
            return { x: a.x, y: c.y }
        } else { //第一条线斜率存在
            var k1 = (b.y - a.y) / (b.x - a.x)
            var e1 = (b.y - k1 * b.x)
            return { x: (c.y - e1) / k1, y: c.y }
        }
    }
}

6. a,b两点所在线段与c,d两点所在线段是否相交(即非平行)

  • 项目中绘制垂线|水平线时,判断是否相交,是否需要 计算交点
function isIntersect(a, b, c, d) {
    if ((a.x == b.x) && (c.x == d.x)) { //斜率不存在时
        return false;
    }
    var firstK = (a.y - b.y) / (a.x - b.x)
    var lastK = (c.y - d.y) / (c.x - d.x)
    if (firstK == lastK) { //斜率存在时
        return false;
    } else {
        return true;
    }
}

7.尾点围绕起点,旋转后angleGet度后,求尾点坐标。

  • 特殊化求解
    在这里插入图片描述
    假设angleGet不为90度。A为起点,B为尾点,绕A旋转到C
    1.已知 AB,求AB距离,AB等于AC
    2.已知角度,可得正切,既而得正割.
    3.根据正割和AC,可以得出AD
    4.根据正切和AC可得出DC
    6.C的横坐标为 A的横坐标+AD,纵坐标为A的纵坐标+DC(在svg里坐标原点在左上角)
    7.当起点在尾点的右侧时,则减
function changeDirection(angleGet) {
    var start = { x: $('line').eq($('line').length - 1).attr('x1'), y: $('line').eq($('line').length - 1).attr('y1') }
    var stop = { x: $('line').eq($('line').length - 1).attr('x2'), y: $('line').eq($('line').length - 1).attr('y2') }
    var row1 = Math.pow(stop.x - start.x, 2)
    var col1 = Math.pow(stop.y - start.y, 2)
    var c = Math.sqrt(row1 + col1) //两点长
    if (Number(angleGet) != 90) { //tan90不存在
        var d1 = Math.tan(angleGet * (2 * Math.PI / 360))// angleGet对应的弧度 求得正切值
        var d = Math.pow(d1, 2) + 1
        var e = Math.sqrt(d)// 正切的平方+1 = 正割的平方 ,求得正割 = 邻边/斜边
        var f = c / e  
        var g = Number(start.x) + Number(f)
        var l = Number(start.x) - Number(f)
        var h = Number(start.y) + Number(d1 * f)
        var i = Number(start.y) - Number(d1 * f)
        if (Number(start.x) <= Number(stop.x)) {//尾点在起点左边
            return { x: g, y: h }
        } else if (Number(start.x) > Number(stop.x)) {//尾点在起点右边
            return { x: l, y: i }
        }
    } else {
        if (Number(start.x) <= Number(stop.x)) {
            return { x: start.x, y: Number(start.y) + Number(c) }
        } else if (Number(start.x) > Number(stop.x)) {
            return { x: start.x, y: Number(start.y) - Number(c) }
        }
    }
}

8.已知起点和尾点,改变线段长度后,求尾点坐标

在这里插入图片描述
假如AB不为垂线的话,A为起点,B为尾点,延迟AB长度后,B变为C点,求C坐标
1.求AB斜率,斜率即正切,既而得到正割
2.已知AC距离,根据正割,得到C点相对A的横坐标
3.根据正切,和C点相对A的横坐标,得到C点相对A的纵坐标
4.起点在尾点左边,则加,右边则减
最后,考虑AB为垂线的情况

function changeLong(longGet) {
   	 var start = { x: $('line').eq($('line').length - 1).attr('x1'), y: $('line').eq($('line').length - 1).attr('y1') }
     var stop = { x: $('line').eq($('line').length - 1).attr('x2'), y: $('line').eq($('line').length - 1).attr('y2') }
     var k = (stop.y - start.y) / (stop.x - start.x)  //1.求斜率
     var e = Math.pow(k, 2) + 1  //2.斜率即是正切,根据公式得到正割
     var c = Math.sqrt(e)
     var f = longGet / c  3.根据正割得到邻边长度
     var g = Number(start.x) + Number(f)
     var l = Number(start.x) - Number(f)
     var h = Number(start.y) + Number(k * f)
     var i = Number(start.y) - Number(k * f)
     if (Number(stop.x) != Number(start.x)) {
         if (Number(start.x) < Number(stop.x)) {
             return { x: g, y: h }
         } else if (Number(start.x) > Number(stop.x)) {
             return { x: l, y: i }
         }
     } else {
         return { x: start.x, y: Number(start.y) + Number(longGet) }
     }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值