Unity Image - 镜像

1、为什么要使用镜像

在游戏开发过程中,我们经常会为了节省 美术图片资源大小,美术会将两边相同的图片进行切一半来处理。如下所示一个按钮 需要 400 * 236,然而美术只需要切一张 74*236的大小就可以了。这样一来图集就可以容纳更多的图片。内存占用也更少。

2.实现方案

  1. 拷贝一张图片,然后把 scale改成-1,这种方法比较笨,需要多加一张图片,操作起来也很不方便。没啥好讲的。
  2. 拷贝原有的图片顶点,进行对称处理。如下图所示。

3.在哪里拿到mesh顶点?修改顶点?

BaseMeshEffect :是用于实现网格效果的抽象类实现IMeshModifier接口,是Shadow、Outline等效果的基类。
从Unity uGUI原理解析-Graphic可以知道,Graphic 在执行 DoMeshGeneration 时会获取到当前GameObject上的所有实现 IMeshModifier 的组件。 并且会调用 ModifyMesh 方法来修改当前Graphic 的Mesh数据。BaseMeshEffect 的类结构图如下:

我们编写一个MirrorImage来继承BaseMeshEffect,拿到 VertexHelper,获取网格的顶点流数据,然后进行下面的镜像,映射操作:

using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.UI;public enum MirrorType
{Horizontal,Vertical,HorizontalAndVertical
}[RequireComponent(typeof(Image))]
public class MirrorImage : BaseMeshEffect
{public MirrorType mirrorType = MirrorType.Horizontal;public Dictionary<Image.Type, IMirror> MirrorDic = new Dictionary<Image.Type, IMirror>(){{Image.Type.Simple, new SimpleMirror()},{Image.Type.Sliced, new SlicedMirror()},{Image.Type.Tiled, new TiledMirror()},{Image.Type.Filled, new FilledMirror()},};public Image image => graphic as Image;public override void ModifyMesh(VertexHelper vh){if (!IsActive()) return;Image.Type imageType = (graphic as Image).type;List<UIVertex> vertices = new List<UIVertex>();vh.GetUIVertexStream(vertices);vh.Clear();MirrorDic[imageType].Draw(image, vertices, mirrorType);vh.AddUIVertexTriangleStream(vertices);}[Button("Set Native Size")]public void SetNativeSize(){if (image.sprite != null){float w = image.sprite.rect.width / image.pixelsPerUnit;float h = image.sprite.rect.height / image.pixelsPerUnit;image.rectTransform.anchorMax = image.rectTransform.anchorMin;float x = mirrorType == MirrorType.Horizontal || mirrorType == MirrorType.HorizontalAndVertical ? 2 : 1;float y = mirrorType == MirrorType.Vertical || mirrorType == MirrorType.HorizontalAndVertical ? 2 : 1;image.rectTransform.sizeDelta = new Vector2(w * x, h * y);image.SetAllDirty();}}
}

当然除了继承BaseMeshEffect,当然还可以直接继承Image,重写OnPopulateMesh。

4.如何实现顶点的镜像?

很简单 假设中心的是 center( 0,0),需要水平镜像的点 A(-1,0) 镜像后的点就是 B(-1,0)需要满足   A 到Center的距离 == B到center的距离:

所以我们先求出镜像的中心点 center的位置 ,因为矩形有自己的中心点位置,我们需要求出镜像的中心点位置在改矩形下的坐标,这么说可能有点绕看下图:

矩形的宽w:100,h:100,矩形自身的中心点(蓝色的圈) 这边为称为O点,在Unity中是以  Rect中的 x,y代表的是坐下角的点 既 (-75,-50),

对于Rect(x,y) 不理解的话可以看下GPT的回答,可能比我讲的清楚:

那么镜像真正的中心点坐标

  • center.x = rect.x + rect.width;
  • center.y = rect.y + rect.height;

那么要镜像的点 A 镜像后为B   ,需要求出A到center的长度大小然后取反 + 矩形中心点与镜像中心点的偏移

B.x = -(A.x - center.x) + (rect.x+rect.width/2)

B.y = -(A.y - center.y) + (rect.x+rect.width/2)

逻辑分析完了,直接看代码吧:


using System.Collections.Generic;
using UnityEngine;public static class MirrorUtlis
{public static void Mirror(Rect rect,List<UIVertex> uiVertices,MirrorType type){int count = uiVertices.Count;switch (type){case MirrorType.Horizontal:Mirror(rect, uiVertices, type, count);break;case MirrorType.Vertical:Mirror(rect, uiVertices, type, count);break;case MirrorType.HorizontalAndVertical:Mirror(rect, uiVertices, MirrorType.Horizontal, count);Mirror(rect, uiVertices, MirrorType.Vertical, 2 * count);break;}RemoveVertices(uiVertices);}private static void Mirror(Rect rect, List<UIVertex> uiVertices, MirrorType type, int count){for (int i = 0; i < count; i++){UIVertex vertex = uiVertices[i];switch (type){case MirrorType.Horizontal:vertex = HorizontalMirror(rect, vertex);break;case MirrorType.Vertical:vertex = VerticalMirror(rect, vertex);break;case MirrorType.HorizontalAndVertical:vertex = HorizontalMirror(rect, vertex);vertex = VerticalMirror(rect, vertex);break;}uiVertices.Add(vertex);}}private static UIVertex HorizontalMirror(Rect rect, UIVertex vertex){float center = rect.width / 2 + rect.x;vertex.position.x = -(vertex.position.x - center) + rect.x + rect.width/2;return vertex;}private static UIVertex VerticalMirror(Rect rect, UIVertex vertex){float center = rect.height / 2 + rect.y;vertex.position.y = -(vertex.position.y - center) + rect.y + rect.height/2;return vertex;}// 移除构不成三角形的顶点private static void RemoveVertices(List<UIVertex> uiVertices){int end = uiVertices.Count;for (int i = 2; i < end; i += 3){UIVertex v1 = uiVertices[i];UIVertex v2 = uiVertices[i - 1];UIVertex v3 = uiVertices[i - 2];if (v1.position == v2.position ||v1.position == v3.position ||v2.position == v3.position){// 移动到尾部ChaneVertices(uiVertices, i - 1, end - 3);ChaneVertices(uiVertices, i - 2, end - 2);ChaneVertices(uiVertices, i, end - 1);end -= 3;}}if(end < uiVertices.Count)uiVertices.RemoveRange(end,uiVertices.Count - end);}private static void ChaneVertices(List<UIVertex> uiVertices,int a,int b){(uiVertices[a], uiVertices[b]) = (uiVertices[b], uiVertices[a]);}
}

在顶点镜像前我们需要对顶点进行顶点映射,什么时时映射?

如上图所示,原来图片是白色区域大小,顶点为白色图片的四个顶点,因为要做对称,所以需要留出一半的位置来增加映射后的顶点。

在不同模式下的顶点映射需要做不同处理,在Unity中有一下几种模式:

  • Simple: 如上面的图所示,对顶点的位置 除以 2 即可比较简单
  • Sliced:九宫格模式下因为要保留九宫格的顶点位置,不能让九宫格保留的位置发生形变,就不能直接除以2来处理,需要做平移处理。具体实现下面在讲
  • Filed:平铺模式下是不需要在镜像网格顶点的,因为平铺下的图片顶点是已经增加好的了,我们只需要对UV做镜像就可以了
  • Filled:暂时未实现该模式下的,以后有时间在研究。

由于有多种模式的处理我们将实现接口化,方便我们的管理:定义一个IMirror接口:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public interface IMirror
{void Draw(Image image,List<UIVertex> uiVertices,MirrorType type);
}

Simpe下的顶点映射:

public class SimpleMirror : IMirror
{public void Draw(Image image,List<UIVertex> uiVertices,MirrorType type){ChangeVertices(image.rectTransform.rect,uiVertices,type);MirrorUtlis.Mirror(image.rectTransform.rect,uiVertices,type);}// 改变原有的顶点位置 (做一半映射) 如果是 Horizontal:左半部分 Vertical:上半部分 HorizontalAndVertical:左上四分之一private void ChangeVertices(Rect rect,List<UIVertex> uiVertices,MirrorType type){for (int i = 0; i < uiVertices.Count; i++){UIVertex vertex = uiVertices[i];switch (type){case MirrorType.Horizontal:vertex = HorizontalVertex(rect, vertex);break;case MirrorType.Vertical:vertex = VerticalVertex(rect, vertex);break;case MirrorType.HorizontalAndVertical:vertex = HorizontalVertex(rect, vertex);vertex = VerticalVertex(rect, vertex);break;}uiVertices[i] = vertex;}}// 水平映射private UIVertex HorizontalVertex(Rect rect,UIVertex vertex){vertex.position.x = (vertex.position.x + rect.x) / 2;// - rect.width / 2;return vertex;}// 垂直映射private UIVertex VerticalVertex(Rect rect,UIVertex vertex){vertex.position.y = (rect.y + vertex.position.y) / 2 + rect.height / 2;return vertex;}
}

Sliced下的顶点映射:

我们可以看到如下映射的主要方法:

// 水平映射
private UIVertex HorizontalVertex(Rect rect,UIVertex vertex)
{if (vertex.position.x == s_VertScratch[0].x || vertex.position.x == s_VertScratch[1].x) return vertex;vertex.position.x -= rect.width / 2;return vertex;
}

 时机上非常简单,就是直接对 x 做矩形宽度/2 的平移,比较难的是我们需要知道什么顶点需要做平移?

这个需要看一下Image的源码是如何实现顶点的处理:

        /// <summary>/// Generate vertices for a 9-sliced Image./// </summary>private void GenerateSlicedSprite(VertexHelper toFill){if (!hasBorder){GenerateSimpleSprite(toFill, false);return;}Vector4 outer, inner, padding, border;if (activeSprite != null){outer = Sprites.DataUtility.GetOuterUV(activeSprite);inner = Sprites.DataUtility.GetInnerUV(activeSprite);padding = Sprites.DataUtility.GetPadding(activeSprite);border = activeSprite.border;}else{outer = Vector4.zero;inner = Vector4.zero;padding = Vector4.zero;border = Vector4.zero;}Rect rect = GetPixelAdjustedRect();Vector4 adjustedBorders = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);padding = padding / multipliedPixelsPerUnit;s_VertScratch[0] = new Vector2(padding.x, padding.y);s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);s_VertScratch[1].x = adjustedBorders.x;s_VertScratch[1].y = adjustedBorders.y;s_VertScratch[2].x = rect.width - adjustedBorders.z;s_VertScratch[2].y = rect.height - adjustedBorders.w;for (int i = 0; i < 4; ++i){s_VertScratch[i].x += rect.x;s_VertScratch[i].y += rect.y;}............}

这段源码不全我截取了,计算图片的位置信息,然后把4个顶点位置信息按顺序写进s_VertScratch数组中。这四个位置分别对应一下位置:

即九宫格裁剪后映射到Image顶点上的四个位置,所以当我们向做水平映射的时候只需要平移和 3和4 x轴相等的顶点,与1和2 x轴相等的顶点保留原来的位置。如下图可以很直观的看出来

至于怎么算出这四个九宫格映射的顶点就直接拷贝Image源码的实现就好了。

贴一下完整代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class SlicedMirror : IMirror
{private Image image;// 九宫格的四个分界点private Vector2[] s_VertScratch = new Vector2[4];public void Draw(Image image,List<UIVertex> uiVertices,MirrorType type){this.image = image;SetVertScratch();ChangeVertices(image.rectTransform.rect,uiVertices,type);MirrorUtlis.Mirror(image.rectTransform.rect,uiVertices,type);}private void ChangeVertices(Rect rect,List<UIVertex> uiVertices,MirrorType type){for (int i = 0; i < uiVertices.Count; i++){UIVertex vertex = uiVertices[i];switch (type){case MirrorType.Horizontal:vertex = HorizontalVertex(rect, vertex);break;case MirrorType.Vertical:vertex = VerticalVertex(rect, vertex);break;case MirrorType.HorizontalAndVertical:vertex = HorizontalVertex(rect, vertex);vertex = VerticalVertex(rect, vertex);break;}uiVertices[i] = vertex;}}// 水平映射private UIVertex HorizontalVertex(Rect rect,UIVertex vertex){if (vertex.position.x == s_VertScratch[0].x || vertex.position.x == s_VertScratch[1].x) return vertex;vertex.position.x -= rect.width / 2;return vertex;}// 垂直映射private UIVertex VerticalVertex(Rect rect,UIVertex vertex){if (vertex.position.y == s_VertScratch[2].y || vertex.position.y == s_VertScratch[3].y) return vertex;vertex.position.y += rect.height / 2;return vertex;}private void SetVertScratch(){Sprite activeSprite = image.sprite;Vector4 padding, border;if (activeSprite != null){padding = UnityEngine.Sprites.DataUtility.GetPadding(activeSprite);border = activeSprite.border;}else{padding = Vector4.zero;border = Vector4.zero;}Rect rect = image.GetPixelAdjustedRect();var multipliedPixelsPerUnit = image.pixelsPerUnit * image.pixelsPerUnitMultiplier;Vector4 adjustedBorders = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);padding /= multipliedPixelsPerUnit;s_VertScratch[0] = new Vector2(padding.x, padding.y);s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);s_VertScratch[1].x = adjustedBorders.x;s_VertScratch[1].y = adjustedBorders.y;s_VertScratch[2].x = rect.width - adjustedBorders.z;s_VertScratch[2].y = rect.height - adjustedBorders.w;for (int i = 0; i < 4; ++i){s_VertScratch[i].x += rect.x;s_VertScratch[i].y += rect.y;}}private Vector4 GetAdjustedBorders(Vector4 border, Rect adjustedRect){Rect originalRect = image.rectTransform.rect;for (int axis = 0; axis <= 1; axis++){float borderScaleRatio;if (originalRect.size[axis] != 0){borderScaleRatio = adjustedRect.size[axis] / originalRect.size[axis];border[axis] *= borderScaleRatio;border[axis + 2] *= borderScaleRatio;}float combinedBorders = border[axis] + border[axis + 2];if (adjustedRect.size[axis] < combinedBorders && combinedBorders != 0){borderScaleRatio = adjustedRect.size[axis] / combinedBorders;border[axis] *= borderScaleRatio;border[axis + 2] *= borderScaleRatio;}}return border;}
}

Tiled:模式下的映射

在平铺模式下顶点都是完整的,不需要做镜像处理,只需要修改没一块对应的UV对称即可,我们固定开始位置为1,不做翻转,那么

2位置所构成的顶点UV.y:就需要做对称处理

4位置所构成的顶点UV.x:就需要做对称处理

3位置所构成的顶点UV.x和y :都需要做对称处理

如何判断某几个顶点的UV需要做对称?
我们知道一个三角面由三个顶点构成,那么我么只需要找出三个顶点的中心位置,假设sprite的宽高都为w = 100,h = 100,构成的三角形区域的中心点分别为

1位置 =>(50,50),

2位置 => (50,150),

3位置 => (150,150),

4位置 => (150,50),

我们对中心的的

1 => x / W = 0.5

2 => x / W = 1.5

。。

我们对结果 %2 那么 结果为 1 的就需要翻转了;

uv怎么翻转
outerUv = UnityEngine.Sprites.DataUtility.GetOuterUV(image.sprite);

outerUV中的  x,y就代表右下角的点,z就代表宽,w:代表高,假设A镜像UV后的点为B,那么就满足:

A 到 (0,0)的距离  == B到(0+z)的距离,所以

镜像后的 A.x = outer.z -( A.x - outerUv.x )

贴一下完整代码

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class TiledMirror : IMirror
{private Vector4 outerUv;public void Draw(Image image,List<UIVertex> uiVertices,MirrorType type){outerUv = UnityEngine.Sprites.DataUtility.GetOuterUV(image.sprite);ChangeUv(uiVertices,type);}// uv翻转private void ChangeUv(List<UIVertex> uiVertices,MirrorType type){Vector3 cellMinP = uiVertices[0].position;Vector3 cellMaxP = uiVertices[2].position;float w = cellMaxP.x - cellMinP.x;float h = cellMaxP.y - cellMinP.y;for (int i = 0; i < uiVertices.Count; i+= 3){UIVertex v1 = uiVertices[i];UIVertex v2 = uiVertices[i+1];UIVertex v3 = uiVertices[i+2];float centerX = GetCenter(v1, v2, v3, true) - cellMaxP.x;float centerY = GetCenter(v1, v2, v3, false) - cellMaxP.y;bool changeX = Mathf.Ceil(centerX / w) % 2 != 0;bool changeY = Mathf.Ceil(centerY / h) % 2 != 0;if (changeX && (type == MirrorType.Horizontal || type == MirrorType.HorizontalAndVertical)){v1 = HorizontalUv(v1);v2 = HorizontalUv(v2);v3 = HorizontalUv(v3);}if (changeY && (type == MirrorType.Vertical || type == MirrorType.HorizontalAndVertical)){v1 = VerticalUv(v1);v2 = VerticalUv(v2);v3 = VerticalUv(v3);}uiVertices[i] = v1;uiVertices[i + 1] = v2;uiVertices[i + 2] = v3;}}// 获取三个顶点的中心位置private float GetCenter(UIVertex v1,UIVertex v2,UIVertex v3,bool isX){float min = Mathf.Min(Mathf.Min(isX ? v1.position.x : v1.position.y,isX ? v2.position.x : v2.position.y),Mathf.Min(isX ? v1.position.x : v1.position.y,isX ? v3.position.x : v3.position.y));float max = Mathf.Max(Mathf.Max(isX ? v1.position.x : v1.position.y,isX ? v2.position.x : v2.position.y),Mathf.Max(isX ? v1.position.x : v1.position.y,isX ? v3.position.x : v3.position.y));return (min + max) / 2;}private UIVertex HorizontalUv(UIVertex vertex){vertex.uv0.x = outerUv.x + outerUv.z - vertex.uv0.x;return vertex;}private UIVertex VerticalUv(UIVertex vertex){vertex.uv0.y = outerUv.y + outerUv.w - vertex.uv0.y;return vertex;}}

总结:

实现过程中,思路理清之后实现基本上是不难,但是需要去理解Unity Image的实现,针对绘制不同模式的生成网格顶点的实现,知道图篇是怎么绘制上去的,三个顶点构成一个面,Rect中的(x,y,z,w)分别代表什么。然后就是计算计算。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于spring boot电子商务系统

一、 系统总体结构设计 (一) 功能结构图 图1-1 后台管理子系统 图1-2 电子商务子系统功能结构图 (二) 项目结构目录截图&#xff08;例如下图&#xff09; 图 1-3 系统目录图 (三) 系统依赖截图 图 1-2 所有依赖截图 (四) 配置文件 1、 全局配置文件 2、 其他配置文…

Leetcode226. 翻转二叉树

文章目录 题目介绍题目分析解题思路边界条件&#xff1a;节点为空时返回空子问题&#xff1a;交换左右子节点 整体代码 题目介绍 题目分析 题目要求我们将树中每个节点的左右子节点全部交换,最后返回交换后的树的根节点。 解题思路 这题是比较常见的递归&#xff0c;直接找边…

Simple_SSTI_1-WEB-bugku-解题步骤

——CTF解题专栏—— 声明&#xff1a;文章由作者weoptions学习或练习过程中的步骤及思路&#xff0c;非正式答案&#xff0c;仅供学习和参考。 题目信息&#xff1a; 题目&#xff1a;Simple_SSTI_1 作者&#xff1a;valecalida 提示&#xff1a;无 场景&#xff1a; 解题…

蓝桥杯day03——二进制间距

1.题目 给定一个正整数 n&#xff0c;找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1&#xff0c;返回 0 。 如果只有 0 将两个 1 分隔开&#xff08;可能不存在 0 &#xff09;&#xff0c;则认为这两个 1 彼此 相邻 。两个 1 之间的距离…

oops-framework框架 之 创建项目(二)

引擎&#xff1a; CocosCreator 3.8.0 环境&#xff1a; Mac Gitee: oops-game-kit 构建 本篇博客将使用oops-game-kit 构建一个新的开发项目&#xff0c; 关于 oops-framework 框架的了解&#xff0c;可参考上篇博客&#xff1a; oops-framework框架 之 初始了解(一) 大概…

力扣题:字符串的反转-11.24

力扣题-11.24 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;151. 翻转字符串里的单词 解题思想&#xff1a;保存字符串中的单词即可 class Solution(object):def reverseWords(self, s):""":type s: str:rtype: str"&quo…

Qt路径和Anaconda中QT路径冲突(ubuntu系统)

最近做一个项目需要配置QT库&#xff0c;本项目配置环境如下&#xff1a; Qt version 5 Operating system, version and so on ubuntu 20.04 Description 之前使用过anaconda环境安装过QT5&#xff0c;所以在项目中CMakeLists文件中使用find_package时候&#xff0c;默认使用An…

【Linux】ubuntu配置SSH服务

要在Ubuntu上配置SSH服务&#xff0c;首先安装ssh-server sudo apt install openssh-server 安装完成后&#xff0c;可以检查一下是否安装成功 systemctl status ssh vim /etc/ssh/sshd_config 此时ubuntu就可以被远程连接工具连接了&#xff0c;如果我们想配置关于SCP服务允…

JVM运行时数据区域

文章目录 内存结构程序计数器&#xff08;寄存器&#xff09;虚拟机栈局部变量表两类异常状况 线程运行诊断 本地方法栈堆方法区运行时常量池串池&#xff08;StringTable&#xff09;字符串的拼接串池的位置StringTable垃圾回收StringTable性能调优 直接内存 内存结构 程序计…

(三)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)

一、无人机模型简介&#xff1a; 单个无人机三维路径规划问题及其建模_IT猿手的博客-CSDN博客 参考文献&#xff1a; [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、Tiki-taka算法&#xff08;TTA&#xf…

Overflow Aware Quantization

Overflow Aware Quantization Framework N o _o o​是 amount of arithmetic overflow 辅助信息 作者未提供代码

A--Z与a--z的ASCII码的差异

从z到A还有一些字符 应该改为str[i]>A&&str[i]<Z||str[i]>a&&str[i]<z;

架构图是什么,怎么做?

架构图是一种用来描述系统或软件的结构和组成的图形表示。它展示了系统中各个组件之间的关系、交互和功能。通过绘制架构图&#xff0c;可以更好地理解和沟通系统的设计和实现。 绘制架构图的软件 目前市场上有许多用于绘制架构图的软件工具&#xff0c;下面简单…

软件工程 - 第8章 面向对象建模 - 4 - 物理体系结构建模

构件图 构件图概述 构件图描述了软件的各种构件和它们之间的依赖关系。 构件图的作用 在构件图中&#xff0c;系统中的每个物理构件都使用构件符号来表示&#xff0c;通常&#xff0c;构件图看起来像是构件图标的集合&#xff0c;这些图标代表系统中的物理部件&#xff0c;…

pandas美化表格并导出到Excel

美化Excel表格用两种方式,一种是用Pandas自带的Dataframe.style类并通过CSS来改变样式,另外一种是通过Excel引擎来直接修改Excel样式。 Dataframe.style Dataframe.style可以美化Pandas样式。导出样式到Excel的功能只有openpyxl渲染引擎支持。 大于平均数的单元格背景变色…

JavaScript 延迟加载的艺术:按需加载的最佳实践

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

React Native 更换淘宝镜像提升包下载速度

React Native 更换淘宝镜像提升包下载速度 每次运行项目的时候都是卡在包下载的命令上&#xff0c;每次一等就要 1h20m 极度崩溃&#xff0c;那是因maven镜像源为Google导致无法正常下载。 那么我们就可以切换maven镜像源&#xff0c;方法如下&#xff1a; 找到项目下的**/an…

逻辑回归与正则化 逻辑回归、激活函数及其代价函数

逻辑回归、激活函数及其代价函数 线性回归的可行性 对分类算法&#xff0c;其输出结果y只有两种结果{0&#xff0c;1}&#xff0c;分别表示负类和正类&#xff0c;代表没有目标和有目标。 在这种情况下&#xff0c;如果用传统的方法以线性拟合 &#xff08; h θ ( x ) θ T…

医疗器械设备模组的具体应用

直线模组是一种高精度、高速度的精密传动元件&#xff0c;目前被广泛应用在各种工业自动化领域&#xff1b;尤其是在激光加工、电子制造、医疗设备、物流设备和机器人等行业中&#xff0c;都发挥着重要作用&#xff0c;接下来我们看看医疗器械设备模组的具体应用吧&#xff01;…

多模块下MyBatis官方生成器

MyBatis官方生成器 1. 依赖插件 创建generator模块 在父模块中进行版本管理 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version> </dependency><dependency><g…