欢迎来到皮皮网网首页

【怎么编译aide源码】【源码 交付 制度】【navmesh原理源码】scale源码分析

来源:crossgate 源码 时间:2024-11-25 09:48:35

1.CSS移动端1px(线条/边框)解决方案
2.BigDecimal转换成String的码分精度问题
3.caffe 中为什么bn层要和scale层一起使用
4.Kubernetes —— Pod 自动水平伸缩源码剖析(上)
5.大屏适配的几种方式
6.android Matrix.setRotate 和 postRotate的区别

scale源码分析

CSS移动端1px(线条/边框)解决方案

       由于不同的手机有不同的像素密度导致的。如果移动显示屏的码分分辨率始终是普通屏幕的2倍,1px的码分边框在devicePixelRatio=2的移动显示屏下会显示成2px,所以在高清瓶下看着1px总是码分感觉变胖了

       小编阅读过其他作者的文章中有写0.5px的写法,在理论上最小的码分单位是1px。所以会出现有的码分怎么编译aide源码设备写0.5px无效(没有边框)的情况。

       如何使用正确的码分1px单位又能在移动设备上显示1px的效果呢?

       本文将介绍使用CSS3的transform属性的scale值来解决这个问题,这也是码分最常用的解决方案。下方的码分源码中说明1px(线条/边框)解决方案

效果对比(效果有点问题,请复制下方源码查看最终效果)源码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,码分initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"><metaname="author"content="helang.love@qq.com"><title>移动端1px(线条/边框)解决方案</title><styletype="text/css">body{ margin:0;padding:0;font-size:px;color:#;font-family:'MicrosoftYaHei','TimesNewRoman',Times,serif;}/*线条*/.list{ margin:px;list-style:none;line-height:px;padding:0;}.list>li{ padding:0;position:relative;}.list>li:not(:first-child):after{ /*CSS匹配非第一个直接子元素*/content:"";display:block;height:0;border-top:#solid1px;width:%;position:absolute;top:0;right:0;transform:scaleY(0.5);/*将1px的线条缩小为原来的%*/}/*边框*//*其他作者可能会通过设置4个边的线条凑出边框线的效果,这样做不仅代码不够精简,码分而且调整圆角问题也会非常麻烦*/.button{ line-height:px;text-align:center;margin:px;background-color:#f8f8f8;position:relative;border-radius:4px;}.button:after{ content:"";position:absolute;top:-%;right:-%;bottom:-%;left:-%;border:1pxsolid#;transform:scale(0.5);transform-origin:%%0;box-sizing:border-box;border-radius:8px;/*尺寸缩小%,码分即圆角半径设置为按钮的码分源码 交付 制度2倍*/}</style></head><body><ulclass="list"><li>线条1px</li><li>web前端河浪</li><li>helang.love@qq.com</li></ul><divclass="button">边框1px</div></body></html>

       作者:黄河爱浪邮箱:helang.love@qq.com

BigDecimal转换成String的精度问题

       在项目中遇到一个价格展示问题,.的码分商品在购物车中显示为.,源于BigDecimal到String的码分转换中精度丢失。为此,对BigDecimal的精度展示进行了深入研究。

       转换方式主要有两种:String.format和price.setScale。首先,采用String.format的原始方法,它依赖于format源码中的fs.print(),尤其printFloat方法,其默认的RoundMode.halfUp策略导致了进位误差。进一步分析,这种模式会自动进行向上取整,navmesh原理源码造成精度损失。

       相比之下,采用price.setScale的方式更具优势。这种方式允许开发者自定义舍入策略,避免了默认进位带来的偏差。在具体实现中,通过divideAndRound方法,可以灵活控制精度。结合toPlainString方法,可以满足各种精度需求,得到更准确的结果。

       总的c 社区源码来说,String.format由于其默认的舍入规则可能导致精度问题,而price.setScale则提供了更多选择,能更好地解决精度转换中的困扰,是更推荐的做法。

caffe 中为什么bn层要和scale层一起使用

       1) 输入归一化 x_norm = (x-u)/std, 其中u和std是个累计计算的均值和方差。

       2)y=alpha×x_norm + beta,对归一化后的x进行比例缩放和位移。其中alpha和beta是通过迭代学习的。

       é‚£ä¹ˆcaffe中的bn层其实只做了第一件事,scale层做了第二件事,所以两者要一起使用。

       ä¸€ï¼Œåœ¨Caffe中使用Batch Normalization需要注意以下两点:

       1. 要配合Scale层一起使用。

       2. è®­ç»ƒçš„时候,将BN层的use_global_stats设置为false,然后测试的时候将use_global_stats设置为true。

       äºŒï¼ŒåŸºæœ¬å…¬å¼æ¢³ç†ï¼š

       Scale层主要完成 top=alpha∗bottom+betatop=alpha∗bottom+beta的过程,则层中主要有两个参数alphaalpha与betabeta,

       æ±‚导会比较简单。∂y∂x=alpha;∂y∂alpha=x;∂y∂beta=1。 需要注意的是alphaalpha与betabeta均为向量,针对输入的channelschannels进行的处理,因此不能简单的认定为一个floatfloat的实数。

       ä¸‰ï¼Œå…·ä½“实现该部分将结合源码实现解析scalescale层:

       åœ¨Caffe proto中ScaleParameter中对Scale有如下几个参数:

       1,基本成员变量,基本成员变量主要包含了Bias层的参数以及Scale层完成对应通道的标注工作。

       2,基本成员函数,主要包含了LayerSetup,Reshape ,Forward和Backward ,内部调用的时候bias_term为true的时候会调用biasLayer的相关函数。

       3,Reshape 调整输入输出与中间变量,Reshape层完成许多中间变量的size初始化。

       4,Forward 前向计算,前向计算,在BN中国紧跟着BN的归一化输出,完成乘以alpha与+bias的操作,由于alpha与bias均为C的向量,因此需要先进行广播。

       5,Backward 反向计算,主要求解三个梯度,对alpha 、beta和输入的bottom(此处的temp)。

Kubernetes —— Pod 自动水平伸缩源码剖析(上)

       ReplicaSet 控制器负责维持指定数量的 Pod 实例正常运行,这个数量通常由声明的工作负载资源对象如 Deployment 中的.spec.replicas字段定义。手动伸缩适用于对应用程序进行预调整,如在电商促销活动前对应用进行扩容,活动结束后缩容。然而,这种方式不适合动态变化的应用负载。

       Kubernetes 提供了 Pod 自动水平伸缩(HorizontalPodAutoscaler,在线佛堂源码简称HPA)能力,允许定义动态应用容量,容量可根据负载情况变化。例如,当 Pod 的平均 CPU 使用率达到 %,且最大 Pod 运行数不超过 个时,HPA 会触发水平扩展。

       HPA 控制器负责维持资源状态与期望状态一致,即使出现错误也会继续处理,直至状态一致,称为调协。控制器依赖 MetricsClient 获取监控数据,包括 Pod 的 CPU 和内存使用情况等。

       MetricsClient 接口定义了获取不同度量指标类别的监控数据的能力。实现 MetricsClient 的客户端分别用于集成 API 组 metrics.k8s.io,处理集群内置度量指标,自定义度量指标和集群外部度量指标。

       HPA 控制器创建并运行,依赖 Scale 对象客户端、HorizontalPodAutoscalersGetter、Metrics 客户端、HPA Informer 和 Pod Informer 等组件。Pod 副本数计算器根据度量指标监控数据和 HPA 的理想资源使用率,决策 Pod 副本容量的伸缩。

       此篇介绍了 HPA 的基本概念和相关组件的创建过程,后续文章将深入探讨 HPA 控制器的调协逻辑。感谢阅读,欢迎指正。

大屏适配的几种方式

       在开发中,大屏适配有多种策略可供选择,包括rem、vw/vh、scale方案以及相关的开源组件库。首先,rem方案通过调整HTML根节点的字体大小,实现根据不同屏幕大小的动态适配。vw/vh方案则是基于设计稿的相对百分比,确保在不同分辨率下保持一致的视觉效果。

       scale方案针对*(:9)设计稿,提供了两种方法:一是按宽度缩放,适用于对宽度变化敏感的应用;二是动态计算网页宽高比,以便根据屏幕尺寸进行更精准的缩放。开源组件库如autofit.js,利用比例缩放原理,通过调整容器尺寸实现全屏填充,保持布局一致性,适合跨分辨率项目。安装、配置和源码地址可以在其官方文档中找到。

       另一种组件是v-scale-screen,专为大屏项目设计,支持宽度、高度和宽高比自适应,适用于React开发者。安装和配置同样需要参考其文档。FitScreen则基于设计草图的像素尺寸,通过缩放实现简单的大屏适配,兼容vue2、vue3和React框架,只需少量代码即可实现。

       总的来说,这些方法各有利弊,开发者需要根据项目需求和具体技术栈选择最适合的适配方式。在实际应用中,务必确保在各种屏幕尺寸上都能提供良好的用户体验。

android Matrix.setRotate 和 postRotate的区别

       Matrix主要用于对平面进行平移(Translate),缩放(Scale),旋转(Rotate)以及斜切(Skew)操作。

       ä¸ºç®€åŒ–矩阵变换,Android封装了一系列方法来进行矩阵变换;其中包括:

       set系列方法:setTranslate,setScale,setRotate,setSkew;设置,会覆盖之前的参数。

       pre系列方法:preTranslate,preScale,preRotate,preSkew;矩阵先乘,如M' = M * T(dx, dy)。

       post系列方法:postTranslate,postScale,postRotate,postSkew;矩阵后乘,如M' = T(dx, dy) * M。

       é€šè¿‡å°†å˜æ¢çŸ©é˜µä¸ŽåŽŸå§‹çŸ©é˜µç›¸ä¹˜æ¥è¾¾åˆ°å˜æ¢çš„目的,例如:

       å¹³ç§»ï¼ˆx'=x+tx;y'=y+ty):

       ç¼©æ”¾ï¼ˆx'=sx*x;y'=sy*y):

       æ—‹è½¬ï¼ˆx'=cosβ*x-sinβ*y;y'=sinβ*x+cosβ*y):

       é€‰æ‹©éœ€è¦ç”¨åˆ°å¦‚下的三角函数的公式:

       â‘ sin(α+β)=sinαcosβ+cosαsinβ

       â‘¡cos(α+β)=cosαcosβ-sinαsinβ

       å…¬å¼â‘ å¯ä»¥ç”±å•ä½åœ†æ–¹æ³•æˆ–托勒密定理推导出来。

       æŽ¨å¯¼è¿‡ç¨‹å‚见:/s/blog_fcj.html

       æ–œåˆ‡ï¼ˆx'=x+k1*y;y'=k2*x+y):

       //源码文件:external\skia\legacy\src\core\SkMatrix.cpp

       #define SK_Scalar1 (1.0f)

       #define kMatrixElem SK_Scalar1

       typedef float SkScalar;

       #define SkScalarMul(a, b) ((float)(a) * (b))

       enum {

        kMScaleX, kMSkewX, kMTransX,

        kMSkewY, kMScaleY, kMTransY,

        kMPersp0, kMPersp1, kMPersp2

       };

       void SkMatrix::reset() {

        fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; //其值为1

        fMat[kMSkewX] = fMat[kMSkewY] =

        fMat[kMTransX] = fMat[kMTransY] =

        fMat[kMPersp0] = fMat[kMPersp1] = 0; //其值,全为0

        fMat[kMPersp2] = kMatrixElem; //其值为1

        this->setTypeMask(kIdentity_Mask | kRectStaysRect_Mask);

       }

       void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) {

        if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {

        fMat[kMTransX] = dx; //以新值dx覆盖原值,原值无效了

        fMat[kMTransY] = dy;

        fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; //其值为1

        fMat[kMSkewX] = fMat[kMSkewY] =

        fMat[kMPersp0] = fMat[kMPersp1] = 0; //其值,全为0

        fMat[kMPersp2] = kMatrixElem; //其值为1

        this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask);

        } else {

        this->reset();

        }

       }

       bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) {

        if (this->hasPerspective()) {

        SkMatrix m;

        m.setTranslate(dx, dy);

        return this->preConcat(m); //矩阵的先乘运算

        }

        if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {

        fMat[kMTransX] += SkScalarMul(fMat[kMScaleX], dx) +

        SkScalarMul(fMat[kMSkewX], dy); //先乘,需要矩阵运算过

        fMat[kMTransY] += SkScalarMul(fMat[kMSkewY], dx) +

        SkScalarMul(fMat[kMScaleY], dy);

        this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);

        }

        return true;

       }

       bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) {

        if (this->hasPerspective()) {

        SkMatrix m;

        m.setTranslate(dx, dy);

        return this->postConcat(m); //矩阵的后乘运算

        }

        if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {

        fMat[kMTransX] += dx; //后乘,直接加新值dx即可

        fMat[kMTransY] += dy;

        this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);

        }

        return true;

       }

       bool SkMatrix::preConcat(