OpenGL-贴纸方案
OpenGL-贴纸方案
普通贴纸(缩放、Z轴旋转、平移)
OpenGL环境说明
OpenGL渲染区域使用正交投影换算,正常OpenGL坐标是vertexData,这样的 Matrix.orthoM
进行换算
//顶点坐标(原点为显示区域中心店)private final float[] vertexData = {-1.0f, -1.0f, //左下角1.0f, -1.0f, //右下角-1.0f, 1.0f, //左上角1.0f, 1.0f, //右上角};
m_width=720;
m_height=1280Matrix.orthoM(matrix, 0, 0, m_width, m_height,0 , -1, 1);//坐标原点对应屏幕左上角private final float[] m_position = {0f, 0f,//左上角坐标720f,0f,///右上角坐标0f, 1280f, //左下角坐标720f, 1280f,//右下角坐标};
以上面的基础的渲染区域设置FBO的绘制区,进行贴纸绘制,对应的缩放、旋转、平移时候对矩阵的处理和顶点点位处理的方法说明m_position对应的是贴纸的坐标,m_materialRect对应的xy轴的坐标和宽高。
float[] m_materialRect={0f,0f,500f,500f};//x,y,w,h//坐标原点对应屏幕左上角private final float[] m_position = {0f, 0f,//左上角坐标500f, 0f,//右上角坐标0f, 500f, //左下角坐标500f, 500f,//右下角坐标};void processCommonRect() {if (m_locateType == Locate_Common_Rect && m_position) {float x = m_materialRect.origin.x * m_width;float y = m_materialRect.origin.y * m_height;Rect rect(x, y, m_materialRect.size.width, m_materialRect.size.height);m_matrix->identity();if (m_scale != 1.0f || (m_angle != 0.f && m_angle != 360.f)) {m_matrix->scale(m_scale);m_matrix->rotateZ(m_angle);// 纹理在屏幕上旋转,x 和 y 需要计算屏幕的比例,防止拉伸float screenRadio = m_height / m_width;float screenRadioFlip = 1.0f / screenRadio;float *m = (float *)m_matrix->get();m[0] *= screenRadio;m[4] *= screenRadio;m_matrix->scale(screenRadioFlip, 1, 1);if (m_offsetRect.size.width > 0 && m_offsetRect.size.height > 0) {float offsetX = m_offsetRect.origin.x - (0.5f - m_offsetRect.size.width / m_width * 0.5f);float offsetY = m_offsetRect.origin.y - (0.5f - m_offsetRect.size.height / m_height * 0.5f);rect.origin.x -= offsetX * m_width;rect.origin.y -= offsetY * m_height;m[12] = offsetX * 2.0f;m[13] = offsetY * 2.0f;} else {float centerX = (m_width - rect.size.width) * 0.5f;float centerY = (m_height - rect.size.height) * 0.5f;m[12] = (rect.origin.x - centerX) / m_width * 2.0f;m[13] = (rect.origin.y - centerY) / m_height * 2.0f;rect.origin.x = centerX;rect.origin.y = centerY;}}if(m_isCut){if(m_originalRect.size.width != 0 && m_originalRect.size.height != 0){m_texcoord[0].set(0, 0);if(1.0f*m_materialRect.size.width/m_originalRect.size.width < 1.0){m_texcoord[1].set(1.0f*m_materialRect.size.width/m_originalRect.size.width, 0);}else{m_texcoord[1].set(1.0,0);}m_texcoord[2].set(0, 1);if(1.0f*m_materialRect.size.width/m_originalRect.size.width < 1.0){m_texcoord[3].set(1.0f*m_materialRect.size.width/m_originalRect.size.width, 1);}else{m_texcoord[3].set(1.0, 1);}}else{m_texcoord[0].set(0, 0);m_texcoord[1].set(1, 0);m_texcoord[2].set(0, 1);m_texcoord[3].set(1, 1);}}m_position[0].set(rect.origin.x, rect.origin.y);m_position[1].set(rect.right(), rect.origin.y);m_position[2].set(rect.origin.x, rect.bottom());m_position[3].set(rect.right(), rect.bottom());}
}
代码解说:
float x = m_materialRect.origin.x * m_width;float y = m_materialRect.origin.y * m_height;Rect rect(x, y, m_materialRect.size.width, m_materialRect.size.height);
m_materialRect.origin.x和m_materialRect.origin.y分别是占m_width和m_height的比例,相乘就获取真实的x,y坐标值,然后保存到Rect。
m_matrix->identity();是矩阵的初始化, m_matrix->scale(m_scale);进行缩放, m_matrix->rotateZ(m_angle); 进行旋转.
// 纹理在屏幕上旋转,x 和 y 需要计算屏幕的比例,防止拉伸float screenRadio = m_height / m_width;float screenRadioFlip = 1.0f / screenRadio;float *m = (float *)m_matrix->get();m[0] *= screenRadio;m[4] *= screenRadio;m_matrix->scale(screenRadioFlip, 1, 1);
上面的代码是对进行缩放后的再按屏幕(720,1280)比例进行再次矫正,防止拉伸,实际上的操作 m[0] *= screenRadio*screenRadioFlip; m[4] *= screenRadio*screenRadioFlip; 如果不理解可以查看缩放矩阵和Z轴旋转矩阵相乘
float centerX = (m_width - rect.size.width) * 0.5f;float centerY = (m_height - rect.size.height) * 0.5f;m[12] = (rect.origin.x - centerX) / m_width * 2.0f;m[13] = (rect.origin.y - centerY) / m_height * 2.0f;rect.origin.x = centerX;rect.origin.y = centerY;
-
float centerX = (m_width - rect.size.width) * 0.5f;:计算屏幕宽度减去矩形宽度后的一半,以此确定矩形在 x 轴上居中的位置。 -
float centerY = (m_height - rect.size.height) * 0.5f;:计算屏幕高度减去矩形高度后的一半,以此确定矩形在 y 轴上居中的位置。 -
m[12] = (rect.origin.x - centerX) / m_width * 2.0f;:这行代码的目的是根据矩形左上角的 x 坐标相对于屏幕中心点的偏移量来计算 x 轴的位移量。以下是具体步骤:(rect.origin.x - centerX):计算矩形左上角 x 坐标和屏幕中心 x 坐标之间的偏移量。/ m_width:将得到的偏移量除以屏幕宽度,将其转换为比例,结果范围在 [-0.5, 0.5] 之间。* 2.0f:最后乘以 2.0,将比例倍增,确保偏移量适合矩阵的变换范围。而归一化后的[-0.5, 0.5]范围不太适合用于这些变换。通过乘以2,可以使得矩阵的位移调整更加明显和精确[-0.1, 0.1]
-
这样计算出的结果将会被存储在矩阵
m_matrix的第 12 个元素中,通常表示 x 轴的位移信息。
总的来说,这段代码用于根据矩形左上角与屏幕中心的偏移量,计算并设置矩阵的 x 方向位移,以便将矩形移动到屏幕的中心位置,从而实现在屏幕中心进行正确显示和定位。
Matrix4说明:
Matrix4& Matrix4::identity()
{m[0] = m[5] = m[10] = m[15] = 1.0f;m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;return *this;
}Matrix4& Matrix4::rotateZ(float angle)
{angle *= DEG2RAD;float c = cosf(angle);float s = sinf(angle);float m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3],m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7];m[0] = m0 * c + m4 *-s;m[1] = m1 * c + m5 *-s;m[2] = m2 * c + m6 *-s;m[3] = m3 * c + m7 *-s;m[4] = m0 * s + m4 * c;m[5] = m1 * s + m5 * c;m[6] = m2 * s + m6 * c;m[7] = m3 * s + m7 * c;return *this;
}Matrix4& Matrix4::scale(float s)
{return scale(s, s, s);
}Matrix4& Matrix4::scale(float x, float y, float z)
{m[0] = m[0]*x; m[1] = m[1]*x; m[2] = m[2]*x; m[3] = m[3]*x;m[4] = m[4]*y; m[5] = m[5]*y; m[6] = m[6]*y; m[7] = m[7]*y;m[8] = m[8]*z; m[9] = m[9]*z; m[10]= m[10]*z; m[11]= m[11]*z;return *this;
}
缩放转的矩阵等于:

沿Z轴旋转的矩阵等于:

计算重心坐标原理
已知三角形3顶点坐标A(x1,y1),B(x2,y2),C(x3,y3),求三角形ABC的面积的公式
写成一般形式如下:
设A(x1,y1),B(x2,y2),C(x3,y3)在坐标系中中顺序为三点按逆时针排列,对应的权重 ( weight1, weight2, weight3 )
weight1 + weight2 + weight3 = 1S=1/2[(x1y2-x2y1)+(x2y3-x3y2)+(x3y1-x1y3)]//分别计算三个点对总面积的贡献 这一步表示每个点在总面积中所占的比例。
S1 = S * weight1;
S2 = S * weight2;
S3 = S * weight3;
//计算加权平均的重心坐标 (xw, yw)xw = (S1 * x1 + S2 * x2 + S3 * x3) / S;yw = (S1 * y1 + S2 * y2 + S3 * y3) / S;

在重心坐标系中,三角形平面的任何一个点(x,y)都可以表示成三角形三个顶点的线性组合(系数分别是α β γ \alpha \beta \gammaαβγ,且满足这三个系数相加和为1)

获得三角形任意一点的重心坐标

人脸贴纸说明
1=weight1+weight2+weight3
p_index_1=44
weight1=-2.2564
p_index_2=38
weight2=1.6250
p_index_3=37
weight3=1.6314void processFace2DLocate()
{if (m_position == nullptr) {Rect rect = m_materialRect;rect.origin.x = (m_width - rect.size.width) * 0.5f;rect.origin.y = (m_height - rect.size.height) * 0.5f;// 更新数据int count = 4;m_position = new Vector2[count];m_position[0].set(rect.origin.x, rect.origin.y);m_position[1].set(rect.right(), rect.origin.y);m_position[2].set(rect.origin.x, rect.bottom());m_position[3].set(rect.right(), rect.bottom());m_texcoord = new Vector2[count];m_texcoord[0].set(0, 0);m_texcoord[1].set(1, 0);m_texcoord[2].set(0, 1);m_texcoord[3].set(1, 1);m_indexCount = 6;m_pointIndex = new unsigned short[m_indexCount]{0, 1, 2, 2, 1, 3};m_matrix = new Matrix4;}m_matrix->identity();Vector2* point106 = m_face->getPoint106();float screenRadio = m_height / m_width;float screenRadioFlip = 1.0f / screenRadio;float x_dis = std::fabs(point106[32].x - point106[0].x) * screenRadioFlip;float y_dis = std::fabs(point106[32].y - point106[0].y);// 标准人脸0\32之间的距离float standard_face_x = 475.0f / m_width;float standard_face_y = 0.0f;float scale = std::sqrt(x_dis * x_dis + y_dis * y_dis) / std::sqrt(standard_face_x * standard_face_x + standard_face_y * standard_face_y) * screenRadio;int index1 = m_2DLocateParam.p_index_1;float weight1 = m_2DLocateParam.p_weight_1;int index2 = m_2DLocateParam.p_index_2;float weight2 = m_2DLocateParam.p_weight_2;int index3 = m_2DLocateParam.p_index_3;float weight3 = m_2DLocateParam.p_weight_3;float _x1 = point106[index1].x;float _y1 = point106[index1].y;float _x2 = point106[index2].x;float _y2 = point106[index2].y;float _x3 = point106[index3].x;float _y3 = point106[index3].y;// 总面积float S = 0.5 * fabs((_x1 * _y2 - _x2 * _y1) + (_x2 * _y3 - _x3 * _y2) + (_x3 * _y1 - _x1 * _y3));// s_index1float S1 = S * weight1;// s_index2float S2 = S * weight2;// s_index3float S3 = S * weight3;float xw = (S1 * _x1 + S2 * _x2 + S3 * _x3) / S;float yw = (S1 * _y1 + S2 * _y2 + S3 * _y3) / S;m_matrix->scale(scale);m_matrix->rotate(m_face->getYaw() * 1.2, 0.0, 1.0, 0.0);m_matrix->rotate(m_face->getPitch() * 1.2, 1.0, 0.0, 0.0);m_matrix->rotate(m_face->getRoll(), 0.0, 0.0, 1.0);
// printf("m_face->getRoll() = %f, %f, %f\n", 360 + m_face->getRoll(), m_face->getPitch(), m_face->getYaw());// 纹理在屏幕上旋转,x 和 y 需要计算屏幕的比例,防止拉伸float *m = (float *)m_matrix->get();m[0] *= screenRadio;m[4] *= screenRadio;m_matrix->scale(screenRadioFlip, 1, 1);m[12] = xw * 2.f - 1.f;m[13] = yw * 2.f - 1.f;
}
m_matrix 进行旋转变换,根据人脸的偏航角(yaw)、俯仰角(pitch)和横摆角(roll)来调整姿态。让我给您解释一下:
-
m_matrix->rotate(m_face->getYaw() * 1.2, 0.0, 1.0, 0.0);- 这行代码根据人脸的偏航角(yaw)来进行绕 Y 轴旋转。
m_face->getYaw()是获取人脸的偏航角度,乘以1.2用于增加旋转幅度。- 参数
(0.0, 1.0, 0.0)表示围绕 Y 轴旋转。
-
m_matrix->rotate(m_face->getPitch() * 1.2, 1.0, 0.0, 0.0);- 这行代码根据人脸的俯仰角(pitch)来进行绕 X 轴旋转。
m_face->getPitch()是获取人脸的俯仰角度,乘以1.2用于增加旋转幅度。- 参数
(1.0, 0.0, 0.0)表示围绕 X 轴旋转。
-
m_matrix->rotate(m_face->getRoll(), 0.0, 0.0, 1.0);- 这行代码根据人脸的横摆角(roll)来进行绕 Z 轴旋转。
m_face->getRoll()是获取人脸的横摆角度。- 参数
(0.0, 0.0, 1.0)表示围绕 Z 轴旋转。

point106[32]和point106[0]分别是左右两边脸部两个点,下面代码为了计算脸部对屏幕上的缩放比例,std::sqrt(x_dis * x_dis + y_dis * y_dis) 计算了特征点索引为 0 和 32 之间的欧几里德距离。同时,std::sqrt(standard_face_x * standard_face_x + standard_face_y * standard_face_y) 则计算了标准人脸上 x 和 y 方向的长度与屏幕尺寸的比例之间的欧几里德距离。
float x_dis = std::fabs(point106[32].x - point106[0].x) * screenRadioFlip;float y_dis = std::fabs(point106[32].y - point106[0].y);// 标准人脸0\32之间的距离float standard_face_x = 475.0f / m_width;float standard_face_y = 0.0f;float scale = std::sqrt(x_dis * x_dis + y_dis * y_dis) / std::sqrt(standard_face_x * standard_face_x + standard_face_y * standard_face_y) * screenRadio;
重心坐标值(xw,yw)在[0, 1]范围转化为[-1, 1] 范围,这个顶点坐标标准
m[12] = xw * 2.f - 1.f;m[13] = yw * 2.f - 1.f;
相关文章:
OpenGL-贴纸方案
OpenGL-贴纸方案 普通贴纸(缩放、Z轴旋转、平移) OpenGL环境说明 OpenGL渲染区域使用正交投影换算,正常OpenGL坐标是vertexData,这样的 Matrix.orthoM 进行换算 //顶点坐标(原点为显示区域中心店)private final float[] vertex…...
【性能测试】移动测试md知识总结第1篇:移动端测试课程介绍【附代码文档】
移动测试完整教程(附代码资料)主要内容讲述:移动端测试课程介绍,移动端测试知识概览,移动端测试环境搭建,ADB常用命令学习主要内容,学习目标,学习目标,1. window安装andorid模拟器,学习目标。主流移动端自动…...
Vue2和vue3的区别(前端面试常见问题)
1.Api的变化:vue3使用组合式Api(compostion Api)和Vue2是选项式Api(options Api)。选项式Api具有data ,watch,methods,computed,一个个的模块。如果代码过多可读性会很差…...
openGauss学习笔记-241 openGauss性能调优-SQL调优-审视和修改表定义
文章目录 openGauss学习笔记-241 openGauss性能调优-SQL调优-审视和修改表定义241.1 审视和修改表定义概述241.2 选择存储模型241.3 使用局部聚簇241.4 使用分区表241.5 选择数据类型 openGauss学习笔记-241 openGauss性能调优-SQL调优-审视和修改表定义 241.1 审视和修改表定…...
PDFPlumber解析PDF文本报错:AssertionError: (‘Unhandled’, 6)
文章目录 1、问题描述2、问题原因3、问题解决 1、问题描述 今天在使用PDFPlumber模块提取PDF文本时extract_text()方法报错,报错内容如下: Traceback (most recent call last):......File "F:\Python\...\site-packages\pdfminer\pdffont.py"…...
51WORLD正式落地中东,助力沙特伙伴与客户数字化升级!
近日,在被誉为中东“数字达沃斯”的LEAP科技展上,51WORLD首次震撼亮相Digital Twin Riyadh2924k㎡ 全要素城市底座、数字地球平台51Earth,向中东及全球科技从业者展现中国企业技术实力与创新能力。此外,以LEAP为起点,5…...
嵌入式学习38-数据库
数据库软件: 关系型数据库: Mysql (开源) Oracle SqlServer Sqlite (小型数据) 非关系型数据库:(快速查找数据) Redis NoSQ…...
去除PDF论文行号的完美解决方案
去除PDF论文行号的完美解决方案 1. 遇到的问题 我想去除论文的行号,但是使用网上的Adobe Acrobat裁剪保存后 如何去掉pdf的行编号? - 知乎 (zhihu.com) 翻译时依然会出现行号,或者是转成word,这样就大大损失了格式,…...
《ElementPlus 与 ElementUI 差异集合》icon 图标使用(包含:el-button,el-input和el-dropdown 差异对比)
安装 注意 ElementPlus 的 Icon 图标 要额外安装插件 element-plus/icons-vue. npm install element-plus/icons-vue注册 全局注册 定义一个文件 element-icon.js ,注意代码第 6 行。加上了前缀 ElIcon ,避免组件命名重复,且易于理解为 e…...
力扣题库第8题:去重后的最长子串
题目: 给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2: 输入: s "bbbbb" …...
CSS样式中长度单位含义解析:rpx、px、vw、vh、em、rem、pt
在 CSS 样式中,有几种常见的长度单位,包括 rpx 、 px 、 vw 和 vh 等,含义解析如下: 1 . rpx (响应像素): 是微信小程序中的一种相对长度单位,可以根据屏幕宽度进行自适应缩放。 1rp…...
全国车辆识别代码信息API查询接口-VIN深度解析
我们先来介绍下什么是vin码,以及vin码的构成结构解析,汽车VIN码,也叫车辆识别号码,通俗可以理解为汽车的身份证号码。 VIN码一共分四大部分: 1~3位,是世界制造厂识别代号(WMI)&…...
python django 模型中字段设置blank, null属性值用法说明
问题1: ShareUser models.CharField(max_length128, blankTrue) blank设置True和false分别代表什么含义, 有什么区别?chatgpt回答的答案如下: 在 Django 模型字段中,blank 参数用于指定在创建对象时该字段是否可以为空值。它的含义如下: blankTrue:…...
暴雨信息:可持续转型更需要“以人为本”
数字化正在开启新的商业模式和价值流,为企业与组织带来巨大收益。其中,“人 (People)”这一因素至关重要。 提供更好的工作与生活体验,应对人口老龄化、劳动力短缺等挑战。对于企业而言,解决这些问题既是社会责任,也是…...
1.2_3 TCP/IP参考模型
文章目录 1.2_3 TCP/IP参考模型(一)OSI参考模型与TCP/IP参考模型(二)5层参考模型(三)5层参考模型的数据封装与解封装 1.2_3 TCP/IP参考模型 (一)OSI参考模型与TCP/IP参考模型 TCP/I…...
真空泵系统数据采集远程监控解决方案
行业背景 半导体制造业可以说是现代电子工业的核心产业,广泛应用于计算机、通信、汽车、医疗等领域。而在半导体生产加工过程中,如刻蚀、 镀膜、 扩散、沉积、退火等环节,真空泵都是必不可少的关键设备,它可以构建稳定受控的真空…...
Python语言在编程业界的地位——《跟老吕学Python编程》附录资料
Python语言在编程业界的地位——《跟老吕学Python编程》附录资料 ⭐️Python语言在编程业界的地位2024年3月编程语言排行榜(TIOBE前十) ⭐️Python开发语言开发环境介绍1.**IDLE**2.⭐️PyCharm3.**Anaconda**4.**Jupyter Notebook**5.**Sublime Text** …...
基于Redis自增实现全局ID生成器(详解)
本博客为个人学习笔记,学习网站与详细见:黑马程序员Redis入门到实战 P48 - P49 目录 全局ID生成器介绍 基于Redis自增实现全局ID 实现代码 全局ID生成器介绍 背景介绍 当用户在抢购商品时,就会生成订单并保存到数据库的某一张表中&#…...
hadoop 总结
1.hadoop 配置文件 core-site hdfs-site yarn-site.xml worker hdfs-site.xml <?xml version"1.0" encoding"UTF-8"?> <?xml-stylesheet type"text/xsl" href"configuration.xsl"?> <configuration><pr…...
luatos框架中LVGL如何使用中文字体〈二〉编写脚本设置中文字体
本节内容,将和大家一同学习,在luatos环境中,使用lvgl库,一步步的编译固件、编写脚本,最终实现中文字体的显示。 芯片:AIR101 LCD屏:ST7789 上一节,我们一同学习了,硬件引…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
