射线法判断点在多边形内:原理、实现与边界条件详解
判断点在多边形内射线法是我几乎每天都在用的算法。在地图引擎、游戏碰撞检测、图像标注工具里它都是最基础的那块拼图。这算法听起来高深其实核心就一句话从目标点朝任意方向射出一条射线数一数它和多边形边界相交了几次交点个数是奇数就在内部偶数就在外部。就这么朴素但它把“几何包含关系”变成了一次简单的计数几十年来都没被淘汰。这篇文章适合刚接触计算几何的开发者也适合被顶点相交、浮点精度折磨过的老手。我会从原理讲到完整实现再重点拆解那些教科书里不会明说的边界条件——也就是真正决定算法能不能用的地方。如果你只需要一个能跑的方案可以直接跳到第2节抄代码如果你想搞清楚为什么这么写甚至连射线为什么不能随便乱选方向这种细节都想弄明白那就从头往下看。1. 射线法的核心原理与算法步骤1.1 从生活直觉到数学判定先忘掉代码想象你在一个形状不规则的地块旁边手里拿一根激光笔站在某个不确定是不是在地块内部的点位上朝正东方向发射一束激光。激光穿出地块边界的时候你会记录一次“穿越”。如果最终穿越次数是奇数说明激光是从地块内部出发的如果是偶数说明激光是从外部射进来的。这个直觉就是射线法的全部。为什么奇数/偶数能判定内外因为多边形边界是闭合的一条直线穿过闭合区域时必然是一会儿进一会儿出。从外部出发进入一次、出去一次成对出现最后一定是偶数从内部出发第一次就是出界最后一定是奇数。这不需要任何复杂的拓扑学画个图就能验证。不过这里有个容易忽略的点射线方向的选择。理论上任意方向都可以但为了把“线段求交”的数学公式尽量简化几乎所有实现都选水平向右的射线。原因很实际水平射线可以固定某个坐标比如y不变求交点时只需要算x坐标与线段端点x坐标的关系避免了对任意直线方程做繁琐的联立求解。这个取舍让每次相交测试的运算量降到几个比较和一次除法在数百万次调用场景下性能差异巨大。1.2 标准实现流程与关键公式射线法的标准流程分四步第一遍历多边形的每条边每条边由两个连续顶点xi, yi和xj, yj定义最后一条边记得从末顶点绕回首顶点。第二判断这条边是否“跨越”了射线所在的水平线。这里不能用简单的yi y或者yj y因为顶点刚好落在射线高度时会产生重复计数。业界通用的做法是“上闭下开”规则只有当 (yi y) ! (yj y) 时才认为边的两个端点位于射线水平线的两侧。这样顶点即使正好在y坐标上也只被计数一次不会算重。第三如果边跨越水平线就计算射线与线段的交点的x坐标。根据相似三角形公式是x_intersect xi (y - yi) * (xj - xi) / (yj - yi)第四比较x_intersect和目标点的x坐标。如果大于x说明交点在目标点右侧计数加一如果等于x说明目标点就在这条边上如果小于x忽略。遍历完所有边之后交点数为奇数则在多边形内偶数则在多边形外。整段逻辑连一个三角函数都用不到全是四则运算和比较这正是它成为基础算法的原因。1.3 为什么用射线法而不是其他方法接触过计算几何的人可能还会想到其他方案角度和法、叉积法、网格剖分法。拿它们和射线法对比你才能理解为什么射线法在工程里最常用。角度和法需要把目标点和多边形每个顶点连起来计算所有夹角之和。若和等于360度则在内部等于0度则在外部。这个方法数学上是严谨的但每次要调用atan2计算角度既有三角函数开销又容易被浮点误差影响边界情况极难处理。叉积法通常只适用于凸多边形。判断一个点是否在所有边的同一侧效率很高但遇到凹多边形直接失效。实际业务场景里的地块、行政区划、UI热区哪有那么多凸多边形。网格剖分法比如扫射线把多边形切成梯形或三角形需要预处理一次判断速度极快但构建索引的代价不是所有场景都能接受。射线法不需要任何预处理存储只依赖多边形本身的顶点列表一个点算一次也是这个复杂度一万个点算一万次也依然是O(n)实用性拉满。所以技术选型的逻辑很清晰射线法是通用性、简单性、可维护性之间的最佳平衡点。当你只需要回答“点在不在里面”时没必要引入更重的数据结构。2. 手把手实现从伪代码到可运行代码2.1 数据结构与输入约定动手写代码之前先把输入约定想清楚否则后面全是坑。我习惯用两个数组分别存x坐标和y坐标也可以用点对象列表。这里统一用点对象列表每个点至少包含x和y两个属性。多边形约定为“环”也就是按顺序排列的顶点序列最后一个顶点不需要和第一个顶点重复。比如一个矩形可以表示为[(0, 0), (4, 0), (4, 3), (0, 3)]而不是把(0,0)写在末尾再写一次。如果你拿到的数据是闭合环首尾重复实现里要先判断并去掉最后那个重复点或者在遍历边时跳过首尾相同的边。另一个约定是坐标系。射线法本身不关心坐标是屏幕像素坐标还是经纬度坐标只要所有数值处于同一坐标系乘法除法不会溢出就行。但经纬度坐标在跨180度经线时会出幺蛾子这个我会在第4节单独讲。2.2 基础实现Python版本我尽量写一个没有花哨语法、不依赖外部库的Python实现方便你直接搬到C、JavaScript、Go等任何语言。第一个版本先实现“纯射线计数”暂不处理点在边上的情况def point_in_polygon_ray(point, polygon): x, y point n len(polygon) inside False j n - 1 for i in range(n): xi, yi polygon[i] xj, yj polygon[j] # 判断边是否跨越射线所在的水平线上闭下开 if (yi y) ! (yj y): # 计算边与水平线交点x坐标 x_intersect (xj - xi) * (y - yi) / (yj - yi) xi # 只统计交点位于目标点右侧的情况 if x_intersect x: inside not inside j i return inside这里用的是“每次交点就翻转inside”的写法效果等同于数奇偶。注意我在循环外维护了一个j让它指向前一个顶点这样不需要额外处理闭合回绕也避免了重复创建对象。这段代码已经能处理绝大多数常规多边形。但如果目标点恰好落在边上它会根据边的方向随机返回True或False这是不可接受的。完整版本必须把“点在边上”的情况显式判断出来。2.3 完整实现与边界处理完整版在每一条边求交点之后先判断点是否在边上再判断是否要翻转inside。判断点在边上的方法有很多我推荐用“跨立实验叉积为零”的方式因为已经有了交点x坐标可以直接比较目标点是否在线段范围内。下面这段代码我实际用在多个项目里处理了顶点相交和边重合问题def point_in_polygon(point, polygon): x, y point n len(polygon) inside False j n - 1 for i in range(n): xi, yi polygon[i] xj, yj polygon[j] # 快速检测点是否在这条边的包围盒内 if min(xi, xj) x max(xi, xj) and min(yi, yj) y max(yi, yj): # 叉积判断是否共线 cross (xj - xi) * (y - yi) - (yj - yi) * (x - xi) if abs(cross) 1e-9: return True # 点在边上 # 射线求交上闭下开规则避免顶点重复计数 if (yi y) ! (yj y): x_intersect (xj - xi) * (y - yi) / (yj - yi) xi if x_intersect x: inside not inside j i return inside关键点全在这个函数里首先是叉积判断点是否在边上。叉积为零表示目标点和线段端点共线再配合包围盒判断保证目标点的坐标确实落在线段范围内而不是在延长线上。严格说这个快速包围盒条件已经把大多数不可能情况过滤掉了所以这段代码在日常使用中性能也不会太差。其次是“上闭下开”规则。当顶点yi和yj都不大于y时条件为False这条边不会参与计数。这样当射线恰好穿过一个顶点时只有一侧的边会统计这个顶点不会出现一个顶点被两条邻边各计一次导致奇偶翻转被抵消的情况。这就是射线法最容易踩的坑不少经典教材里的旧实现都栽在这里。最后是浮点精度。叉积判断用了1e-9作为阈值这个值不是随便拍的。如果你的坐标是整数像素坐标可以放宽到1e-6如果是经纬度坐标1e-9已经比较严格但还要结合坐标量级调整。后面我专门写一节讲精度问题。2.4 一个可直接验证的示例拿一个凹多边形做测试最能说明问题。比如多边形顶点为[(0,0), (4,0), (4,4), (2,2), (0,4)]这个形状像个倒置的勺子凹口在右边。用上面的函数测试几个点点(1,1)肉眼可见在多边形内部函数应该返回True。点(3,1)虽然在(4,0)到(4,4)右边线的左边但它在凹口外部区域实际是False。点(2,2)正好落在(4,4)到(2,2)这条边的端点上应该返回True。我实测一遍手算一下点(3,1)的求交过程从(2,2)到(0,4)这条边水平线y1并没有被跨越因为两个点的y都大于1条件为False从(4,0)到(2,2)这条边y1在0和2之间跨越条件成立计算x_intersect (2-4)*(1-0)/(2-0)4 3恰好等于目标点x3。这里需要注意我的代码里判断是x_intersect x严格大于所以这个交点没有计数。最终交点数为偶数结果False。这个设计是为了配合点在边上时已经提前返回True避免边界归属混乱。如果你想用就把点在边上的判断放在前面结果一致。3. 边界条件与坑位排查3.1 点在边上、顶点相交怎么办第2节的代码已经处理了这两种情况但我想再啰嗦几句为什么必须处理以及处理不当会发生什么。点在边上时理论上“内部”和“外部”的边界归属取决于你的应用。地图选点工具通常会算作命中内部游戏碰撞里可能算作碰撞GIS里的拓扑校验可能要求单独返回“在边界上”的状态。如果你只需要布尔值那么返回True是最符合直觉的。顶点相交更危险。假设一个不带“上闭下开”的旧版本算法从点向右发射射线恰好经过多边形某个顶点而该顶点两侧的两条边都跨越了同一水平线那么这个顶点会被计数两次两个交点一抵消奇偶性又恢复原状结果碰巧正确但另一些顶点构型下两条边可能一条跨越一条不跨越计数一次结果就是错误的。这个错误不是理论威胁而是实际在多边形密集的网格数据中反复出现表现为某些点反复横跳一会儿在内一会儿在外。3.2 射线穿越顶点和与边重合的经典Bug与边重合是射线法另一个臭名昭著的坑。当多边形有一条边恰好和射线所在的水平线重叠时比如y坐标相同的水平边如果只按“跨越”条件处理这条水平边根本不会被计入因为yi y和yj y同为False。这是正确的不需要额外处理。但问题出在水平边的端点与另一条非水平边的端点共用顶点时。比如水平边从(2,2)到(4,2)另一条斜边从(4,2)到(5,3)射线从点(1,2)向右射。如果不做任何处理当遍历到水平边时两个y都等于2不算跨越遍历到斜边时(2 2) ! (3 2)跨越条件成立会计算一个交点。顶点(4,2)仍然只被计数一次结果是对的。真正容易翻车的是另一种情况多边形存在两条边共享同一顶点并且该顶点在射线高度上而这两条边分别在射线的两侧。旧版射线法经常会把这个顶点同时算给两条边或者都不算给两条边。用“上闭下开”规则后只有当一条边的某个端点严格大于y另一个端点小于等于y时才跨越。这样一来顶点只会被计入一次因为从大于y到小于等于y的那一侧边被计入从小于等于y到大于y那一侧边不被计入。这个规则的记忆方法很简单把所有顶点当作一个“半边在下、半边在上”的开区间永远只统计从上方穿到下方的那一侧。3.3 奇偶规则 vs 非零环绕数射线法常见的有两套判断准则奇偶规则Even-Odd Rule和非零环绕数Nonzero Winding Number。它们对简单多边形的判定结果一致但对自相交多边形会产生差异。奇偶规则就是我上面讲的任何一条边穿过射线就翻转一次。自相交多边形就像两笔画出来的回字形中间交叉某些区域在奇偶规则下会被判为外部但在环绕数规则下被判为内部。原因是环绕数会考虑边的方向按逆时针方向累计角度变化如果累计值非零则判定为内部。不少商业图形库默认采用非零环绕数因为它能正确处理带洞或者重叠路径的图形。但非零环绕数需要计算射线与边的带符号交点每条边要区分向上还是向下穿越逻辑比奇偶规则复杂一些。我的建议是如果你的数据来源是GIS或游戏碰撞体基本都是简单多边形用奇偶规则已经足够如果你在解析SVG路径或字体轮廓那些数据里可能有自相交或重叠的腱规则就必须用非零环绕数。def point_in_polygon_winding(point, polygon): x, y point n len(polygon) winding 0 j n - 1 for i in range(n): xi, yi polygon[i] xj, yj polygon[j] if yi y: if yj y and (xj - xi) * (y - yi) (x - xi) * (yj - yi): winding 1 else: if yj y and (xj - xi) * (y - yi) (x - xi) * (yj - yi): winding - 1 j i return winding ! 0这段代码用叉积判断交点是否在点右侧同时根据边的方向决定交点是正向还是负向。绕数不为零即内部。它比奇偶规则多了一点运算但换来了对路径缠绕的宽容。3.4 多边形方向、坐标精度、浮点误差处理多边形顶点顺序在射线法中其实不重要奇偶规则对顺时针和逆时针都一视同仁。但如果你在同一个系统里既要判断点又要计算面积最好统一要求顶点按逆时针顺序存储这样面积、法向量、填充规则都能保持一致。浮点误差是个大话题。射线法的运算量小但除法容易放大误差。比如顶点坐标达到上百万的经纬度值保留6位小数在计算x_intersect时(y-yi)/(yj-yi)这个比例可能非常接近0或1导致乘法的舍入误差被放大。解决思路有三层第一层优先用叉积代替直接求交点。某些判断场景其实不需要算出具体的x_intersect只需要知道交点与目标点的左右关系可以直接用叉积符号判断。这样既减少了一次除法也减少了误差。第二层对坐标做中心平移。把多边形所有顶点都减去一个固定基准点比如多边形的包围盒中心将坐标数量级缩放到0~100之间再进行射线法。这个技巧在地图跨大面积区域时特别有效。第三层设置合理的epsilon。点在边上的叉积判断不要用0要根据坐标量级设阈值。整数坐标可以用1e-6浮点坐标最好用1e-9再乘以坐标范围。千万别搞什么“一刀切”的全局精度不同数据源误差天差地别。4. 性能优化与工程应用细节4.1 包围盒快速排除射线法虽然只有O(n)复杂度但n很大时比如几万个顶点的地块边界每个点都遍历一遍还是有点心痛。最常见的优化是先做多边形包围盒遍历顶点时顺便求出最小x、最小y、最大x、最大y存下来。判断新点时如果点不在包围盒内直接返回False不需要进入射线求交循环。def build_bbox(polygon): xs [p[0] for p in polygon] ys [p[1] for p in polygon] return (min(xs), min(ys), max(xs), max(ys)) def point_in_polygon_fast(point, polygon, bbox): x, y point min_x, min_y, max_x, max_y bbox if x min_x or x max_x or y min_y or y max_y: return False return point_in_polygon(point, polygon)这个优化的收益在凹多边形场景下特别明显。很多点根本不在包围盒内一个O(1)判断就扔掉了。就算点在包围盒内也只是进入原来的逻辑没有额外负担。4.2 数据量大的场景怎么加速如果多边形数量很多而不是单个多边形顶点很多比如地图上有几万个行政区每次请求要判断点落在哪个区域那单靠射线法一个个试肯定不够。常见的加速方案是网格索引或空间索引。网格索引的做法是把整个范围切分成粗粒度格子每个格子记录可能包含这个点的多边形列表。请求到达时先定位到格子再对格子里的多边形做射线法。这个方案实现简单适合多边形分布比较均匀的场景。更通用的是R树或四叉树。很多内存数据库和GIS库都内置了这类索引。我自己的经验是数据量小于一万个多边形时暴力遍历加包围盒就足够超过十万个格时务必引入索引否则单次请求就会超过50毫秒用户体验明显变差。射线法本身也还能再做一点微优化把多边形存储为两个数组x数组和y数组而不是点对象数组这样在循环里能减少属性访问开销提前把首顶点复制到尾后用“for i in range(n): j (i 1) % n”的方式访问不过取模操作有额外开销实际要用性能分析说话别盲信。4.3 在GIS、游戏碰撞、图像处理中的应用细节GIS里最常见的是经纬度坐标。经纬度不是平面坐标但射线法在判断包含关系时天然对“平面坐标”有效。原因是一个地理区域的边界通常不会跨越反经线即经度从-180到180跳变如果跨越了就需要先做投影或对经度做平移处理。另一种处理方式是把-180到180映射到0到360让边界连续。我在一个涉及跨越太平洋的航线多边形上就踩过这个坑后来统一做经度归一化才修复。游戏开发中射线法多用于鼠标点击拾取Picking。屏幕上的UI多边形往往是凸多边形用叉积法更高效。但如果涉及不规则碰撞体或地图上的区域判定射线法还是首选。需要注意游戏引擎的坐标系Y轴朝下而我们日常数学习惯Y轴朝上奇偶规则不关心Y轴方向所以可以无脑适用这是射线法的又一个好处。图像处理里的应用更微妙。比如在标注工具里填充一个多边形区域需要逐像素判断是否在多边形内部。如果图片是1920x1080直接对每个像素跑射线法性能会非常难看。正确的做法是先用扫描线把多边形内部的行区间算出来然后逐行填充一次像素判断退化为区间判断。射线法是扫描线算法的基础明白射线法之后你能更好地理解图像矢量填充的原理。4.4 与GeoJSON/WKT等格式结合的注意点GeoJSON的Polygon类型可能是“外部环内部洞”的结构。一个带洞的多边形实际上由多个环组成外环逆时针内环顺时针。判断点是否在几何体内部时先判断点是否在外环内同时要确保不在任何一个内洞内。用射线法分别判断每个环然后“外环结果 AND (OR 每个洞取反)”。WKT格式里的POLYGON((外环),(洞1),(洞2))也是类似。很多开发者只判断了外环导致洞区域也被错误判定为内部。遇到这种情况我建议封装一个函数接收外环和洞列表def point_in_polygon_with_holes(point, exterior, holes): if not point_in_polygon(point, exterior): return False for hole in holes: if point_in_polygon(point, hole): return False return True注意这里的hole方向是否被翻转不重要因为射线法对方向无感只要顶点顺序构成闭合环就行。还要注意GeoJSON的坐标系是经纬度但坐标数值通常保留6位小数用float64存储没有问题但在3.4节提到的误差处理还是要做。5. 常见问题与实战排查速查5.1 典型问题1:射线经过顶点现象同一个点在不同次调用中结果不稳定或者明显在内部的点被判为外部。原因射线恰好穿过多边形某个顶点导致该顶点的两条邻边都被计数或者都被跳过奇偶性翻转次数不对。解决严格采用“上闭下开”条件 (yi y) ! (yj y)。这个条件确保当两个端点在y高度两侧时才计算交点等于y的端点不会触发跨越。说白了就是把射线稍微“抬起来”0.000001个像素避免刚好压在顶点上。在代码里不真的抬高而是用开闭区间模拟。5.2 典型问题2:点在边界上现象点在多边形边上但结果有时返回True有时返回False无法稳定表达“边界命中”。原因纯射线计数算法没有显式检测点在边上的情况边的方向会影响最终计数。解决在每次遍历边时加入叉积判断如果点与线段共线且点的坐标在线段包围盒内直接返回True。注意返回True前要确认这不是“假共线”例如浮点误差导致的叉积极小值。设置合适的epsilon并检查包围盒条件缺一不可。5.3 典型问题3:退化多边形/自相交多边形现象多边形有两个连续重复顶点、有零长度边、或者边与边交叉。原因零长度边会导致除法分母为零自相交会导致奇偶规则和环绕数规则结果不一致。解决数据预处理阶段先去除重复顶点。遇到分母为零时直接跳过该边。对自相交多边形如果业务允许优先换成非零环绕数算法如果业务不允许比如GIS强约束简单多边形那就在数据校验阶段拒绝这类多边形。5.4 经验表我把常见场景对应的方案整理成一张表方便你排查时直接对号入座症状原因解决方案结果时对时错射线经过顶点使用上闭下开条件点在边上误判缺边界检测叉积包围盒判断带洞区域被误判只判断外环分别判断内洞并对结果取反坐标跨180经线经度不连续经度偏移到连续坐标系大坐标下误差大除法放大了舍入误差中心平移 epsilon调整数据量大时太慢每次都遍历全部顶点包围盒快速排除 空间索引5.5 一个真实场景的排查实录有次我在做某跨平台地图系统时发现某个行政区域的选中判定在边缘坐标上总是漂移。最初以为是坐标精度不够把经纬度从小数点后6位加到8位也没用。后来打印出所有交点计算过程才发现是因为多边形顶点是从数据库动态加载的每次加载顺序不一致导致某个顶点在射线正下方和射线正上方之间抖动触发了顶点重复计数bug。换成“上闭下开”之后问题立刻消失。这个经历告诉我射线法虽然简单但数据源的微小差异就能引爆边界问题写代码时宁可把规则写得死板一点也不要依赖“碰巧正确”。6. 我在实际项目中的专属建议最后分享几个我自己踩过坑之后总结的习惯。第一个习惯是永远先写测试用例。不要只在纸上画一个四边形验证要准备凸多边形、凹多边形、带洞多边形、自相交多边形、点在边上、顶点刚好与射线同高、坐标极大极小等各种案例。我用一组约五十个点的多边形做回归测试每次改射线法实现都跑一遍确保不会因为优化破坏边界行为。第二个习惯是尽量别自己去实现有洞多边形的处理。如果项目允许引入外部几何库直接用成熟的库更省心。但就算用库也得明白库背后的射线法原理否则你很难判断某个bug是数据问题还是算法问题。第三个习惯是能用整数坐标就不用浮点坐标。像素级UI、网格数据、磁贴数据都可以用整数坐标叉积运算完全不会出现误差问题。只有经纬度、物理单位数据才需要浮点那时再启动epsilon策略。射线法真正的价值不在于算法本身有多高明而在于它把复杂几何问题降维成了一个稳定可靠、可测试、可解释的计数问题。你在一个项目里把这个基础打牢了后面再碰到多边形面积、线段求交、点集凸包都会顺手很多。希望这篇内容能让你少踩一些我当年踩过的坑。

相关新闻

多Agent技能管理实战:用GNU Stow和chezmoi建立唯一事实源

多Agent技能管理实战:用GNU Stow和chezmoi建立唯一事实源

1. 事故现场:同一个 skill,怎么可能存了三份上半年我在团队里搭了一套多 agent 的日常工具链,角色也不复杂:一个负责代码评审,一个负责日志排查,一个负责数据查询。最开始为了赶进度,每个 agent…

2026/10/12 12:29:44 阅读更多 →
MyEclipse 2021安装配置与避坑指南:JDK、Tomcat及编码排错

MyEclipse 2021安装配置与避坑指南:JDK、Tomcat及编码排错

简介:MyEclipse 2021.5.24a 是面向 Java 开发者的一体化 IDE 资源包,覆盖 Java SE/EE/ME 桌面应用与 Web 开发场景,也适合使用 Spring、Struts、Hibernate、Tomcat、GlassFish 以及 MySQL 等数据库连接的企业级项目,初学者搭建环境…

2026/10/12 12:29:44 阅读更多 →
HTTP与RPC接口测试实战:从协议差异到用例设计与线上排错

HTTP与RPC接口测试实战:从协议差异到用例设计与线上排错

做接口测试这几年,我把 Postman、Jmeter、Apifox、grpcurl 这些工具换了一轮,最后发现工具只是表面,真正决定测试质量的是你对 HTTP 和 RPC 这两套协议的理解深度。很多人觉得接口测试就是发个请求、看个状态码,真到线上出问题的时…

2026/10/12 12:29:44 阅读更多 →

最新新闻

Vue实战进阶:从环境配置到动态路由与多端部署要点

Vue实战进阶:从环境配置到动态路由与多端部署要点

学Vue这几年,从最开始只会照着教程敲todo list,到后来完整负责过好几个基于Spring Boot加Vue的前后端分离项目,中间踩过的坑、绕过的弯,攒下来不少东西。这份Vue网站制作学习心得,我按“从入门到实战的进阶之路”来写&…

2026/10/12 13:21:33 阅读更多 →
豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

简介:这份资源是面向高校学生与Python初学者的数据可视化课程设计完整方案,围绕豆瓣电影Top250数据集展开,涵盖数据采集、清洗、统计分析与图表呈现全流程,适合用作毕业设计、期末大作业或课程设计的高分参考。压缩包共221个文件&…

2026/10/12 13:21:33 阅读更多 →
基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

每年到这个时间点,都会有一批学弟学妹来问我:"毕设选题到底怎么选?Java后端会不会太难?前端是不是要写很多页面?"我的回答一直很统一:如果方向是Java Web或全栈开发,基于SpringBoot …

2026/10/12 13:21:33 阅读更多 →
claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

你有没有过这种体验:跟Claude聊一个项目,前期费了好大劲把背景、依赖、约束讲清楚,刚进入正题,上下文窗口满了,或者新开一个会话,全部打回原形。每次对话就像金鱼一样,七秒记忆,项目…

2026/10/12 13:21:33 阅读更多 →
云数据库HTTP API歌单更新实战:权限、批量与避坑指南

云数据库HTTP API歌单更新实战:权限、批量与避坑指南

1. 从一次歌单同步的诡异失败说起做云音乐类小程序,绕不开的一个核心功能就是歌单管理。用户在小程序端新建、编辑、删除歌单,这些操作最终都要落到云数据库里。我最近在重构一个云音乐小程序的管理系统,前面几篇已经把基础架构、页面路由、用…

2026/10/12 13:21:33 阅读更多 →
C++中判断汉字:从编码原理到跨平台实现

C++中判断汉字:从编码原理到跨平台实现

1. 从一次文本统计翻车说起:为什么“判断汉字”没那么简单前阵子帮一个做数据清洗的朋友处理一批用户提交的文本,需求听起来特别朴素:把每条记录里的汉字挑出来,统计一下字数,非汉字的字符(标点、数字、字母…

2026/10/12 13:20:31 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →