【学习笔记】Windows GDI绘图(五)图形路径GraphicsPath详解(上)

文章目录

  • 图形路径GraphicsPath
  • 填充模式FillMode
  • 构造函数
    • GraphicsPath()
    • GraphicsPath(FillMode)
    • GraphicsPath(Point[],Byte[])和GraphicsPath(PointF[], Byte[])
    • GraphicsPath(Point[], Byte[], FillMode)和GraphicsPath(PointF[], Byte[], FillMode)
    • PathPointType
  • 属性
    • FillMode
    • PathData
    • PathPoints、PathTypes
    • PointCount
  • 方法
    • AddArc添加椭圆弧
    • AddBezier添加贝赛尔曲线
    • AddClosedCurve添加封闭基数样条曲线
    • AddCurve添加基数样条曲线(开放)
    • AddEllipse添加椭圆
    • AddLine添加线段

图形路径GraphicsPath

定义:表示一系列相连的线段和曲线。

namespace System.Drawing.Drawing2D;public sealed unsafe class GraphicsPath : MarshalByRefObject, ICloneable, IDisposable

应用程序使用路径绘制形状的轮廓、填充内部和创建剪裁区域(clipping regions)。
图形引擎在世界坐标空间中维护路径中几何形状的坐标。

一个路径可以由任意数量的图形(子路径)组成。每个图形由一系列连接的线段和曲线组成,或由一个几何形状基本体组成。

一个由一系列连接的线段和曲线组成的图形(起点和终点可能合重合)是一个开放的图形,除非它被显式定义为封闭图形。可以使用CloseFigure方法显示地封闭一个图形,该方法通过从终点到起点连接一条线来封闭当前图形。

由几何形状基本体组成的图形是一个封闭的图形。

为了填充和剪切,所有开放图形都会通过在力的起点和终点之间添加一条线来封闭。

当创建路径或封闭图形时,会隐藏地启动一个新图形。当调用StartFigure方法时,会显式地创建一个新图形。

当将几何形状基本体添加到路径时,它会添加一个包含该几何形状的图形,并隐式地启动一个新图形。因此,路径中总是存在一个当前图形,当将线段和曲线添加到路径时,会根据需要隐式地添加一条线,以连接当前图形的终点与新线段或曲线的起点,从而形成一系列连接的线段和曲线。

图形具有描述如何从起点到终点之间的线段与曲线的方向。该方向由线段和曲线添加的顺序或由几何体形状基本体定义。方向用于确定剪裁和填充路径的内部。
全文图像
全文图像

填充模式FillMode

解释GraphicsPath前,先说明下路径的两种填充方式 Alternate交替模式 和 Winding绕线模式
这两种填充模式都使用奇偶规则来确定如何填充封闭路径。

路径填充模式
Allternate:

  1. 从你感兴趣的点画一条射线(通常是水平线)。
  2. 数一下射线与路径的边相交的次数。
  3. 如果交点数是奇数,点在路径内部;如果是偶数,点在路径外部。

Winding:

  1. 从你感兴趣的点画一条射线(通常是水平线)。
  2. 对射线与路径的每一个相交点,根据相交时路径边界的方向(顺时针或逆时针)进行计数:
    • 如果边界从下到上穿过射线,加1。
    • 如果边界从上到下穿过射线,减1。
  3. 如果最终计数结果不是0,则该点在路径内部;如果是0,则该点在路径外部。
[System.ComponentModel.Description("路径填充模式示例")]
public void Demo05_01(PaintEventArgs e)
{//生成五角星的顶点var pts = CalculateStarPoints(200, 200, 200, 5);//默认填充方式:Alternateusing (var path = new GraphicsPath()){path.AddLines(pts);path.CloseFigure();e.Graphics.DrawPath(Pens.Black, path);e.Graphics.FillPath(Brushes.Green, path);//标志顶点顺序using (var font = new Font("Times New Roman", 15)){for (int i = 0; i < pts.Length; i++){e.Graphics.DrawString(i.ToString(), font, Brushes.Red, pts[i]);}}//修改填充方式path.FillMode = FillMode.Winding;using (var matrix = new Matrix()){matrix.Translate(300, 0);path.Transform(matrix);e.Graphics.DrawPath(Pens.Black, path);e.Graphics.FillPath(Brushes.Red, path);}}
}

构造函数

GraphicsPath()

原型:

public GraphicsPath ();//默认FillMode为Alternate

构造一个填充方式为Alternate的GraphicsPath实例。

GraphicsPath(FillMode)

原型:

public GraphicsPath (System.Drawing.Drawing2D.FillMode fillMode);

构造一个指定填充方式的GraphicsPath实例。

GraphicsPath(Point[],Byte[])和GraphicsPath(PointF[], Byte[])

原型:

public GraphicsPath (System.Drawing.Point[] pts, byte[] types);
public GraphicsPath (System.Drawing.PointF[] pts, byte[] types);

通过指定点集和点集路径类型生成GraphicsPath实例,填充方式为Alternate

GraphicsPath(Point[], Byte[], FillMode)和GraphicsPath(PointF[], Byte[], FillMode)

原型:

public GraphicsPath (System.Drawing.Point[] pts, byte[] types, System.Drawing.Drawing2D.FillMode fillMode);
public GraphicsPath (System.Drawing.PointF[] pts, byte[] types, System.Drawing.Drawing2D.FillMode fillMode);

通过指定点集和点集路径类型生成GraphicsPath实例,并可指定填充方式

//定义点集
var pts = new PointF[]
{new PointF(100,100),new PointF(200,250),new PointF(300,270),new PointF(350,360),                new PointF(270,400)
};
//绘制点和点的序号
using (var font = new Font("Times New Roman", 15))
{for (int i = 0; i < pts.Length; i++){var pt = pts[i];e.Graphics.FillEllipse(Brushes.Red, pt.X-5, pt.Y-5, 10, 10);e.Graphics.DrawString(i.ToString(), font, Brushes.Black, pt);}
}
//定义路径点类型
var types = new byte[]
{(byte)PathPointType.Start,(byte)PathPointType.Line,(byte)PathPointType.Bezier,(byte)PathPointType.Bezier,(byte)PathPointType.Bezier
};
using(var graphicsPath=new GraphicsPath(pts,types))
{e.Graphics.DrawPath(Pens.Black,graphicsPath);
}

构造GraphicsPath

PathPointType

类型
Bezier3默认贝赛尔曲线
Bezier33三次贝赛尔曲线
CloseSubPath128子路径的终点
DashMode16相应的线段是虚线
Line1画线
PathMarker32路径标记
PathTypeMask7用于屏蔽路径类型的高位
Start0路径的起点

属性

FillMode

原型:

public System.Drawing.Drawing2D.FillMode FillMode { get; set; }

获取或设置GraphicsPath的填充方式

PathData

原型:

public System.Drawing.Drawing2D.PathData PathData { get; }

获取该路径的点(Points)与类型(Types)数组。

var rect1 = new Rectangle(200, 100, 250, 150);
var rect2 = new Rectangle(460, 100, 250, 150);
using (var graphicsPath = new GraphicsPath())
{graphicsPath.AddRectangle(rect1);graphicsPath.AddEllipse(rect2);e.Graphics.DrawPath(Pens.Black, graphicsPath);var pathData = graphicsPath.PathData;var pts = pathData.Points;var types = pathData.Types;int offset = 20;using (var font = new Font("Times New Roman", 15)){for (int i = 0; i < pathData.Points.Length; i++){var pt = pts[i];e.Graphics.FillEllipse(Brushes.Red, pt.X - 5, pt.Y - 5, 10, 10);e.Graphics.DrawString(i.ToString(), font, Brushes.Black, pt);DrawString(e, $"({pt.X},{pt.Y}) type:{types[i]}", ref offset);}}
}

PathData示例

PathPoints、PathTypes

等价于PathData的Points和Types

PointCount

原型:

public int PointCount { get; }

获取路径点集或类型的个数。

方法

AddArc添加椭圆弧

原型:

public void AddArc (float x, float y, float width, float height, float startAngle, float sweepAngle);
public void AddArc (int x, int y, int width, int height, float startAngle, float sweepAngle);
public void AddArc (System.Drawing.Rectangle rect, float startAngle, float sweepAngle);
public void AddArc (System.Drawing.RectangleF rect, float startAngle, float sweepAngle);

通过定义一个矩形来确定椭圆,再通过起始角度(x轴顺时针开始)和经过的角度,来确定一条椭圆弧线。

var rect = new Rectangle(200, 100, 300, 200);
using (var graphicsPath = new GraphicsPath())
{//从x轴顺时针30度开始,共画180度的弧graphicsPath.AddArc(rect, 30, 180);e.Graphics.DrawPath(Pens.Red, graphicsPath);graphicsPath.Reset();//从210度开始,共画180度的弧graphicsPath.AddArc(rect.Left, rect.Top, rect.Width, rect.Height, 30 + 180, 180);e.Graphics.DrawPath(Pens.LightGreen, graphicsPath);e.Graphics.DrawRectangle(Pens.Black, rect);e.Graphics.FillEllipse(Brushes.Red, (rect.Left + rect.Right) / 2f - 3, (rect.Top + rect.Bottom) / 2f - 3, 6, 6);
}

画一条红色的椭圆弧从30°到210°,再画一条亮绿的椭圆弧从210°到30°,刚好形成一个椭圆。
AddArc

AddBezier添加贝赛尔曲线

原型:

public void AddBezier (System.Drawing.Point pt1, System.Drawing.Point pt2, System.Drawing.Point pt3, System.Drawing.Point pt4);
public void AddBezier (System.Drawing.PointF pt1, System.Drawing.PointF pt2, System.Drawing.PointF pt3, System.Drawing.PointF pt4);
public void AddBezier (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
public void AddBezier (float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4);

通过添加4个点(1个起始点,2个控制点,1个终止点)来生成一条三次贝赛尔曲线。

// 定义贝塞尔曲线的四个控制点
Point[] bezierPoints = new Point[]
{new Point(50, 200),    // 起点new Point(150, 50),    // 控制点1new Point(250, 350),   // 控制点2new Point(350, 200)    // 终点
};
using (var path = new GraphicsPath())
{//绘制三次贝赛尔曲线path.AddBezier(bezierPoints[0], bezierPoints[1], bezierPoints[2], bezierPoints[3]);e.Graphics.DrawPath(Pens.LightGreen, path);//绘制四个点foreach (var pt in bezierPoints){e.Graphics.FillEllipse(Brushes.Red, pt.X - 3, pt.Y - 3, 6, 6);}e.Graphics.DrawLine(Pens.Red, bezierPoints[0], bezierPoints[1]);e.Graphics.DrawLine(Pens.Red, bezierPoints[2], bezierPoints[3]);
}

定义四个点,生成一条贝赛尔曲线
AddBezier

AddClosedCurve添加封闭基数样条曲线

原型:

public void AddClosedCurve (params System.Drawing.Point[] points);//默认tension=0.5f
public void AddClosedCurve (params System.Drawing.PointF[] points);//默认tension=0.5f
public void AddClosedCurve (System.Drawing.Point[] points, float tension);
public void AddClosedCurve (System.Drawing.PointF[] points, float tension);

添加经过给定点集的基数样条曲线,可通过tension控制曲线的弯曲程度(0至1之间,0最尖锐,1最平滑)

// 定义贝四个点
Point[] pts = new Point[]
{new Point(50, 200),    new Point(150, 50),    new Point(250, 350),   new Point(350, 200)    
};
using (var path = new GraphicsPath())
{path.AddClosedCurve(pts);e.Graphics.DrawPath(Pens.LightGreen, path);path.Reset();path.AddClosedCurve(pts,0.25f);e.Graphics.DrawPath(Pens.Red, path);path.Reset();path.AddClosedCurve(pts, 0.75f);e.Graphics.DrawPath(Pens.Black, path);//绘制四个点foreach (var pt in pts){e.Graphics.FillEllipse(Brushes.Red, pt.X - 3, pt.Y - 3, 6, 6);}
}

给定4个点(与前面贝赛尔曲线相同的四个点),生成不同tension的基数样条曲线。
AddClosedCurve

AddCurve添加基数样条曲线(开放)

原型:

public void AddCurve (System.Drawing.PointF[] points, int offset, int numberOfSegments, float tension);
public void AddCurve (System.Drawing.Point[] points, int offset, int numberOfSegments, float tension);
public void AddCurve (System.Drawing.PointF[] points, float tension);
public void AddCurve (params System.Drawing.Point[] points);//默认tension=0.5
public void AddCurve (params System.Drawing.PointF[] points);//默认tension=0.5
public void AddCurve (System.Drawing.Point[] points, float tension);
参数说明
points待绘制基数样条要经过的点
offset从第几个点开始画曲线(序号为0开始)
numberOfSegments要画几段(两个点之间为1段)曲线
offset+numberOfSegments<=points的个数-1
tension张力系数,指定曲线在控制点之间弯曲量的值,在0到1之间。
大于 1 的值会产生不可预测的结果。

两个基数样条控制点之间的曲线,其它也是一段贝赛尔曲线。
具体算法见下面示例。
通过AddCurve和DrawBezier绘制相同的基数样条曲线。

[System.ComponentModel.Description("GraphicsPath的AddCurve方法Curve转Bezier")]
public void Demo05_07(PaintEventArgs e)
{Point[] controlPoints = {new Point(50, 150), // 控制点1new Point(150, 50), // 控制点2new Point(250, 250), // 控制点3new Point(350, 100),  // 控制点4new Point(450, 150)  // 控制点5};//绘制基数样条曲线的控制点foreach (var pt in controlPoints){e.Graphics.DrawEllipse(Pens.DarkRed, pt.X - 10, pt.Y - 10, 20, 20);}using (var path=new GraphicsPath()){float tension = 0.8f;path.AddCurve(controlPoints, tension);// 绘制基数样条曲线e.Graphics.DrawPath(new Pen(Color.LightGreen, 7), path);// 将基数样条曲线转换为贝赛尔曲线后再绘制for (int i = 0; i < controlPoints.Length - 1; i++){PointF[] bezierPoints = CurveToBezier(i > 0 ? controlPoints[i - 1] : controlPoints[i],controlPoints[i],controlPoints[i + 1],i < controlPoints.Length - 2 ? controlPoints[i + 2] : controlPoints[i + 1],tension);//curve转beziere.Graphics.DrawBezier(Pens.Black, bezierPoints[0], bezierPoints[1], bezierPoints[2], bezierPoints[3]);}//绘制路径所有控制点var dataPoints = path.PathPoints;foreach(var pt in dataPoints){e.Graphics.FillEllipse(Brushes.DarkViolet, pt.X - 5, pt.Y - 5, 10, 10);}}
}
/// <summary>
/// 将四个基数样条控制点转换为贝塞尔曲线控制点
/// </summary>
/// <param name="p0"></param>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <param name="p3"></param>
/// <param name="tension">张力系数(0~1)之间</param>
/// <returns></returns>
private PointF[] CurveToBezier(PointF p0, PointF p1, PointF p2, PointF p3, float tension = 0.5f)
{float t = tension / 3;return new PointF[]{p1,new PointF(p1.X + t * (p2.X - p0.X), p1.Y + t * (p2.Y - p0.Y)),new PointF(p2.X - t * (p3.X - p1.X), p2.Y - t * (p3.Y - p1.Y)),p2};
}

Curve转Bezier
一样定义多个控制点,分多次绘制基数样条曲线

Pen penRed = new Pen(Color.Red, 3);
Pen penLightGreen = new Pen(Color.Green, 1);[System.ComponentModel.Description("GraphicsPath的AddCurve方法分段绘制")]
public void Demo05_08(PaintEventArgs e)
{Point[] controlPoints = {new Point(50, 150), // 控制点1new Point(150, 50), // 控制点2new Point(250, 250), // 控制点3new Point(350, 100),  // 控制点4new Point(450, 150)  // 控制点5};//绘制基数样条曲线的控制点foreach (var pt in controlPoints){e.Graphics.DrawEllipse(Pens.DarkRed, pt.X - 10, pt.Y - 10, 20, 20);}using (var path = new GraphicsPath()){float tension = 0.8f;//从第1个点开始,绘制3段基数样条曲线path.AddCurve(controlPoints,0,3,tension);e.Graphics.DrawPath(penRed, path);path.Reset();//从第2个点开始,绘制3段基数样条曲线path.AddCurve(controlPoints, 1, 3, tension);e.Graphics.DrawPath(penLightGreen, path);}
}

分段绘制基数样条曲线

AddEllipse添加椭圆

原型:

public void AddEllipse (System.Drawing.Rectangle rect);
public void AddEllipse (System.Drawing.RectangleF rect);
public void AddEllipse (int x, int y, int width, int height);
public void AddEllipse (float x, float y, float width, float height);

通过定义矩形来确定一个椭圆路径

var rect = new RectangleF(100, 100, 200, 150);using (var path = new GraphicsPath())
{//添加椭圆路径path.AddEllipse(rect);e.Graphics.DrawPath(penRed, path);e.Graphics.DrawRectangle(penLightGreen,rect.X, rect.Y, rect.Width, rect.Height);
}

绘制一个矩形包着的椭圆
椭圆

AddLine添加线段

原型:

public void AddLine (int x1, int y1, int x2, int y2);
public void AddLine (float x1, float y1, float x2, float y2);
public void AddLine (System.Drawing.Point pt1, System.Drawing.Point pt2);
public void AddLine (System.Drawing.PointF pt1, System.Drawing.PointF pt2);

通过定义两个点的坐标,添加一条线段。

using (var path = new GraphicsPath())
{path.AddLine(150, 150, 300, 300);path.AddLine(300, 300, 0, 300);path.AddLine(0, 300, 150, 150);e.Graphics.DrawPath(penRed, path);
}

添加三条线段围成一个三角形
AddLine

内容太多,另起一篇吧!
【学习笔记】Windows GDI绘图目录

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

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

相关文章

[LLM-Agent]万字长文深度解析规划框架:HuggingGPT

HuggingGPT是一个结合了ChatGPT和Hugging Face平台上的各种专家模型&#xff0c;以解决复杂的AI任务&#xff0c;可以认为他是一种结合任务规划和工具调用两种Agent工作流的框架。它的工作流程主要分为以下几个步骤&#xff1a; 任务规划&#xff1a;使用ChatGPT分析用户的请求…

成犬必备!福派斯鲜肉狗粮,亮毛祛泪痕的神奇功效!

对于成犬来说&#xff0c;选择一款合适且高质量的狗粮至关重要。成犬时期的狗狗正处于身体和生理机能逐渐稳定的阶段&#xff0c;因此&#xff0c;需要选择能够满足其日常营养需求、维持健康状态并有助于长寿的狗粮。理想的狗粮应当包含狗狗所需的各种营养物质&#xff0c;如高…

齐护K210系列教程(三十一)_视觉小车

视觉小车 齐护编程小车端程序动作说明联系我们 在经常做小车任务项目时会用的K210的视觉与巡线或其它动作结合&#xff0c;这就关系到要将K210的识别结果传送给小车的主控制器&#xff0c;K210为辅助传感器&#xff08;视觉采集&#xff09;。 这节课我们用K210识别图像&#x…

Java 解决 古典问题

1 问题 编写一个Java程序&#xff0c;解决以下问题&#xff1a; 2 方法 再导入java.util包下的Scanner类&#xff0c;构建Scanner对象&#xff0c;以便输入。通过对问题的分析&#xff0c;我们可以得到&#xff0c;当位数为1时&#xff0c;其返回值为1&#xff1b;当位数为2时&…

IDEA 将多个微服务Springboot项目Application启动类添加到services标签,统一启动、关闭服务

IDEA 将多个微服务Springboot项目Application启动类添加到services标签&#xff0c;统一启动、关闭服务 首先在Views > Tool Windows > Services 添加services窗口 点击services窗口&#xff0c;首次需要添加配置类型&#xff0c;我们选择Springboot 默认按照运行状态分…

微软如何打造数字零售力航母系列科普11 - 什么是Microsoft Fabric中的数据工程?

什么是Microsoft Fabric中的数据工程&#xff1f; 目录 1. Lakehouse(湖边小屋) 2. Apache Spark Job Definition (作业定义) 3. Notebook(笔记本) 4. Data Pipeline (数据管道) Microsoft Fabric中的数据工程使用户能够设计、构建和维护基础架构和系统&#xff0c;使其组…

LabVIEW舱段测控系统开发

LabVIEW舱段测控系统开发 在航空技术飞速发展的当下&#xff0c;对于航空器的测控系统的需求日益增加&#xff0c;特别是对舱段测控系统的设计与实现。开发了一款基于LabVIEW开发的舱段测控系统&#xff0c;包括系统设计需求、系统组成、工作原理以及系统实现等方面。 开发了…

柱状图中最大的矩形 - LeetCode 热题 73

大家好&#xff01;我是曾续缘&#x1f61b; 今天是《LeetCode 热题 100》系列 发车第 73 天 栈第 5 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xf…

MyBatis实用方案,如何使项目兼容多种数据库

系列文章目录 MyBatis缓存原理 Mybatis plugin 的使用及原理 MyBatisSpringboot 启动到SQL执行全流程 数据库操作不再困难&#xff0c;MyBatis动态Sql标签解析 Mybatis的CachingExecutor与二级缓存 使用MybatisPlus还是MyBaits &#xff0c;开发者应该如何选择&#xff1f; 巧…

【问题处理】maven一直提示artemis-http-client-1.1.8.jar报错(2024-05-25)

项目使用了视频监控&#xff0c;里面涉及到海康威视的视频监控。 问题&#xff1a; pom在导入maven时&#xff0c;报错“Could not find artifact com.artemis:http-client:jar:1.1.8 ” 原因&#xff1a; 根据平台提供的maven地址&#xff0c;填写进pom文件中&#xff0c;编…

汇编-16位汇编环境搭建

16位汇编环境 在学习16位汇编时&#xff0c;我选择的环境是在VMware中安装Windows XP虚拟机来学习&#xff1b;因为Windows XP提供了兼容的DOS环境&#xff0c;可以直接运行和调试16位汇编程序&#xff1b;在win10&#xff0c;win11环境中原生不支持直接运行 16 位程序&#x…

房地产画册制作成手机在线翻页效果

​随着科技的飞速发展&#xff0c;移动互联网已经深入到人们的日常生活中。在这个数字化的时代&#xff0c;房地产行业也紧跟潮流&#xff0c;将画册制作成手机在线翻页效果&#xff0c;以满足消费者的阅读习惯。 房地产画册制作成手机在线翻页效果&#xff0c;不仅能够满足消费…

mac清理软件推荐免费 mac清理系统数据怎么清理 cleanmymac和腾讯柠檬哪个好

macbook是苹果公司的一款高性能的笔记本电脑&#xff0c;受到了很多用户的喜爱。但是&#xff0c;随着使用时间的增长&#xff0c;macbook的系统也会积累一些垃圾文件&#xff0c;影响其运行速度和空间。那么&#xff0c;macbook系统清理软件推荐有哪些呢&#xff1f;macbook用…

263 基于matlab得到的频分复用(FDM,Frequency Division Multiplexing)实现

基于matlab得到的频分复用(FDM&#xff0c;Frequency Division Multiplexing)实现&#xff0c;仿真时录入三路声音信号进行处理&#xff0c;将用于传输信道的总带宽划分成三个子频带&#xff0c;经过复用以后再将录入的声音信号恢复出来。程序已调通&#xff0c;可直接运行。 2…

Docker | 基础指令

环境&#xff1a;centos8 参考&#xff1a; 安装 Docker | Docker 从入门到实践https://vuepress.mirror.docker-practice.com/install/ 安装Docker 卸载旧版本&#xff0c;安装依赖包&#xff0c;添加yum软件源&#xff0c;更新 yum 软件源缓存&#xff0c;安装 docker-ce…

AI助力农田作物智能化激光除草,基于轻量级YOLOv8n开发构建农田作物场景下常见20种杂草检测识别分析系统

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术在各个领域的应用愈发广泛&#xff0c;其中农业领域也不例外。近年来&#xff0c;AI助力农田作物场景下智能激光除草的技术成为了农业领域的一大亮点&#xff0c;它代表着农业智能化、自动化的新趋势。智…

基于地理坐标的高阶几何编辑工具算法(1)——目录

文章目录 背景目录效果相交面裁剪相离面吸附线分割面合并相交面合并相离面矩形绘制整形面 背景 在实际的地图编辑平台中&#xff0c;有一些场景是需要对几何面做修形操作&#xff0c;低效的做法是通过新增形点拖拽来实现。为了提高面几何的编辑效率&#xff0c;需要提供一些便…

Java开发大厂面试第23讲:说一下 JVM 的内存布局和运行原理?

JVM&#xff08;Java Virtual Machine&#xff0c;Java 虚拟机&#xff09;顾名思义就是用来执行 Java 程序的“虚拟主机”&#xff0c;实际的工作是将编译的 class 代码&#xff08;字节码&#xff09;翻译成底层操作系统可以运行的机器码并且进行调用执行&#xff0c;这也是 …

虹科案例丨VLAN不再难懂:一台转换器+交换机轻松解锁VLAN配置

来源&#xff1a;虹科汽车电子 虹科案例丨VLAN不再难懂&#xff1a;一台转换器交换机轻松解锁VLAN配置 原文链接&#xff1a;https://mp.weixin.qq.com/s/5cFLWniozlppQGD7RcvgxA 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #VLAN #转换器 #交换机 导读 还在为…

【Numpy】深入解析numpy中的ravel方法

NumPy中的ravel方法&#xff1a;一维化数组的艺术 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f393; 博主简…