NavMesh只制作可移动的导航网,清除多余不可走区域

只制作可移动的导航网。它使存储文件大小减小并提高性能。它消除了迁移到随机区域的问题。添加链接描述
1.如何使用
**加粗样式**
2.创建一个包含“NavMeshCleaner”组件的对象。Andadd指向可定制区域。

按住控制键并单击添加点。如果要移动它,请按
输入上的control键并单击。您不需要在此处添加多点筛选
3.单击计算按钮
在这里插入图片描述
非步行问题表已取消。
在这里插入图片描述
4.重建一个无碱问题的NavMesh。完成。
在这里插入图片描述
提示
如果NvMesh的坡度较大,它仍可能成为不可步行的区域。在这种情况下,复制NavMeshCleaner对象并创建新的非行走问题表。

using System.Collections.Generic;
using UnityEngine;
#if UNITY_5_3_OR_NEWER
using UnityEngine.AI;
#endif
#if UNITY_EDITOR
using UnityEditor;
#endifpublic class NavMeshCleaner : MonoBehaviour
{public List<Vector3> m_WalkablePoint = new List<Vector3>();public float m_Height = 1.0f;public float m_Offset = 0.0f;public int m_MidLayerCount = 3;#if UNITY_EDITORprivate void Awake(){SetMeshVisible(false);}List<GameObject> m_Child = new List<GameObject> ();void Reset(){Undo.RecordObject(this, "Reset");for (int i = 0; i < m_Child.Count; i++){Undo.DestroyObjectImmediate(m_Child[i]);}m_Child.Clear();}void SetMeshVisible(bool visible){for (int i = 0; i < m_Child.Count; i++)m_Child[i].SetActive(visible);}public bool HasMesh(){return m_Child.Count != 0 ? true : false;}public bool MeshVisible(){if (m_Child.Count > 0)return m_Child[0].activeSelf;return false;}void Build(){Mesh[] m = CreateMesh();Undo.RegisterCreatedObjectUndo(this, "build");for (int i = 0; i < m.Length || i == 0; i++){GameObject o;if (i >= m_Child.Count){o = new GameObject();//o.hideFlags = HideFlags.DontSave;o.name = gameObject.name + "_Mesh(DontSave)";o.AddComponent<MeshFilter>();MeshRenderer meshrenderer = o.AddComponent<MeshRenderer>();meshrenderer.sharedMaterial = AssetDatabase.GetBuiltinExtraResource<Material>("Default-Diffuse.mat");o.transform.parent = transform;o.transform.localScale = Vector3.one;o.transform.localPosition = Vector3.zero;o.transform.localRotation = Quaternion.identity;GameObjectUtility.SetStaticEditorFlags(o, GameObjectUtility.GetStaticEditorFlags(gameObject) | StaticEditorFlags.NavigationStatic);GameObjectUtility.SetNavMeshArea(o, 1);m_Child.Add(o);Undo.RegisterCreatedObjectUndo(o, "");}else{o = m_Child[i].gameObject;}o.hideFlags = i == 0 ? (HideFlags.DontSave | HideFlags.HideInHierarchy) : m_Child[0].gameObject.hideFlags;MeshFilter meshfilter = m_Child[i].GetComponent<MeshFilter>();Undo.RecordObject(meshfilter, "MeshUpdate");meshfilter.sharedMesh = m.Length == 0 ? null : m[i];}while (m_Child.Count > m.Length){Undo.DestroyObjectImmediate(m_Child[m_Child.Count-1]);m_Child.RemoveAt(m_Child.Count-1);}}static int Find(Vector3[] vtx, int left, int right, Vector3 v, float key){int center = (left + right) / 2;if (center == left){for (int i = left; i < vtx.Length && vtx[i].x <= key + 0.002f; i++){if (Vector3.Magnitude(vtx[i] - v) <= 0.01f)return i;}return -1;}if (key <= vtx[center].x)return Find(vtx, left, center, v, key);elsereturn Find(vtx, center, right, v, key);}class Tri{public Tri(int i1, int i2, int i3) { this.i1 = i1; this.i2 = i2; this.i3 = i3; min = Mathf.Min(i1, i2, i3); max = Mathf.Max(i1, i2, i3); }public int i1, i2, i3;public int min, max;};class Edge{public Edge(int i1, int i2) { this.i1 = i1; this.i2 = i2; }public int i1, i2;};static bool Find(Edge[] edge, int left, int right, int i1, int i2){int center = (left + right) / 2;if (center == left){for (int i = left; i < edge.Length && edge[i].i1 <= i1; i++){if (edge[i].i1 == i1 && edge[i].i2 == i2)return true;}return false;}if (i1 <= edge[center].i1)return Find(edge, left, center, i1, i2);elsereturn Find(edge, center, right, i1, i2);}Mesh[] CreateMesh(){NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation();Vector3[] navVertices = triangulatedNavMesh.vertices;List<Vector3> vertices = new List<Vector3>();vertices.AddRange(navVertices);vertices.Sort(delegate (Vector3 v1, Vector3 v2) { return v1.x == v2.x ? (v1.z == v2.z ? 0 : (v1.z < v2.z ? -1 : 1)) : (v1.x < v2.x ? -1 : 1); });Vector3[] v = vertices.ToArray();int[] table = new int[triangulatedNavMesh.vertices.Length];for (int i = 0; i < table.Length; i++){table[i] = Find(v, 0, vertices.Count, navVertices[i], navVertices[i].x - 0.001f);if ((i % 100) == 0)EditorUtility.DisplayProgressBar(string.Format("Export Nav-Mesh (Phase #1/3) {0}/{1}", i, table.Length), "Weld Vertex", Mathf.InverseLerp(0, table.Length, i));}int[] navTriangles = triangulatedNavMesh.indices;List <Tri> tri = new List <Tri> ();for (int i = 0; i < navTriangles.Length; i += 3)tri.Add(new Tri(table[navTriangles[i + 0]], table[navTriangles[i + 1]], table[navTriangles[i + 2]]));tri.Sort(delegate (Tri t1, Tri t2) { return t1.min == t2.min ? 0 : t1.min < t2.min ? -1 : 1; });int[] boundmin = new int[(tri.Count + 127) / 128];int[] boundmax = new int[boundmin.Length];for (int i = 0, c=0; i < tri.Count; i += 128, c++){int min = tri[i].min;int max = tri[i].max;for (int j = 1; j < 128 && i + j < tri.Count; j++){min = Mathf.Min(tri[i + j].min, min);max = Mathf.Max(tri[i + j].max, max);}boundmin[c] = min;boundmax[c] = max;}int[] triangles = new int[navTriangles.Length];for (int i = 0; i < triangles.Length; i += 3){triangles[i+0] = tri[i/3].i1;triangles[i+1] = tri[i/3].i2;triangles[i+2] = tri[i/3].i3;}List<int> groupidx = new List<int>();List<int> groupcount = new List<int>();int[] group = new int[triangles.Length / 3];for (int i = 0; i < triangles.Length; i += 3){int groupid = -1;int max = Mathf.Max(triangles[i], triangles[i + 1], triangles[i + 2]);int min = Mathf.Min(triangles[i], triangles[i + 1], triangles[i + 2]);for (int b=0, c=0; b < i; b+=3*128, c++){if (boundmin[c] > max || boundmax[c] < min)continue;for (int j=b; j < i && j < b+3*128; j+=3){if (tri[j / 3].min > max)break;if (tri[j / 3].max < min)continue;if (groupidx[group[j / 3]] == groupid)continue;for (int k = 0; k < 3; k++){int vi = triangles[j + k];if (triangles[i] == vi || triangles[i+1] == vi || triangles[i+2] == vi){if (groupid == -1){groupid = groupidx[group[j / 3]];group[i/3] = groupid;}else{int curgroup = groupidx[group[j / 3]];for (int l = 0; l < groupidx.Count; l++){if (groupidx[l] == curgroup)groupidx[l] = groupid;}}break;}}}}if (groupid == -1){groupid = groupidx.Count;group[i/3] = groupid;groupidx.Add(groupid);groupcount.Add(0);}if (((i / 3) % 100) == 0)EditorUtility.DisplayProgressBar("Collect (Phase #2/3)", "Classification Group", Mathf.InverseLerp(0, triangles.Length, i));}for (int i = 0; i < triangles.Length; i += 3){group[i / 3] = groupidx[group[i / 3]];groupcount[group[i / 3]]++;}List<Mesh> result = new List<Mesh>();List<Vector3> vtx = new List<Vector3>();List<int> indices = new List<int>();int[] newtable = new int[vertices.Count];for (int i = 0; i < newtable.Length; i++)newtable[i] = -1;Vector3[] walkpoint = m_WalkablePoint.ToArray();for (int g = 0; g < groupcount.Count; g++){if (groupcount[g] == 0)continue;List<Vector3> isolatevtx = new List<Vector3>();List<int> iolateidx = new List<int>();for (int i = 0; i < triangles.Length; i += 3){if (group[i / 3] == g){for (int j = 0; j < 3; j++){int idx = triangles[i + j];if (newtable[idx] == -1){newtable[idx] = isolatevtx.Count;isolatevtx.Add(transform.InverseTransformPoint(vertices[idx] + Vector3.up * m_Offset));}}iolateidx.Add(newtable[triangles[i + 0]]);iolateidx.Add(newtable[triangles[i + 1]]);iolateidx.Add(newtable[triangles[i + 2]]);}}if (Contains(isolatevtx.ToArray(), iolateidx.ToArray(), walkpoint) == true)continue;int maxvertex = 32768;if (vtx.Count > maxvertex || vtx.Count + isolatevtx.Count*(2+m_MidLayerCount) >= 65536){result.Add(CreateMesh(vtx.ToArray(), indices.ToArray()));vtx.Clear();indices.Clear();}Vector3 h = transform.InverseTransformVector(Vector3.up * m_Height);int vtxoffset = vtx.Count;int layer = 2 + m_MidLayerCount;for (int i = 0; i < isolatevtx.Count; i++){for(int j=0; j<layer; j++)vtx.Add(isolatevtx[i] + h * ((float)j / (layer-1)));}for (int i = 0; i < iolateidx.Count; i += 3){for (int j = 0; j < layer; j++){if (j == 0)indices.AddRange(new int[] { vtxoffset + iolateidx[i] * layer + j, vtxoffset + iolateidx[i + 2] * layer + j, vtxoffset + iolateidx[i + 1] * layer + j });elseindices.AddRange(new int[] { vtxoffset + iolateidx[i] * layer + j, vtxoffset + iolateidx[i + 1] * layer + j, vtxoffset + iolateidx[i + 2] * layer + j });}}if (m_Height > 0){List<Edge> edge = new List<Edge>();for (int i = 0; i < iolateidx.Count; i += 3){edge.Add(new Edge(iolateidx[i+0], iolateidx[i+1]));edge.Add(new Edge(iolateidx[i+1], iolateidx[i+2]));edge.Add(new Edge(iolateidx[i+2], iolateidx[i+0]));}edge.Sort(delegate (Edge e1, Edge e2) { return e1.i1 == e2.i1 ? 0 : (e1.i1 < e2.i1 ? -1 : 1); });Edge[] e = edge.ToArray();for (int i = 0; i < iolateidx.Count; i += 3){for (int i1 = 2, i2 = 0; i2 < 3; i1 = i2++){int v1 = iolateidx[i + i1];int v2 = iolateidx[i + i2];if (!Find(e, 0, edge.Count, v2, v1)){if (vtx.Count + 4 >= 65536){result.Add(CreateMesh(vtx.ToArray(), indices.ToArray()));vtx.Clear();indices.Clear();}indices.AddRange(new int[] { vtx.Count, vtx.Count + 1, vtx.Count + 3, vtx.Count, vtx.Count + 3, vtx.Count + 2 });vtx.AddRange(new Vector3[] { isolatevtx[v1], isolatevtx[v2], isolatevtx[v1]+h, isolatevtx[v2]+h });}}if ((i%600) == 0)EditorUtility.DisplayProgressBar("Collect (Phase #3/3)", "Create Mesh", Mathf.InverseLerp(0, groupcount.Count*100, g*100 + i * 100 / (i - iolateidx.Count)));}}EditorUtility.DisplayProgressBar("Collect (Phase #3/3)", "Create Mesh", Mathf.InverseLerp(0, groupcount.Count, g));}if (vtx.Count > 0){result.Add(CreateMesh(vtx.ToArray(), indices.ToArray()));}EditorUtility.ClearProgressBar();return result.ToArray();}static Mesh CreateMesh(Vector3[] vtx, int[] indices){Mesh m = new Mesh();m.hideFlags = HideFlags.DontSave;m.vertices = vtx;m.SetIndices(indices, MeshTopology.Triangles, 0);m.RecalculateNormals();m.RecalculateBounds();return m;}static bool Contains(Vector3[] vtx, int[] indices, Vector3[] points){for (int j = 0; j < points.Length; j++){Vector3 p = points[j];for (int i = 0; i < indices.Length; i += 3){if (indices[i] == indices[i + 1] || indices[i] == indices[i + 2] || indices[i + 1] == indices[i + 2])continue;if (PointInTriangle(vtx[indices[i]], vtx[indices[i + 2]], vtx[indices[i + 1]], p))return true;}}return false;}static bool PointInTriangle(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 p){Vector3 up = Vector3.Cross(v3 - v1, v2 - v1);if (Vector3.Dot(Vector3.Cross(p - v1, v2 - v1), up) > 0 &&Vector3.Dot(Vector3.Cross(p - v2, v3 - v2), up) > 0 &&Vector3.Dot(Vector3.Cross(p - v3, v1 - v3), up) > 0)return true;return false;}[UnityEditor.CustomEditor(typeof(NavMeshCleaner))]public class NavMeshCleanerEditor : Editor{NavMeshCleaner m_Target;void OnEnable(){m_Target = (NavMeshCleaner)target;Undo.undoRedoPerformed += OnUndoOrRedo;}void OnDisable(){Undo.undoRedoPerformed -= OnUndoOrRedo;}void OnUndoOrRedo(){Repaint();}public override void OnInspectorGUI(){EditorGUILayout.HelpBox(m_OverPoint != -1 ? "Press Control and click to remove the point." : "Press Control and click to add a walkable point.", m_Target.m_WalkablePoint.Count == 0 ? MessageType.Warning : MessageType.Info);base.OnInspectorGUI();NavMeshCleaner t = (NavMeshCleaner)target;if (t.m_Child.Count > 0){EditorGUI.BeginChangeCheck();bool hideInHierarchy = EditorGUILayout.Toggle("Hide Temp Mesh Object In Hierarchy", (t.m_Child[0].gameObject.hideFlags & HideFlags.HideInHierarchy) != 0 ? true : false);if (EditorGUI.EndChangeCheck()){for (int i = 0; i < t.m_Child.Count; i++)t.m_Child[i].gameObject.hideFlags = hideInHierarchy ? (t.m_Child[i].gameObject.hideFlags | HideFlags.HideInHierarchy) : (t.m_Child[i].gameObject.hideFlags & (~HideFlags.HideInHierarchy));try{EditorApplication.RepaintHierarchyWindow();EditorApplication.DirtyHierarchyWindowSorting();}catch { }}}if (GUILayout.Button(t.HasMesh() ? "Recalculate" : "Calculate", GUILayout.Height(30.0f))){t.Build();t.SetMeshVisible(true);SceneView.RepaintAll();}if (t.HasMesh() && GUILayout.Button(t.MeshVisible() ? "Hide Mesh" : "Show Mesh", GUILayout.Height(30.0f))){//StaticEditorFlags flags = GameObjectUtility.GetStaticEditorFlags(t.gameObject);bool enabled = !t.MeshVisible();t.SetMeshVisible(enabled);SceneView.RepaintAll();}if (t.HasMesh() && GUILayout.Button("Reset Mesh", GUILayout.Height(30.0f))){t.Reset();SceneView.RepaintAll();}if (t.HasMesh() && GUILayout.Button("Reset WalkablePoints", GUILayout.Height(30.0f))){Undo.RecordObject(target, "reset");m_Target.m_WalkablePoint.Clear();SceneView.RepaintAll();}}static class Styles{public static GUIStyle Get(string id){GUIStyle style;if (!texture.TryGetValue(id, out style)){style = new GUIStyle(id);texture.Add(id, style);}return style;}static Dictionary<string, GUIStyle> texture = new Dictionary<string, GUIStyle>();}void DrawDisc(Vector3 p, Vector3 n, float radius){Vector3[] v = new Vector3[20];Matrix4x4 tm = Matrix4x4.TRS(p, Quaternion.LookRotation(n), Vector3.one * radius);for (int i = 0; i < 20; i++){v[i] = tm.MultiplyPoint3x4(new Vector3(Mathf.Cos(Mathf.PI * 2 * i / (20 - 1)), Mathf.Sin(Mathf.PI * 2 * i / (20 - 1)), 0));}Handles.DrawAAPolyLine(v);}void OnSceneGUI(){SceneView sceneview = SceneView.currentDrawingSceneView;Event guiEvent = Event.current;if (guiEvent.type == EventType.Repaint){// drawfor (int i = 0; i < m_Target.m_WalkablePoint.Count; i++){Vector3 p = m_Target.transform.TransformPoint(m_Target.m_WalkablePoint[i]);float unitsize = WorldSize(1.0f, sceneview.camera, p);Handles.color = Color.black;DrawDisc(p, Vector3.up, unitsize * 15);Handles.color = i == m_OverPoint ? Color.red : Color.green;Handles.DrawSolidDisc(p, Vector3.up, unitsize * 10);Handles.DrawLine(p, p + Vector3.up * (unitsize * 200.0f));}}if (guiEvent.type == EventType.Layout && guiEvent.control == true){HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));}if (guiEvent.control == true){EditorGUIUtility.AddCursorRect(new Rect(0, 0, Screen.width, Screen.height), m_OverPoint == -1 ? MouseCursor.ArrowPlus : MouseCursor.ArrowMinus);}if ((guiEvent.type == EventType.MouseDown || guiEvent.type == EventType.MouseDrag || guiEvent.type == EventType.MouseMove || guiEvent.type == EventType.MouseUp) && guiEvent.button == 0){MouseEvent(guiEvent.type, guiEvent.mousePosition, guiEvent.modifiers == EventModifiers.Control ? true : false);}}int m_OverPoint = -1;void MouseEvent(EventType type, Vector2 mouseposition, bool controldown){SceneView sceneview = SceneView.currentDrawingSceneView;Ray mouseRay = HandleUtility.GUIPointToWorldRay(mouseposition);            if (type == EventType.MouseMove){int pointindex = -1;for (int i = 0; i < m_Target.m_WalkablePoint.Count; i++){Vector3 p = m_Target.transform.TransformPoint(m_Target.m_WalkablePoint[i]);float size = WorldSize(10.0f, sceneview.camera, p) * 1.5f;if (DistanceRayVsPoint(mouseRay, p) < size){pointindex = i;break;}}if (pointindex != m_OverPoint){m_OverPoint = pointindex;HandleUtility.Repaint();}}if (type == EventType.MouseDown && controldown == true){if (m_OverPoint != -1){Undo.RecordObject(m_Target, "Remove Point");m_Target.m_WalkablePoint.RemoveAt(m_OverPoint);m_OverPoint = -1;}else{float mint = 1000.0f;RaycastHit hit;if (Physics.Raycast(mouseRay, out hit, mint)){Undo.RecordObject(m_Target, "Add Point");m_Target.m_WalkablePoint.Add(m_Target.transform.InverseTransformPoint(hit.point));}else{NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation();Vector3[] navVertices = triangulatedNavMesh.vertices;int[] indices = triangulatedNavMesh.indices;Vector3 outNormal = Vector3.up;for (int i = 0; i < indices.Length; i += 3)mint = IntersectTest(mouseRay, navVertices[indices[i]], navVertices[indices[i + 1]], navVertices[indices[i + 2]], mint, ref outNormal);if (mint < 1000.0f){Undo.RecordObject(m_Target, "Add Point");Vector3 point = mouseRay.origin + mouseRay.direction * mint;m_Target.m_WalkablePoint.Add(m_Target.transform.InverseTransformPoint(point));}}}HandleUtility.Repaint();}}static float kEpsilon = 0.000001f;// https://en.wikipedia.org/wiki/Möller–Trumbore_intersection_algorithmstatic float IntersectTest(Ray ray, Vector3 v0, Vector3 v1, Vector3 v2, float mint, ref Vector3 outNormal){// edges from v1 & v2 to v0.     Vector3 e1 = v1 - v0;Vector3 e2 = v2 - v0;Vector3 h = Vector3.Cross(ray.direction, e2);float a = Vector3.Dot(e1, h);if ((a > -kEpsilon) && (a < kEpsilon))return mint;float f = 1.0f / a;Vector3 s = ray.origin - v0;float u = f * Vector3.Dot(s, h);if ((u < 0.0f) || (u > 1.0f))return mint;Vector3 q = Vector3.Cross(s, e1);float v = f * Vector3.Dot(ray.direction, q);if ((v < 0.0f) || (u + v > 1.0f))return mint;float t = f * Vector3.Dot(e2, q);if (t > kEpsilon && t < mint){outNormal = Vector3.Normalize(Vector3.Cross(e1.normalized, e2.normalized));return t;}return mint;}static float WorldSize(float screensize, Camera camera, Vector3 p){if (!camera.orthographic){Vector3 localPos = camera.transform.InverseTransformPoint(p);float height = Mathf.Tan(camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * localPos.z;return height * screensize / camera.pixelHeight;}else{return camera.orthographicSize * screensize / camera.pixelHeight;}}static float DistanceRayVsPoint(Ray mouseRay, Vector3 pos){Vector3 v = pos - mouseRay.origin;return Mathf.Sqrt(Vector3.Dot(v, v) - Vector3.Dot(mouseRay.direction, v) * Vector3.Dot(mouseRay.direction, v));}static Vector3 IntersectPlane(Vector3 inNormal, Vector3 inPoint, Ray mouseRay){Plane p = new Plane(inNormal, inPoint);float dstToDrawPlane = p.GetDistanceToPoint(mouseRay.origin);return mouseRay.origin + mouseRay.direction * (dstToDrawPlane / Vector3.Dot(-p.normal, mouseRay.direction));}}
#endif
}

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

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

相关文章

信息安全工程师(55)网络安全漏洞概述

一、定义 网络安全漏洞&#xff0c;又称为脆弱性&#xff0c;是网络安全信息系统中与安全策略相冲突的缺陷&#xff0c;这种缺陷也称为安全隐患。漏洞可能导致机密性受损、完整性破坏、可用性降低、抗抵赖性缺失、可控性下降、真实性不保等问题。 二、分类 网络安全漏洞可以根据…

桥接模式,外界与主机通,与虚拟机不通

一 二 在此选择Windows与外界连接的网卡&#xff0c;通过有线连就选有线网卡&#xff0c;通过无线连就选无线网卡。 三 如果需要设置固定IP&#xff0c;则选择"Manual"进行设置。我这边根据实际需要&#xff0c;走无线的时候用DHCP&#xff0c;走有线的时候设固定IP…

C#中的委托、匿名方法、Lambda、Action和Func

委托 委托概述 委托是存有对某个方法的引用的一种引用类型变量。定义方法的类型&#xff0c;可以把一个方法当作另一方法的参数。所有的委托&#xff08;Delegate&#xff09;都派生自 System.Delegate 类。委托声明决定了可由该委托引用的方法。 # 声明委托类型 委托类型声…

Golang | Leetcode Golang题解之第507题完美数

题目&#xff1a; 题解&#xff1a; func checkPerfectNumber(num int) bool {if num 1 {return false}sum : 1for d : 2; d*d < num; d {if num%d 0 {sum dif d*d < num {sum num / d}}}return sum num }

一文掌握Kubernates核心组件,构建智能容器管理集群

1.Kubernates简要概述 Kubernates&#xff08;常称为K8s&#xff0c;因省略了“ubernate”中的8个字符&#xff09;是Google开源的容器编排平台&#xff0c;专为简化和自动化应用服务的部署、扩展和管理而设计。它将应用与底层的服务器抽象开来&#xff0c;提供了自动化的机制…

怎么提取pdf的某一页?批量提取pdf的某一页的简单方法

怎么提取pdf的某一页&#xff1f;在日常工作与学习中&#xff0c;我们经常会遇到各式各样的PDF文件&#xff0c;它们以其良好的兼容性和稳定性&#xff0c;成为了信息传输和存储的首选格式。然而&#xff0c;在浩瀚的文档海洋中&#xff0c;有时某个PDF文件中的某一页内容尤为重…

Docker存储

前提条件 拥有docker环境&#xff0c;可参考&#xff1a;Docker的安装掌握容器的使用&#xff0c;可参考&#xff1a;Docker容器的使用掌握镜像的使用&#xff0c;可参考&#xff1a;Docker镜像的使用 Docker存储的问题 容器是隔离环境&#xff0c;容器内程序的文件、配置、运…

自动发现-实现运维管理自动化

nVisual-Discovery是一款自动化工具软件&#xff0c;通过多种自动发现技术&#xff0c;协助运维管理人员快速建立可视化的网络文档&#xff0c;提升网络管理的效率与准确性。 01 IP扫描发现 当我们新接手一个网络运维项目&#xff0c;通常缺乏精准的网络文档数据&#xff0c;…

vue3+ts实时播放视频,视频分屏

使用vue3以及播放视频组件Jessibuca Jessibuca地址 使用循环个数来实现分屏 效果图&#xff0c;四屏 九屏 dom代码 <div class"icon"><div class"icon-box"><span class"text">分屏&#xff1a;</span><el-icon …

RHCSA笔记三

第二章 linux中执行命令 命令格式 命令分为两类 内置命令&#xff1a;由 shell 程序自带的命令 外部命令&#xff1a;有独立的可执行程序文件&#xff0c;文件名即命令名 格式 主命令 参数 操作对象 # 注意&#xff1a; 下面是对于命令的语法的一些符号的说明&#xff1…

爬虫结合项目实战

由于本人是大数据专业&#xff0c;所以准备的是使用pycharm工具进行爬虫爬取数据&#xff0c;然后实现一个可视化大屏 参考项目&#xff1a; 1.医院大数据可视化最后展示 2. 大数据分析可视化系统展示 代码包&#xff1a;

【js逆向专题】12.RPC技术

目录 一. websocket1. 什么是websocket2. websocket的原理3. websocket实现方式1. 客户端2.服务端3. 实际案例1. 案例目标2. 解析思路 二. RPC1. RPC 简介2.Sekiro-RPC1. 使用方法1. 执行方式2.客户端环境3.使用参数说明 2. 测试使用1. 前端代码2. SK API3.python调用代码 三.项…

LabVIEW伺服压机是如何实现压力位移的精度?

LabVIEW伺服压机通过精确的压力和位移控制&#xff0c;实现了高精度的压装操作。为了达到这种精度&#xff0c;系统通常依赖于多个硬件和软件模块的协同工作&#xff0c;包括伺服电机、压力传感器、位移传感器以及LabVIEW的实时控制和数据处理功能。以下是LabVIEW伺服压机如何实…

论文阅读与写作入门

文章目录 1.阅读第一篇论文(1)论文结构(2)目标 2.使用GPT辅助论文的阅读与写作3.专有名词(1)架构(2)网络(3)机器学习 4.文献翻译软件5.从哪里下载文献&#xff1f;6.如何判断(你自己的)研究工作的价值or贡献【论文精读李沐】7.经典论文(1)AlexNet 2012(2)FCN 全卷积 2014(3)Res…

【java面向对象编程】第一弹----类与对象的理解及类和对象的内存分配机制

一、类与对象 1.1类与对象的理解 &#xff08;1&#xff09;类就是数据类型&#xff0c;比如String类 &#xff08;2&#xff09;对象就是一个具体的实例 1.1.2类和对象的区别与联系 1) 类是抽象的&#xff0c;概念的&#xff0c;代表一类事物,比如人类,猫类.., 即它是数据…

异地组网最简单的方法

异地组网的方法多种多样&#xff0c;每种方法都有其特定的优缺点和适用场景&#xff0c;本期梳理一些相对简单且常用的异地组网方法&#xff0c;开始~ 一、使用硬件路由器的 VPN 功能 前提条件 你需要有支持 VPN 功能的路由器&#xff0c;如华硕、中兴等品牌。这些路由器在设置…

Newstar_week1_week2_wp

week1 wp crypto 一眼秒了 n费马分解再rsa flag&#xff1a; import libnum import gmpy2 from Crypto.Util.number import * p 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297…

「C/C++」C++17 之 std::variant 安全的联合体(变体)

#1024程序员节&#xff5c;征文# ✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计…

vue2 el-select赋值无效(无法选中)

背景&#xff1a;点击添加明细时&#xff0c;el-table会新增一条数据&#xff0c;其中&#xff0c;存货原申购用途 会根据 费用承担事业部 下拉框的值改变而改变&#xff0c;所以每次费用承担事业部发生变化时&#xff0c;都需要清空存货原申购用途的值 最开始是直接这样写的&a…

基于Java(SSM框架)+MySQL开发的小型英语学习网站

一、需求分析 英语已经越来越凸显其重要性。大学生一般都需要考CET-4或者CET-6&#xff0c;对于程序员&#xff0c;如果没有扎实的英语基础&#xff0c;看有些API文档也比较费力。生活中处处存在英语&#xff0c;也越来越体现英语的重要性&#xff0c;如何高效学习英语成了关键…