图形系统开发实战课程:进阶篇(上)——9.空间算法(一)


[

图形开发学院|GraphAnyWhere

  • 课程名称:图形系统开发实战课程:进阶篇(上)
  • 课程章节:“图形样式”
  • 原文地址:https://www.graphanywhere.com/graph/advanced/2-9.html

第九章 空间算法(一)

\quad 在图形开发过程中经常会使用到数学运算、坐标转换、空间算法等方面的功能,本章就来讲解一下anyGraph 所提供的一些工具类。

1. 数学工具类

\quad anyGraph 提供了 MathUtil 工具类,提供了一些常用的数学函数。

1.1 弧度和角度

\quad 角度是角的度量单位,它是指两条射线在圆周上形成的夹角的度数,通常使用度来表示。一个完整的圆有360度。弧度是一种度量角度的方法,是将圆周分为360等分,每一份的角度为1弧度。

\quad 弧度数/π=角度值/180°,其中π是一个常数,等于圆周率(约为3.14159265…)

因此:

  • 角度 = 弧度 * (180 / π)
  • 弧度 = 角度 / (180 / π)

\quad MathUtil 类提供了 toDegrees(angleInRadians)toRadians(angleInDegrees) 方法,实现弧度和角度相互转换,其源代码如下:

/**
 * 将弧度转换为度
 * @param {number} angleInRadians 以弧度为单位的角度
 * @return {number} 角度(以度为单位)
 */
function toDegrees(angleInRadians) {
    return (angleInRadians * 180) / Math.PI;
}

/**
 * 将度数转换为弧度
 * @param {number} angleInDegrees 以度为单位的角度
 * @return {number} 角度(弧度)
 */
function toRadians(angleInDegrees) {
    return (angleInDegrees * Math.PI) / 180;
}

1.2 生成随机数

\quad JavaScript 内置的 Math 对象提供了一个生成随机数的函数 random(),该函数返回一个浮点数,伪随机数在范围从0 到小于1。

\quad 实际在应用过程中,经常需要生成的是某个范围内的随机整数,因此 MathUtil 类提供了 getRandomNum(min, max) 方法,可生成大于等于 min 小于等于 max 的随机整数,其源代码如下:

/**
 * 获取min和Max之间的随机整数
 */
function getRandomNum(min, max) {
    let range = max - min;
    let rand = Math.random();
    return Math.floor(min + Math.round(rand * range));
}

1.3 返回指定小数位数的值

\quad 在 JavaScript 中,浮点运算的小数位是由计算机的浮点数表示方式决定的。JavaScript 使用 IEEE 754 标准来表示浮点数,其中包括单精度浮点数(32位)和双精度浮点数(64位)。单精度浮点数(32位)可以表示大约7位小数,而双精度浮点数(64位)可以表示大约15位小数。

\quad 实际在应用过程中,可能并不需要保留这么长的小数位数,因此 MathUtil 类提供了 toFixed(n, decimals) 方法,可返回指定小数位数的浮点数,如果不指定小数位数,则返回两位数的浮点数。其源代码如下:

/**
 * 返回一个小数位数有限的数字(四舍五入到指定的小数位数)
 * 例如:toFixed(10.465,2)的返回值为10.47, toFixed(10.995, 2)的返回值为11
 * @param {number} n The input number.
 * @param {number} decimals The maximum number of decimal digits.
 * @return {number} The input number with a limited number of decimal digits.
 */
function toFixed(n, decimals = 0) {
    const factor = Math.pow(10, decimals);
    return Math.round(n * factor) / factor;
}

1.4 线性差值

\quad 线性插值法是指使用连接两个已知量的直线来确定在这两个已知量之间的一个未知量的值的方法。

\quad 下面这张图是线性差值的一个示例,蓝色的两个点为已知量,中间橙色的点为根据系数计算出的未知量,系数的取值范围是 0 ~ 1

在这里插入图片描述

\quad MathUtil 类提供了 lerp(a, b, x) 方法,可返回指定系数的差值。

/**
 * 计算a和b之间的x的线性插值。
 * @param {number} a 开始值
 * @param {number} b 结束值
 * @param {number} x 插值系数.
 * @return {number} 插值.
 */
function lerp(a, b, x) {
    return a + x * (b - a);
}

该方法经常配合缓动函数使用。

1.5 返回指定范围内的数字

\quad MathUtil 类提供了 clamp(value, min, max) 方法,可返回指定范围内的数字。

/**
 * 获取指定范围内的数字
 * @param {number} value 数值.
 * @param {number} min 范围最小值.
 * @param {number} max 范围最大值.
 * @return {number} 指定范围内的数字,或与范围最接近的数字
 */
function clamp(value, min, max) {
    return Math.min(Math.max(value, min), max);
}

2. 测量工具类

\quad anyGraph 提供了 Measure 工具类,提供了一些常用的测量函数。

2.1 点与点之间的距离

\quad 点与点之间的距离,可使用勾股定理 a 2 + b 2 = c 2 a^2 + b^2 = c^2 a2+b2=c2 进行计算,其图示分解过程如下图所示:

在这里插入图片描述

其源代码如下:

/**
 * 返回点p1(x1,y1)和p2(x2,y2)之间距离的平方。
 * @param {Array} p1[x1, y1]
 * @param {Array} p2[x2, y2]
 * @return {number} Squared distance.
 */
static dist(p1, p2) {
    const dx = p2[0] - p1[0];
    const dy = p2[1] - p1[1];
    return Math.sqrt(dx * dx + dy * dy);
}

Math.sqrt() 方法为 javaScript内置的求一个数的平方根。

2.2 折线长度

\quad 点与点之间的距离,其实就是线段的长度,折线由多个线段组成,因此通过循环计算每一个线段的长度,即可计算出折线的长度。

/**
 * 计算折线长度
 * @param {Array} coords 折线点坐标数组
 */
static getLength(coords) {
    let length = 0;
    for (let i = 0; i < coords.length - 1; i++) {
        length += this.dist(coords[i], coords[i + 1]);
    }
    return length;
}

2.3 点与线之间的距离

\quad 计算点与线之间的距离,可先计算点到线段的垂足(垂足是指一个点,它与线段上的两个端点形成的两条线段互相垂直)。当垂足在线段上时,点与线之间的距离为坐标到线段上垂足的距离,当垂足在线段外部时,点与线之间的距离为点与离线段最近的线段坐标之间的距离。

/**
 * 返回点p[x,y]和线段(p1[x1,y1], p2[x2,y2])之间最接近距离。
 * @param {Array} p[x, y]
 * @param {Array} p1[x1, y1]
 * @param {Array} p2[x2, y2]
 * @return {number} distance.
 */
static distToSegment(p, p1, p2) {
    // 计算线段两端点的差值
    const dx = p2[0] - p1[0];
    const dy = p2[1] - p1[1];

    // 如果dx和dy都不等于0, p1p2是一个线段,否则p1p2为同一个点
    if (dx !== 0 || dy !== 0) {
        // 计算p到线段p1p2的垂足t
        const t = ((p[0] - p1[0]) * dx + (p[1] - p1[1]) * dy) / (dx * dx + dy * dy);
        if (t > 1) {
            // 如果t大于1,说明垂足在线段p1p2外,此时将p1设置为p2
            p1[0] = p2[0];
            p1[1] = p2[1];
        } else if (t > 0) {
            // 如果t大于0且小于等于1,说明垂足在线段p1p2上,此时将p1设置为垂足的坐标
            p1[0] += dx * t;
            p1[1] += dy * t;
        }
    }

    // 计算并返回两点之间的距离
    return this.dist(p, p1);
}

2.4 多边形面积

\quad 对于任意一个多边形,如果已知其各个顶点的坐标 A 1 ( x 1 , y 1 ) , A 2 ( x 2 , y 2 ) , ⋅ ⋅ ⋅ , A n ( x n , y n ) A_1(x_1,y_1), A_2(x_2,y_2), ···, A_n(x_n,y_n) A1(x1,y1),A2(x2,y2),⋅⋅⋅,An(xn,yn),那么这个多边形的面积为:
S = 1 2 ∑ i = 1 n ( x i y i + 1 − x i + 1 y i ) S = \frac{1}{2} \sum_{i=1}^n (x_iy_{i+1} - x_{i+1}y_i) S=21i=1n(xiyi+1xi+1yi)

\quad 其中 x n + 1 = x 1 , y n + 1 = y 1 x_{n+1} = x_1, y_{n+1} = y_1 xn+1=x1,yn+1=y1

\quad 算法原理参见:利用鞋带定理(Shoelace formula)求2D多边形面积

/**
 * 多边形计算面积
 * @param {Array} coords 多边形顶点坐标数组
 */
static getArea(coords) {
    // 多边形面积换算公式
    // S = Math.abs(0.5 * (x1 * y2 - y1 * x2 + x2 * y3 - y2 * x3 +….+ xn * y1 - yn * x1)));
    let area = 0;
    for (let i = 2; i < coords.length; i++) {
        let ax = coords[i - 1][0] - coords[0][0];
        let bx = coords[i - 1][1] - coords[0][1];
        let cx = coords[i][0] - coords[0][0];
        let dx = coords[i][1] - coords[0][1];
        // 三角形面积公式
        // S = 0.5 * (ax * dx - cx * bx);
        area += 0.5 * (ax * dx - cx * bx);
    };
    //顺时针为正,逆时针为负
    return Math.abs(area);
}

2.5 两点与X轴夹角的角度

\quad 两点连线与x轴的夹角(取旋转角)对应的tanθ三角函数值就是斜率,所以求出斜率,再用反三角函数计算即可。

\quad JavaScript中有一个函数Math.atan2(),返回从原点(0,0)到(x,y)点的线段与x轴正方向之间的平面角度(弧度值),也就是Math.atan2(y,x),该函数可通过斜率计算出角度。

\quad 计算公式如下:
t a n θ = ( y 2 − y 1 ) / ( x 2 − x 1 ) \qquad tanθ=(y2 - y1)/(x2 - x1) tanθ=(y2y1)/(x2x1)
θ = a t a n 2 ( ( y 2 − y 1 ) / ( x 2 − x 1 ) ) \qquad θ = atan2((y2-y1)/(x2-x1)) θ=atan2((y2y1)/(x2x1))

\quad 源代码如下:

/**
 * 计算两点与X轴夹角的角度
 * @param {*} p1
 * @param {*} p2
 * @returns
 */
static calcAngle(p1, p2) {
    return MathUtil.toFixed(MathUtil.toDegrees(Math.atan2(p2[1] - p1[1], p2[0] - p1[0])), 2);
}

3 坐标工具类

\quad 在第一章 基础知识 基础数学知识 中分别讲述了使用三角函数和矩阵变换两种方式实现坐标的平移、缩放、旋转等变换的数学知识,本节讲述 anyGraph 中使用三角函数实现坐标变换的具体实现。

\quad 这些方法封装到了 anyGraph 的工具类 Coordinate 中。

3.1 坐标平移

\quad 平移就是将一个向量(或者点)的 x 和 y 各自移动一段距离。将平移前的坐标(x,y)换算到平移后的新坐标( x ′ x^\prime x, y ′ y^\prime y)的等式如下:

x ′ = x + d x \qquad x^\prime = x + dx x=x+dx
y ′ = y + d y \qquad y^\prime = y + dy y=y+dy

/**
 * 坐标平移
 * @param {Array<Coord>} coords 坐标.
 * @param {number} deltaX x方向上的平移距离
 * @param {number} deltaY y方向上的平移距离
 * @return {Array<Coord>} 转换后的坐标.
 */
static translate(coords, deltaX, deltaY) {
    let dest = [];
    for (let j = 0; j < coords.length; j += 1) {
        dest[j] = [];
        dest[j][0] = coords[j][0] + deltaX;
        dest[j][1] = coords[j][1] + deltaY;
    }
    return dest;
}

3.2 基于原点坐标旋转

\quad 旋转是一种线性变换,是指将一个向量(或者点)的 x 和 y 绕着一个定点旋转一定的角度。将旋转前的坐标(x, y)换算到旋转后的新坐标( x ′ x^\prime x, y ′ y^\prime y)的等式需要用到以下几个三角函数:

  • 三角函数:
    c o s α = x / r = > x = r × c o s α cos \alpha = x / r => x = r \times cos \alpha cosα=x/r=>x=r×cosα
    s i n α = y / r = > y = r × s i n α sin \alpha = y / r => y = r \times sin \alpha sinα=y/r=>y=r×sinα

  • 三角恒等式中的两角和差公式:
    s i n ( α + θ ) = s i n α × c o s θ + c o s α × s i n θ sin(\alpha + \theta) = sin\alpha \times cos\theta + cos\alpha \times sin\theta sin(α+θ)=sinα×cosθ+cosα×sinθ
    c o s ( α + θ ) = c o s α × c o s θ − s i n α × s i n θ cos(\alpha + \theta) = cos\alpha \times cos\theta - sin\alpha \times sin\theta cos(α+θ)=cosα×cosθsinα×sinθ

根据三角函数,可知在旋转之前:

  • x = r × c o s α x = r \times cos \alpha x=r×cosα
  • y = r × s i n α y = r \times sin \alpha y=r×sinα

在旋转之后 r r r 是不变的,假设旋转角度为 θ \theta θ, 根据三角函数和三角恒等式可得出:

  • x ′ = r × c o s ( α + θ ) = r × c o s α × c o s θ − r × s i n α × s i n θ = x × c o s θ − y × s i n θ x^\prime = r \times cos(\alpha + \theta) = r \times cos \alpha \times cos \theta - r \times sin \alpha \times sin \theta = x \times cos\theta - y \times sin\theta x=r×cos(α+θ)=r×cosα×cosθr×sinα×sinθ=x×cosθy×sinθ
  • y ′ = r × c o s ( α + θ ) = r × c o s α × s i n θ + r × s i n α × c o s θ = y × c o s θ + x × s i n θ y^\prime = r \times cos(\alpha + \theta) = r \times cos \alpha \times sin \theta + r \times sin \alpha \times cos \theta = y \times cos\theta + x \times sin\theta y=r×cos(α+θ)=r×cosα×sinθ+r×sinα×cosθ=y×cosθ+x×sinθ

即:

  • x ′ = x × c o s θ − y × s i n θ x^\prime = x \times cos\theta - y \times sin\theta x=x×cosθy×sinθ
  • y ′ = y × c o s θ + x × s i n θ y^\prime = y \times cos\theta + x \times sin\theta y=y×cosθ+x×sinθ

因此,旋转的源代码如下:

/**
 * 基于原点坐标旋转
 * @param {Array<Coord>} coords 坐标
 * @param {number} angle 角度
 * @return {Array<Coord>} 转换后的坐标
 */
static rotate(coords, angle) {
    let cos = Math.cos(angle);
    let sin = Math.sin(angle);
    let dest = [];
    for (let j = 0; j < coords.length; j++) {
        let x = coords[j][0] * cos - coords[j][1] * sin;
        let y = coords[j][1] * cos + coords[j][0] * sin;
        dest.push([x, y]);
    }
    return dest;
}

3.3 基于锚点进行坐标旋转

\quad 基于锚点进行坐标旋转是一种组合变换,它包括了3个过程:

\quad 1. 将锚点坐标平移至原点;
\quad 2. 基于原点进行坐标旋转;
\quad 3. 将原点平移至锚点;

\quad 因此可在将基于原点坐标旋转的代码基础之上增加坐标平移的功能即可,其源代码如下:

/**
 * 基于锚点进行坐标旋转
 * @param {Array<Coord>} coords 坐标
 * @param {number} angle 角度
 * @param {Coord} anchor 锚点坐标
 * @return {Array<Coord>} 转换后的坐标
 */
static rotateByAnchor(coords, angle, anchor) {
    let cos = Math.cos(angle);
    let sin = Math.sin(angle);
    let anchorX = anchor[0];
    let anchorY = anchor[1];
    let dest = [];
    for (let j = 0; j < coords.length; j++) {
        let deltaX = coords[j][0] - anchorX;
        let deltaY = coords[j][1] - anchorY;
        dest.push([anchorX + deltaX * cos - deltaY * sin, anchorY + deltaX * sin + deltaY * cos]);
    }
    return dest;
}

3.4 基于原点进行坐标缩放

\quad 缩放是指将一个向量(或者点)的 x 和 y 各自进行指定比例的缩放。将缩放前的坐标(x, y)换算到缩放后的新坐标( x ′ x^\prime x, y ′ y^\prime y)的等式如下:

x ′ = x × s x \qquad x^\prime = x \times sx x=x×sx
y ′ = y × s y \qquad y^\prime = y \times sy y=y×sy

\quad 在这个等式中,坐标轴的横向缩放倍数记为sx,将原有x坐标乘以它,则可以得出新的横坐标;同时坐标轴的纵向缩放倍数记为sy,将原有y坐标乘以它,则可以得出新的纵坐标。

/**
 * 基于原点进行坐标缩放
 * @param {Array<Coord>} coords 坐标.
 * @param {number} sx x方向上的缩放比例
 * @param {number} sy y方向上的缩放比例
 * @return {Array<Coord>} 转换后的坐标.
 */
static scale(coords, sx, sy = sx) {
    let dest = [];
    for (let j = 0; j < coords.length; j++) {
        dest.push([coords[j][0] * sx, coords[j][1] * sy]);
    }
    return dest;
}

3.5 基于锚点进行坐标缩放

\quad 基于锚点进行坐标缩放是一种组合变换,它包括了3个过程:

\quad 1. 将锚点坐标平移至原点;
\quad 2. 基于原点进行坐标缩放
\quad 3. 将原点平移至锚点;

/**
 * 基于锚点进行坐标缩放
 * @param {Array<Coord>} coords 坐标.
 * @param {number} sx x方向上的缩放比例
 * @param {number} sy y方向上的缩放比例
 * @param {Array<Coord>} anchor Scale anchor point.
 * @return {Array<Coord>} 转换后的坐标.
 */
static scaleByAnchor(coords, sx, sy, anchor) {
    let dest = [];
    let anchorX = anchor[0];
    let anchorY = anchor[1];
    for (let j = 0; j < coords.length; j += 1) {
        let deltaX = coords[j][0] - anchorX;
        let deltaY = coords[j][1] - anchorY;
        dest[j] = [];
        dest[j][0] = anchorX + sx * deltaX;
        dest[j][1] = anchorY + sy * deltaY;
    }
    return dest;
}

3.6 坐标反向

\quad 坐标反向是对已有坐标值的数组或列表进行逆序操作,从而得到新的坐标数组。

/**
 * 坐标反转
 * @param {Array<Coord>} coords 
 * @returns {Array<Coord>} coords
 */
static reverse(coords) {
    let dest = [];
    for (let j = coords.length - 1; j >= 0; j -= 1) {
        dest.push(coords[j]);
    }
    return dest;
}

\quad “图形系统实战开发-进阶篇 第九章 空间算法(一)” 的内容讲解到这里就结束了,如果觉得对你有帮助有收获,可以关注我们的官方账号,持续关注更多精彩内容。

相关资料

▶ 系列教程及代码资料:https://GraphAnyWhere.com
▶ 图形系统开发实战课程:进阶篇(上)——前言
▶ 图形系统开发实战课程:进阶篇(上)——1.基础知识
▶ 图形系统开发实战课程:进阶篇(上)——2.图形管理类(Graph)
▶ 图形系统开发实战课程:进阶篇(上)——3.图层类(Layer)
▶ 图形系统开发实战课程:进阶篇(上)——4.图形基本形状
▶ 图形系统开发实战课程:进阶篇(上)——5.图形交互操作:平移和缩放
▶ 图形系统开发实战课程:进阶篇(上)——6.图形交互操作:拾取
▶ 图形系统开发实战课程:进阶篇(上)——7.图形交互操作: 视点控制与动画
▶ 图形系统开发实战课程:进阶篇(上)——8.图形样式


作者信息

作者 : 图形开发学院
CSDN: https://blog.csdn.net/2301_81340430?type=blog
官网:https://graphanywhere.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/428313.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机专业必看的十部电影

计算机专业必看的十部电影 1. 人工智能2. 黑客帝国3. 盗梦空间4. 社交网络5. Her6. 模仿游戏7. 斯诺登8. 头号玩家9. 暗网10. 网络迷踪 计算机专业必看的十部电影&#xff0c;就像一场精彩盛宴&#xff01; 《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力《模仿游戏…

小红关鸡(双指针)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K Special Judge, 64bit IO Format: %lld 题目描述 有nnn个鸡窝排成一排&a…

#WEB前端(CCS常用属性,补充span、div)

1.实验&#xff1a; 复合元素、行内元素、块内元素、行内块元素 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; span为行内元素&#xff1a;不可设置宽高&#xff0c;实际占用控件决定分布空间。 div为块内元素&#xff1a;占满整行&#xff0c;可以设置宽高 img为行内块元…

Windows 2012 设置 nginx 开机自启动(适用于windows2012/10)

Windows 2012 设置 nginx 开机自启动&#xff08;适用于windows2012/10&#xff09;https://www.cnblogs.com/xuegqcto/articles/7521483.html 在windows server 2012上安装nginx&#xff0c;同时配置开机自启动服务&#xff08;推荐使用“Windows Service Wrapper”工具&…

前后端分离项目服务器部署

文章目录 前言准备工作安装jdk1.8安装nginx安装库解压、编译nginx并安装nginx 命令测试nginx 安装mysql卸载mariadb用root用户登录系统&#xff0c;增加mysql用户和组准备数据目录初始化MySQL将mysql加入到服务中编辑配置文件&#xff0c;保存退出启动mysql配置环境变量设置开机…

20 个不同的 Python 函数实例

Python 是一种广泛使用的高级编程语言&#xff0c;其函数是 Python 编程中至关重要的概念之一。函数是一段可以重复使用的代码块&#xff0c;可以接收输入参数并返回输出结果。使用函数能够提高代码的可读性、可维护性和重用性。 基础知识 在 Python 中&#xff0c;函数使用关…

C语言初阶—数组

数组是一组相同类型元素的集合。 在C99标准之前&#xff0c;数组的大小必须是常量或常量表达式。 在C99标准之后&#xff0c;数组的大小可以是变量&#xff0c;可以支持变长数组&#xff0c;但变长数组不能初始化。 不完全初始化&#xff0c;剩余的元素默认初始化为0 。 数组访…

c++_leetcode_寻找峰值

目录 一、寻找峰值的示例 二、官方实现代码及解释 1、官方测试结果&#xff1a; 2、代码解释&#xff1a; 3、解题思路&#xff1a; 三、我的暴力解决 1、测试一&#xff1a; 2、测试二&#xff1a; 3、最终“暴力求解”代码&#xff1a; 4、官网提交测试通过&#xf…

终极排序(快排,归并,库函数)

一、快速排序 1、确定分界点&#xff1a;q [ l ] , q [ ( l r ) / 2 ] , q [ r ] ,或者其它区间之中的随机数。&#xff08;左 l 右 r &#xff09; 2、调整区间&#xff1a;&#xff08;较难理解的部分&#xff09; &#xff08;1&#xff09;、暴力做法 …

基于Siamese网络的zero-shot意图分类

原文地址&#xff1a;Zero-Shot Intent Classification with Siamese Networks 通过零样本意图分类有效定位域外意图 2021 年 9 月 24 日 意图识别是面向目标对话系统的一项重要任务。意图识别(有时也称为意图检测)是使用标签对每个用户话语进行分类的任务&#xff0c;该标签…

云手机的境外舆情监控应用——助力品牌公关

在当今数字化时代&#xff0c;社交媒体已成为品牌传播和互动的主要平台。随之而来的是海量的信息涌入&#xff0c;品牌需要及时了解并应对海外社交媒体上的舆情变化。本文将介绍如何通过云手机进行境外舆情监控&#xff0c;更好地帮助企业公关及时作出决策。 1. 境外舆情监控与…

图像实现曲面屏效果

图像实现曲面屏效果 双线性插值 双线性插值是一种常用的图像插值方法&#xff0c;用于在图像中两个相邻像素之间进行插值&#xff0c;以获取介于它们之间某个位置的像素值。在透视变换等情况下&#xff0c;由于原始图像的像素点与目标图像的像素点位置不完全重合&#xff0c;…

HTML入门:推荐1款免费好用的web开发工具

前言 你好&#xff0c;我是云桃桃。 在过去的 10 年里&#xff0c;我一直专注于 web 前端开发领域&#xff0c;积累了丰富的经验和知识。 所以&#xff0c;接下来&#xff0c;我会把自己所学所做给体系化输出&#xff0c;我将持续与你分享关于 HTML、CSS、JavaScript&#x…

yolov7添加spd-conv注意力机制

一、spd-conv是什么&#xff1f; SPD-Conv&#xff08;Symmetric Positive Definite Convolution&#xff09;是一种新颖的卷积操作&#xff0c;它主要应用于处理对称正定矩阵&#xff08;SPD&#xff09;数据。在传统的卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;…

天拓四方工业物联网网关在质量管理方面的应用

项目背景 某印刷企业为了提高产品质量和客户满意度&#xff0c;决定建立印刷质量追溯系统&#xff0c;以便对生产过程中的关键参数和产品质量进行追溯和管理。 应用方案 该企业选择了一款具备数据采集和传输功能的工业物联网网关&#xff0c;并与印刷机、切纸机等核心设备进…

【脑科学相关合集】有关脑影像数据相关介绍的笔记及有关脑网络的笔记合集

【脑科学相关合集】有关脑影像数据相关介绍的笔记及有关脑网络的笔记合集 前言脑模板方面相关笔记清单 基于脑网络的方法方面数据基本方面 前言 这里&#xff0c;我将展开有关我自己关于脑影像数据相关介绍的笔记及有关脑网络的笔记合集。其中&#xff0c;脑网络的相关论文主要…

MySQL篇—执行计划之覆盖索引Using index和条件过滤Using where介绍(第三篇,总共三篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…

vscode 本地/远程添加python解释器

文章目录 1. 背景2. 增加python解释器 1. 背景 我们在使用 vscode 去远程调试代码时&#xff0c;如果环境存在多个 Python 版本&#xff08;如用 conda 管理&#xff09;&#xff0c;没有选择正确的 Python 解释器会导致少包、库不适配等各种问题 2. 增加python解释器 windo…

kubernetes(k8s)集群超级详细超全安装部署手册

一、卸载k8s 针对机器已安装过k8s的情况&#xff0c;如未安装过&#xff0c;请忽略。 # 首先清理运行到k8s群集中的pod&#xff0c;使用 kubectl delete node --all# 使用脚本停止所有k8s服务 for service in kube-apiserver kube-controller-manager kubectl kubelet etcd k…

Linux的进程的概念

目录 1.冯诺依曼体系结构&#xff08;硬件&#xff09; 2.操作系统(软件) 2.1概念 2.2设计os(操作系统)的目的 2.3如何理解管理 2.4系统调用和库函数概念 3.进程 3.1基本概念 3.2描述进程-PCB和组织进程 3.3ps axj指令 3.4查看进程 3.5通过系统调用获取进程表示符(P…