当前位置: 首页 > news >正文

用 【C# + WinUI3 + 图像动画】 来理解:高数 - 函数 - 初等函数

目录

函数分类

常数函数

绝对值函数

符号函数

阶梯曲线

多公式分段函数

函数类型总结

基本初等函数

幂函数

指数函数

对数函数

三角函数

反三角函数

学习感悟                                

作为一个高数小白,在学习函数这一节来说,最大的感受就是,怎么这么多公式,简直记不住,虽然中学的时候会学到这些知识,但是已经忘得一干二净了,并且完全不知道这些公式可以真的去用到什么地方,我可以用这些公式去达到哪些效果?

既然记不住公式,那么我希望通过图像化加深对它们的视觉记忆,转化为”感觉“、“直觉”。


函数分类

函数大致分为 常数函数、绝对值函数、符号函数、阶梯曲线、分段函数 ,下面分别演示。

常数函数

例如公式 Y=2,不管自变量怎样变化(此处无自变量),因变量始终为一个固定的数值, 映射到图像中可以是:从绝对变化图来看,不管坐标怎样变化,每个点颜色值始终相同 ;从增量变化图来看,不管坐标怎样变化,每一点的颜色值 增量值 始终相同。

那么 绝对变化图 和 增量变化图 两者的形态分别为 :

这个函数简单到不需要特殊记忆,一看便知,视觉感觉:恒定、平稳、无奇。

WinUI3 部分处理代码:

private async Task ApplyDualImageEffect()
{if (originalPixelData == null) return; var incrementPixels = new byte[originalPixelData.Length];for (int i = 0; i < incrementPixels.Length; i += 4){incrementPixels[i] = ClampByte(originalPixelData[i] + incrementValue);     // BincrementPixels[i + 1] = ClampByte(originalPixelData[i + 1] + incrementValue); // GincrementPixels[i + 2] = ClampByte(originalPixelData[i + 2] + incrementValue); // RincrementPixels[i + 3] = originalPixelData[i + 3]; // A}var processedBitmap = await CreateBitmapFromPixelData(incrementPixels, imageWidth, imageHeight);ProcessedImage.Source = processedBitmap;
}

绝对值函数

这个公式叫做绝对值函数,对它的理解方式是:

当自变量小于零的时候,因变量就取值为它的负数,

当自变量不小于0的时候,因变量就取值它本身。

那么映射到图像处理中,从绝对变化图效果来看,可以类似地理解为,颜色有效值范围是 0~255,假设以 128 为虚拟零点,当灰度值 小于 中间值128,那么取值为该点颜色值的 对称值,以128为对称点,比如某个点的颜色值是 148 ,那么 以 128 为对称点,将要取的值就是 108;当大于128的时候 ,则始终保持为它本身 。同理,将该转换作为 增量值 附加到原图,比如 X 小于128的时候 ,增量值 为固定的 -20,当 x 大于等于128 的时候 增量值为固定的 20。

那么 绝对变化图 和 增量变化图 两者的形态分别为 :

左侧的绝对变化图:给人的感觉是: 一部分做真正的自我,一部分做反向的自我 ,这样稍微有点 变态的感觉,呈现出来的视觉效果也是有点诡异的;

左侧的增量变化图:给人的感觉是:一部分做真正的自我,一部分超越自我,这种自我+超我 的感觉,清晰明亮,个性突出。

WinUI3 部分处理代码:

private byte ApplyAbsoluteFunction(byte value)
{// 以centerValue为中心,小于centerValue的值进行对称映射if (value < centerValue){// 计算对称值int symmetricValue = 2 * centerValue - value;// 确保值在有效范围内return (byte)Math.Min(255, Math.Max(0, symmetricValue));}else{// 大于等于centerValue的值保持不变return value;}
}

符号函数

符号函数,和上面的 绝对值函数 有些类似,但是它的 因变量的值 与 自变量本身 无关联,它是一个固定的数值,比如说当 x 小于 0 的时候,x=0的时候,x>0的时候,因变量 分别为 三个不同的固定的数值。

那么映射到 图像中,可以类似的理解为:仍然是把 128作为零点,从绝对变化图来说,当灰度值 小于128 的时候,取值为 50,当 灰度值 等于128 的时候 就取值为128,当灰度值 大于128 的时候 ,就取值为 200 ;那么 绝对变化图 的形态为 :

符号函数在 少量的几个颜色值之间 简单的变换 目标色 简单 清晰

同样的 ,作用到增量变化图的效果上,当小于128 的时候 ,颜色值 增量 为固定的 -30 ,当等于128 的时候,颜色值不变 ,当大于128 的时候,增量为 固定 的 30 。那么 增量变化图 的形态为 :

符号函数 作为增量值加到图像上 仍然破坏了 颜色的自然过渡 也呈现出了 高的对比度

WinUI3 部分处理代码:

private byte ApplySignIncrement(byte value, int negativeInc, int zeroInc, int positiveInc)
{int newValue;if (value < CENTER_VALUE){newValue = value + negativeInc;  // 小于128时的增量}else if (value == CENTER_VALUE){newValue = value + zeroInc;       // 等于128时的增量}else{newValue = value + positiveInc;   // 大于128时的增量}// 确保值在有效范围内return (byte)Math.Min(255, Math.Max(0, newValue));
}

阶梯曲线

阶梯曲线,是当自变量 在进行 不同阶段 的连续变化 的时候,因变量取值为 某一个集中的值。

比如,当自变量取值为1~2(包含小数)之间的时候,因变量就取值为1;自变量 取值为 2~3 的时候,那么 因变量取值为 2,也就是进行了 取整 操作。

可以看出来,因变量 呈现出 跳跃性 的 阶段性 变化,像是楼梯一节一节的。那么映射到图像中,我们进行类似的如下处理:

由于颜色值是从0~255,它没有小数概念,因此我们把它抽象为:假设每隔 25 属于自变量的一个 变化范围 ,那么因变量 取值为该范围的下限,也就是说,颜色值从 0~25 之间的时候 ,因变量取值为0 ,颜色值取值为 25 到 50 的时候,就取值为 25 ,这样 因变量 的颜色值就会呈现阶段性的变化。

同理,用上面的处理方式作为 增量 值,但是 由于按照上面 范围下限作为增量值的话,颜色值会过太,极可能会无效,所以我们取为它的 1/10(或动态调节) 来作为 增量值 ,例如,当颜色值为0~25 的时候,增量为0;当颜色值为 25~50 的时候 ,增量值为 2.5; 当颜色值 为 200 到 225 的时候,增量值设置为 200的1/10,也就是10。

那么 绝对变化图 和 增量变化图 两者的形态分别为 :

左侧的绝对变化图:给人的感觉是:好像手中只有 颜色可怜的少数的几只画笔 ,把与画笔颜色接近的涂抹为同一个颜色,不同的颜色区域 表现出了 无法衔接的、不自然的过渡状态;

右侧的增量变化图:给人的感觉是:作为增量值时,视觉差异与普通增量效果差异并不是很明显, 但是会看到 接近的颜色 变化范围也比较接近,不同的颜色区域 表现出了 比较明显的亮度层次差异。

WinUI3 部分处理代码:

 private byte ApplyStepIncrement(byte value){// 计算当前值所在的阶梯int stepNumber = value / currentStepSize;int stepBase = stepNumber * currentStepSize;// 增量为阶梯下限值的1/n(n为可调参数)double increment = stepBase / (double)currentIncrementRatio;// 应用增量int newValue = value + (int)Math.Round(increment);// 确保值在有效范围内return (byte)Math.Min(255, Math.Max(0, newValue));}

多公式分段函数

前面讲到的 符号函数 和 阶梯函数,它们都属于是分段函数,在不同的 自变量 的阶段范围内,因变量 发生了对应的变化,但是上面两种情况直接使用了 具体的数值 ,这里我们也可以把它换成 公式,也就是说,当自变量在第 1 个范围时,应用公式a, 当自变量在第 2 个范围时,应用公式b ,即在不同的情形使用不同的 公式转换 。

把它映射到图像中 ,我们可以类似这样处理:对于绝对变化图来说, 如果 当前的颜色值小于128,则对这个 颜色值 进行 开平方计算, 然后再乘以 2 ,即 y=2√x;如果当前的颜色值 大于等于128 时, 则对这个颜色值 进行 加30 的计算 , 也就是 y=30+x,那么 绝对变化图 的处理结果为:

同理,用上面的处理方式作为 增量 值,处理后的形态为:

WinUI3 部分处理代码:

 private byte ApplyPiecewiseFunction(byte value){double result;if (value < THRESHOLD){ result = 2 * Math.Sqrt(value);}else{ result = value + 30;}  return (byte)Math.Min(255, Math.Max(0, Math.Round(result)));}

函数类型总结

以上提到的是函数的基本类型 , 它们具有 4 个方面的特性:有界性、单调性、奇偶性、周期性, 并且对以上的 函数 进行反向(逆向)的处理,即为反函数 ,把 它们进行一些 组合使用,又称为复合函数 ,对多种不同的函数进行和差积商,又可以进行 函数运算。


基本初等函数

了解了函数的基本分类之后,每种类型里的具体函数是多种多样的,有简单的、复杂的,一些常见的函数 包含:幂函数 、指数函数、对数函数、三角函数、反三角函数,这五类称为 基本初等函数。接下来我们来了解具体的公式。

幂函数

幂函数, 对自变量进行 指定次数的乘法计算 。表现在图像上就是,对每个颜色值进行n次方计算,假设n动态可调整,那么处理效果为:

WinUI3 部分处理代码:

private byte ApplyPower(byte value)
{// 将像素值归一化到 [0, 1] 范围double normalized = value / 255.0; // 应用幂函数 y = x^ndouble result = Math.Pow(normalized, currentPower); // 将结果映射回 [0, 255] 范围return (byte)Math.Round(result * 255);
}

指数函数

指数函数,由于需要把自变量作为指数,因此把它 映射到图像中后,颜色的值 需要作为自变量指数,假设对2进行 指数的 运算 , 指数来自于每个点的颜色值,这样得到的结果数值 可能太大 ,远远超出了255,因此 为了能够显示它们,我们 取值为除以256之后的余数。处理效果为:

WinUI3 部分处理代码:

private byte ApplyExponential(byte value)
{// 使用缩放因子来控制指数增长的速度// 缩放因子越小,增长越缓慢,效果越温和double scaledValue = value * scaleFactor; // 计算指数函数double result = Math.Pow(currentBase, scaledValue); // 由于即使使用缩放因子,结果仍可能很大,使用模256运算// 这样可以产生周期性的振荡效果int moduloResult = (int)(result % 256); return (byte)moduloResult;
}

对数函数

基于指定的 底数,把 每个点的颜色值作为自变量来进行 对数函数 处理效果:

WinUI3 部分处理代码:

private byte ApplyLogarithm(byte value)
{// 对数函数:log(0)未定义,所以加1避免// 对于不同的底数,对数曲线的陡峭程度不同double inputValue = value + 1;  // 避免 log(0) // 计算对数值double logValue = Math.Log(inputValue) / Math.Log(currentBase); // 使用增强系数来放大效果double scaledValue = logValue * enhanceFactor; // 确保结果在有效范围内return (byte)Math.Min(255, Math.Max(0, Math.Round(scaledValue)));
}

三角函数

y=sin x , y =cos x, y=tan x, y=cotan x

假设我们用这4个三角函数按照如下公式进行计算,并且可动态调整参数:

sin: y = 128 + amplitude × sin(frequency × x)

cos: y = 128 + amplitude × cos(frequency × x)

tan: y = 128 + amplitude × tan(frequency × x)

cot: y = 128 + amplitude × cot(frequency × x)

那么可处理为不同的效果:

动态调整参数,可以看到炫丽且怪异的图像效果,它们呈现周期性变化、具有波纹和震荡的视觉效果,太另类了,有点欣赏不来,看来我不喜欢三角函数的美:

WinUI3 部分处理代码:

 private byte ApplyTan(byte value)
{// 计算 tan 函数,需要处理垂直渐近线double radians = value * tanFrequency;double tanValue = Math.Tan(radians); // 限制 tan 值的范围,避免过大的值tanValue = Math.Max(-3.0, Math.Min(3.0, tanValue)); // 应用振幅并中心化到128double result = 128.0 + tanAmplitude * tanValue; return (byte)Math.Min(255, Math.Max(0, Math.Round(result)));
}

反三角函数

Y=arcsin x , y =arccos x, y=arctan x, y=arccotan x

假设我们用这4个 反三角函数按照如下公式进行计算,并且可动态调整参数(将像素映射到角度范围,产生周期性效果):

arcsin: y = offset + scale × arcsin((x-128)/128)

arccos: y = offset + scale × arccos((x-128)/128)

arctan: y = offset + scale × arctan((x-128)/16)

arccot: y = offset + scale × arccot((x-128)/16)

那么可处理为不同的效果:

动态调整参数,可以看到优美的图像效果,反三角函数 看起来比 三角函数 “正派” 多了:

WinUI3 部分处理代码:

private byte ApplyArcsin(byte value)
{// 将像素值映射到 [-1, 1] 范围double normalized = (value - 128.0) / 128.0;normalized = Math.Max(-1.0, Math.Min(1.0, normalized)); // 限制在定义域内 // 计算 arcsin,结果在 [-π/2, π/2] 范围double result = Math.Asin(normalized); // 应用缩放和偏移double scaledResult = arcsinOffset + arcsinScale * result; return (byte)Math.Min(255, Math.Max(0, Math.Round(scaledResult)));
}

学习感悟       

不同的公式,它们都代表某个特定范围内的奇妙规律,通过图像化公式,我 “看见” 了公式的不同的个性美和奇妙的多彩的视觉效果。

所以,数学,是美的。                                                                     

http://www.dtcms.com/a/392332.html

相关文章:

  • ​​[硬件电路-296]:单刀双掷(SPDT)模拟开关
  • 【MAVLink】MAVSDK编程入门、基本概念
  • MAC-基于反射的枚举工具类优化
  • 防御性编程:编程界的‘安全驾驶‘指南
  • Qt绘图方式有哪些
  • 使用python创建、管理、分析和可视化“欲望”之间的关系网络图
  • 铸铁平台:工业制造的基石与精密测量的核心
  • Mac环境安装Nginx指南实录
  • 《RAG是什么?为什么它比微调更适合让AI拥有“专业知识”?》
  • 【Python】控制台界面演示
  • 软考中级习题与解答——第九章_信息安全(2)
  • [新启航]民航发动机燃油喷嘴的多孔阵列孔深光学 3D 轮廓测量 - 激光频率梳 3D 轮廓技术
  • 【测试开发/测试】详解测试用例(下):详解设计测试用例的方法
  • Go基础:Go语言错误和异常详解
  • kubeadm部署K8S单master架构实战
  • npx命令介绍(Node Package Execute)(允许开发者直接执行来自npm注册表的包中的二进制文件,而无需全局安装)临时使用
  • LeetCode 3508.设计路由器:STL套STL——有什么需求就设计什么数据结构
  • 基本排序算法
  • 学习Python中Selenium模块的基本用法(15:窗口操作)
  • 能力(1)
  • UE4/UE5 如何迁移HotPatcher插件
  • SQL从入门到起飞:完整数据库操作练习
  • MyBatis 从入门到进阶:数据库操作全指南
  • spring cloud 同一服务多实例 websocket跨实例无法共享Session 的解决
  • 如何通过pycharm使用AutoDL服务器
  • 【Linux】4G网卡-AT命令
  • 新版本附近停车场推荐系统demo,基于python+flask+协同推荐+空车位识别+yolov人工智能开发,开发语言python,数据库mysql
  • 《UE5_C++多人TPS完整教程》学习笔记55 ——《P56 网络更新频率(Net Update Frequency)》
  • 华为鸿蒙 ArkTS 实战:基于 RelationalStore 的 SQLite 实现本地数据持久化
  • 流行的 3D 文件格式及其用途指南