duangsuse::Echo
#learn 首先来了解下中缀链优先级解析法 1+2*3 即 1+(2*3) 1*2+3 即 (1*2)+3 ,即前缀 (+ (* 12)3),+的优先比* 低,所以它离树根最近、最后计算。默认先算左边的 one=ed=>{x(); for(o=s(); l[o]>=l[ed];)one(o) add(ed)}; o是最新一算符、x()是读单项。每层会收纳级=它的算符链,1+2 *3 +4 时乘法深度往上攀升,就先add(*),然后才落回 +的层次继续 x()=4,直到 o=null 整个栈退出 one('')&a.pop()…
https://yfzhe.github.io/posts/2020/03/define-memo/ #fp #algorithm fib 序列
这货一般用递归或递推(伪递归)定义(f=fib)
于是 f 2 = 1+0 ,f 3=f2+1 ,很明显这可以转为递推
也即循环
#haskell 里也可以用
你可能觉得很怪,我 #Python 利用2项tee()缓冲区实现过这个 fib.py
函数式的动态规划 - 脚趾头的文章 - 知乎 讲了背包、子序列问题的DP
https://zhuanlan.zhihu.com/p/104238120
这货一般用递归或递推(伪递归)定义(f=fib)
f 0=0;f 1=1
f n=(f n-1)+(f n-2) --前两次之和 于是 f 2 = 1+0 ,f 3=f2+1 ,很明显这可以转为递推
f' 0 a _ = a --f0=0- f' 0 1 2 - 1
f' n a b = f' (n-1) b (a+b)
f n=f' n 0 1
f2= f' 1 1 1
也即循环
f=n=>{let a=0,b=1,c=0;for(;n--;){c=a+b;a=b;b=c} return b}
如果不想浪费 f'0时的b=(a+b) ,也可以f' 0 _b=b当然即便不使用递推,
f n=f' (n-1) 0 1 ; f0=0
memo 缓存参数也能很好优化雪崩式递归#haskell 里也可以用
fib=0:1:zipWith(+) fib (drop 1 fib) 你可能觉得很怪,我 #Python 利用2项tee()缓冲区实现过这个 fib.py
fibs = iself(lambda fibs: chain([1,1], starmap(add, zip(fibs, drop(1,fibs)))))
函数式的动态规划 - 脚趾头的文章 - 知乎 讲了背包、子序列问题的DP
https://zhuanlan.zhihu.com/p/104238120
yfzhe.github.io
从 Fibonacci 到 define-memo
故事要从 HackerRank 网站上的 "Functional Programming" 题集里的 一道题目 说起。这道题目叫 "Fibonacci",属于 "Memoize and DP" 分类下。一如题目名字一样 直白,这题就是要求 Fibonacci 数列的第 n 项 \(Fib_n\),其中 \(Fib_0 = 0, Fib_1 = 1\)。(其实还是有点点差别,原题因为数字精度范围的问题要求 mod 10e8+7,但是在这里 我们不需要考虑这个问题,下面忽略 mod 10e8+7 这个操作。)...
duangsuse::Echo
https://twitter.com/GrantCuster/status/1457786663275413509 Tech-wise this type in WebGL (using three.js). The letters are put together in a canvas sprite sheet, then placed as a texture on *instanced rectangles*. It's a very different set of constraints than…
Telegram
duangsuse::Echo
为了吹哨人、发哨人,以及所有为了疫情努力过的人(当然,显然我不包括在其中)
本频道 image 象征性灰今明两天。 #Telegram #China
#Python Pillow:
from PIL import Image
def grayifyFile(name):
img = Image.open(name)
img.convert("L").save(name.rsplit(".")[0])
grayifyFile("image.png")
OpenCV #CV #Cplusplus:…
本频道 image 象征性灰今明两天。 #Telegram #China
#Python Pillow:
from PIL import Image
def grayifyFile(name):
img = Image.open(name)
img.convert("L").save(name.rsplit(".")[0])
grayifyFile("image.png")
OpenCV #CV #Cplusplus:…
#math 如果你要在终端展示图片(RGB亮度->灰度),就需要将稠密的浮点切成区间编号。 绿 floor(x*a)/a 在a=2 时将0~1切成2份,a=10 相当于保留1位小数(1.0内含10阶),而 红 round 会切成4份,即数组a.
CSS1 仅支持VGA颜色,后来有了 X11-SVG 标准色集
CSS4 支持
相比之下,弱鸡的 #Java AWT 和 #Python PIL 就没有简单、统一可玩的API ,awt 只有光谱 CIE XYZ 这样低层的概念,
#cg 在「擦拭」位图A->B渐变里,t=0~1 , 当前帧=(1-t)A+tB ;先绘制A, 再以 mask(t) 叠上B
遮罩mask 内最黑的部分代表B最先出现部分,随着t递增 所有像素渐变到B
柔和度=0 时 mask 内只有0,1 二态,所以AB中间的线(如果mask=横向渐变)很锐利
=1 时会用尽alpha色域(一般256色)渐变
a[floor(v*n(a) )]
#CSS #web 提供了 #rgb , #rrggbbaa 的 rgb(255,.) ,以及 hsl(Hdeg S%L%) 扇形选色方式,注意这不是冷知识.. color picker 都支持按色相、饱和、亮度选色, backdrop-filter:hue-rotate(1deg) 也是有的CSS1 仅支持VGA颜色,后来有了 X11-SVG 标准色集
CSS4 支持
rgba(r g b /a) 空格格式和浮点数相比之下,弱鸡的 #Java AWT 和 #Python PIL 就没有简单、统一可玩的API ,awt 只有光谱 CIE XYZ 这样低层的概念,
getHSBColor 和又能大写又能小写的 static RED 这些……emm#cg 在「擦拭」位图A->B渐变里,t=0~1 , 当前帧=(1-t)A+tB ;先绘制A, 再以 mask(t) 叠上B
遮罩mask 内最黑的部分代表B最先出现部分,随着t递增 所有像素渐变到B
柔和度=0 时 mask 内只有0,1 二态,所以AB中间的线(如果mask=横向渐变)很锐利
=1 时会用尽alpha色域(一般256色)渐变
duangsuse::Echo
The Java maintainers chose to generate the implementation class in runtime. This is done by calling java.lang.invoke.LambdaMetafactory.metafactory. Since the arguments for that call (return type, interface, and captured parameters) can change, this requires…
然后呢华为方舟也是做了个
#java #learn 这个 invokedynamic 呢,暴露为 j.l.invoke.CallSite ,咱看看用法
#code
""?是为了规避常量折叠。无论多复杂,带><转型的常量表达式 sun javac 都是能执行的..妈耶,在框架限制内你可牛
会得到自带的FnRun.<init>=super() 和 main():
..我们用 #python #code 重构一下字节码表示
所以Java闭包为啥不能改
因为代码一样
然后new R(){}的
它被 .invoke() 的地方就是动态调用点(callsite) ,bootstrap 方法(^) 用于查找句柄指代的函数实现,只做一次
没错,invokedynamic 的lookup函数的参大多在编译期确定,甚至不能是 Object 😒
当然用反射newInstance就太容易了,Google dx 使用 RuntimeDesugar 转化^
除了查找函数签名的实现,用户代码不会涉及其他关于计算栈的东西,和最常见的
顺便: invoke-interface 是劣化的 virtual 。虚方法是单继承得来,成员有唯一索引;接口方法可被多 class implements ,无法做覆写查找的缓存。但能去虚化内联时一样
super()的话是 invokespecial ,不能通过继承被覆盖也无需查找
总之这个Java8引入的 INDY 主要是关于性能前提的,如果以 #js 程序员的视角会觉得这些都不如
我不想再谈了,也没啥用;还不如做JVM脚本语言—但也不得不考虑Dalvik dex的兼容性?
拿这种东西当知识不如直接说:
为什么必须用dyn: 没有为什么,也不是因为参数类型不确定。反射交给目标SAM函的NameAndType 也能按照impl的参数(=field)动态定义/init this implements SAMFnType ,来创建
当你写
这些内容太细节,工程界自然完全不知道,所以说是什么“metafactory本身的签名不定” “创建调用的参数不确定” —的确不定,但重点是在T子类this.getClass() 定义不确定,这就涉及闭包,而今天的人都tm不知道{x+1}等函数是有词法上下文,由编译器统一保存位置的! 🥲
因为每个开发者眼前都只有自己的一亩三分地,编程是为效果
然而框架的开发者却不懂这个道理,想传教自己的设计有多“可扩展” 😒
我就好奇啊,中国也没几个人真做字节码框架啊,考的有意义吗? 觉得很厉害??🤔🙏
ref: https://jakewharton.com/d8-library-desugaring/ dex 上 stdlib-jre8 的 hashcode, notnull 测试都转换回老版本了,同时兼容Stream等新API
jbc2mpl && mplcg 的示例,其实主要是移植 #jvm 的感觉, virtualcall (invoke-virtual, invoke-special/static 是普通函数) 方法查找模式都复刻了,也有些if,while 的高级Node,但许多库..哪怕 javacore/libjavacore.mplt 的 rt.jar 和 j.l.String 都没开源,在 #zhihu https://www.zhihu.com/question/343431810 可以看到#java #learn 这个 invokedynamic 呢,暴露为 j.l.invoke.CallSite ,咱看看用法
#code
class FnRun{
interface R{void run();}
static R f1;
static public void main(String[]a){
f1="".isEmpty()? ()->{ a[0]=""; } :new R(){public void run(){a[1]="";} };
}
}
javap -c FnRun FnRun$R""?是为了规避常量折叠。无论多复杂,带><转型的常量表达式 sun javac 都是能执行的..妈耶,在框架限制内你可牛
会得到自带的FnRun.<init>=super() 和 main():
..我们用 #python #code 重构一下字节码表示
//L5 "".isEmpty在非static 方法里 aload_0=this 。在这里
ldc String
Fvirt String.isEmpty:()Z
5^ifeq //br.not
aload_0
Fdyna #,0:run:([String;)LFnRun$R; //重点!
14^goto
new FnRun$1 ^5 //here
dup
aload_0
Fspec FnRun$1."<init>":([String;)V
putstatic f1:LFnRun$R; ^14 //goto
//L6
return
new FnRun$1(a) 被翻译为 new, dup, (a) Fspecial, putstatic 即 {R o=new R; init(o); f1=o}, o值引用了两次所以Java闭包为啥不能改
()->{a=new String[]{};} ,在()->{}外也不行? —因为它就是个构造器,Kotlin 使用 IntRef 化来实现完整的局部量共享。因为代码一样
Fdyna 直接初始化了 FnRun$R.run ,然后 callsite$0 开 javap -v 才能看到,待会说然后new R(){}的
class FnRun$1 implements FnRun$R {
final java.lang.String[] val$a;
//<init>: L5
aload_0
aload_1 ; putfield val$a:[String;
aload_0
Fspec Object."<init>":()V
return
//run:L5
aload_0 getfield val$a:[String;
iconst_1
ldc String#3
aastore //还有iastore fastore..IntArray啥
return
Java8的动态调用不止是新增opcodej.invoke.MHs.lookup().findVirtual(Obj,"hashCode",methodType(int))就是方法句柄
它被 .invoke() 的地方就是动态调用点(callsite) ,bootstrap 方法(^) 用于查找句柄指代的函数实现,只做一次
Fdyna 0:run:([String;)LFnRun$R;callsite$0 REF_invokeStatic=
invoke/LambdaMetafactory.metafactory:(Linvoke/MethodHandles$Lookup;LString;Linvoke/MethodType;
Linvoke/MethodType;Linvoke/MethodHandle;Linvoke/MethodType;)Linvoke/CallSite;
明显这个 metafactory(Lookup,String,MethodType,...) 做了字节码new 的工作,只接受 aload_0(this) 和 FnRun.lambda$main$0:([LString;)V的NameAndType 就创建了内部类 FnRun$R 的对象,这一步只是“调用一个尚不存在的class构造器”,我们负责生成&加载相关类 🤔,并链接-给出代码位置
-Djdk.internal.lambda.dumpProxyClasses=.但剩下的3参数太多了: SAM methodType(void.class), implMethod, 泛型SAM描述符
没错,invokedynamic 的lookup函数的参大多在编译期确定,甚至不能是 Object 😒
当然用反射newInstance就太容易了,Google dx 使用 RuntimeDesugar 转化^
lambda$ ,当然这都是过去式了, #Kotlin 万岁super<PT_2>.say()的自由祖父类指定可以用:
class PT_2 {void say();//parent T
class PT extends PT_2 {}
class T extends PT{void say(){}//新版本
void main(){
MHs.lookup().findVirtual(ParentT_2.class,"say",MT.methodType(void.class)).bindTo(this).invokeExact();
}
你不能手写 invokedynamc 而只能由 j.l.invoke.* 工具类invoke()时生成,因为调用是在字节码层,不是运行期元数据反射 😒除了查找函数签名的实现,用户代码不会涉及其他关于计算栈的东西,和最常见的
invokevirtual 是完全一样的,而因为lookup的实现有限制, MHs 提供了 collectArguments,guardWithTest,countedLoop 等一系列组合器帮助修改调用,比如加点参数,对Groovy 不定长参 函数转化 这样就很有帮助顺便: invoke-interface 是劣化的 virtual 。虚方法是单继承得来,成员有唯一索引;接口方法可被多 class implements ,无法做覆写查找的缓存。但能去虚化内联时一样
super()的话是 invokespecial ,不能通过继承被覆盖也无需查找
总之这个Java8引入的 INDY 主要是关于性能前提的,如果以 #js 程序员的视角会觉得这些都不如
new Proxy({}, {get,set}) 😂我不想再谈了,也没啥用;还不如做JVM脚本语言—但也不得不考虑Dalvik dex的兼容性?
拿这种东西当知识不如直接说:
SAMFunc/*void()*/ f=()->{} 编译期生成对 j.l.invoke.LambdaMetaFactory 静态同名方法(Lookup,String name,MethodType) 的调用,并把结果CallSite (仅首次计算)再次调用;这个“元工厂”把()->{}代码生成为 new T(){} 的具体class加载,返回它 static get(...localvars) 的调用句柄,于是得到目标接口的对象为什么必须用dyn: 没有为什么,也不是因为参数类型不确定。反射交给目标SAM函的NameAndType 也能按照impl的参数(=field)动态定义/init this implements SAMFnType ,来创建
o.impl()的代理。Android 最初就是反射直接Proxy class当你写
class Out{int a; new T(){a} } ,相当于生成一个 Out$1 extends T ,它的构造器把(编译器确定共享序的)局部变量存在this,内部代码是有两个上下文的,()->{} 里也一样,只是这次 Out$1 的创建由运行时metafactory()负责,动态链接 T getLambda(int a); 完全是 Oracle 的私货,Kt 1.5 才支持这个 code size 优化这些内容太细节,工程界自然完全不知道,所以说是什么“metafactory本身的签名不定” “创建调用的参数不确定” —的确不定,但重点是在T子类this.getClass() 定义不确定,这就涉及闭包,而今天的人都tm不知道{x+1}等函数是有词法上下文,由编译器统一保存位置的! 🥲
因为每个开发者眼前都只有自己的一亩三分地,编程是为效果
然而框架的开发者却不懂这个道理,想传教自己的设计有多“可扩展” 😒
我就好奇啊,中国也没几个人真做字节码框架啊,考的有意义吗? 觉得很厉害??🤔🙏
ref: https://jakewharton.com/d8-library-desugaring/ dex 上 stdlib-jre8 的 hashcode, notnull 测试都转换回老版本了,同时兼容Stream等新API
Zhihu
如何看待方舟编译器于 2019 年 8 月 31 日开源? - 知乎
华为表示 show you the code,希望有大佬可以借此机会解释解释何为方舟编译器?
duangsuse::Echo
然后呢华为方舟也是做了个 jbc2mpl && mplcg 的示例,其实主要是移植 #jvm 的感觉, virtualcall (invoke-virtual, invoke-special/static 是普通函数) 方法查找模式都复刻了,也有些if,while 的高级Node,但许多库..哪怕 javacore/libjavacore.mplt 的 rt.jar 和 j.l.String 都没开源,在 #zhihu https://www.zhihu.com/question/343431810 可以看到…
jbc.py
725 B
#python #code javap 字节码简写工具, 仅供上午使用..
https://time.geekbang.org/column/article/12564
https://xie.infoq.cn/article/6d30b8221c1a967ec32ac3b9c MethodHandler 相关
https://time.geekbang.org/column/article/12564
https://xie.infoq.cn/article/6d30b8221c1a967ec32ac3b9c MethodHandler 相关
duangsuse::Echo
#math #plt 公开课. 是仿造数学语言 https://github.com/DSLsofMath/DSLsofMath Introduction: Haskell, complex numbers, syntax, semantics, evaluation, approximation Basic concepts of analysis: sequences, limits, convergence, ... Types and mathematics: logic, quantifiers…
#typescript #TT 科普 TypeScript Type-Level Programming - lsdsjy的文章 - 知乎
https://zhuanlan.zhihu.com/p/54182787
TS是支持静态类型的JS。有 number,string 等值,也有常量作 literal type: number, .. "div" "body"..
这个表里[num,str] 是 num|str 的意思,因此若有 P={a:num,b:str} 则 P[keyof P] ,就是并集类型。类同{}类型,
let v:{[K in keyof T]:
子类型中 Int is Num, Num is Num 。is是 <= (never不大与任何类型)的意思,如何实现(=)呢?
这里也以infer语法来引入新的 typevar <U> ,算是某种意义上的“模式匹配”。在Haskl 对 ADT 的值作模式匹配;在这儿,我们对有着“代数类型 类型”的TS类型作模式匹配。
ADT 有普通的函数状 data constructor;Type 也有 type constructor,比如 Promise就是 T->Promise<T>的“类型函数”。它是 lit,list,dict 外第三种组合方法
然后是:
一开始的时候,我把 Coq induction 和数学归纳法搞混了。要用数学归纳法证明一个命题 P,你需要先证明一个基础步骤 P(0),然后在 P(n) 成立的情况下证明一个递推步骤 P(n+1)。但是在 induction 里面没有“基础步骤”和“递推步骤”之分,甚至 induction 产生的小目标的数量都不一定等于2。之后,我发现你可以把 induction 理解成数学归纳法的一种扩展。数学归纳法是作用在自然数上面的,而自然数是一种递归定义的归纳类型:
证明 len_app_plus,就对 s1 进行归纳,因为 String.length 在每次迭代中会消耗字符串的第一个字符。当你对 s1 进行归纳的时候,第二个情况会是 s1 = String char s,这就对应了 String.length 的定义
作者:陈乐群
链接:https://zhuanlan.zhihu.com/p/54164515 能够看出来写得很好,还带FAQ..可对外道入门逻辑式还不够唉
#rust #PLT 自由程续-阴阳谜题 手动脱call/cc解
Rust 阴阳谜题,及纯基于代码的分析与化简 - 知乎用户FGAvTw的文章 - 知乎
https://zhuanlan.zhihu.com/p/52249705
#Python 5行yield解 https://zhuanlan.zhihu.com/p/43207643
如何制造SCP018 - 圆角骑士魔理沙的文章 - 知乎 — 函数式尾调用优化
https://zhuanlan.zhihu.com/p/43163820
形式验证、依赖类型与动态类型 - 老废物千里冰封的文章 - 知乎 讲了 Nullable,静态长Vec,运行时报错的type兼容
https://zhuanlan.zhihu.com/p/50792280
https://zhuanlan.zhihu.com/p/54182787
TS是支持静态类型的JS。有 number,string 等值,也有常量作 literal type: number, .. "div" "body"..
<K extends keyof ElementMap> :R=Map[K] 是入门级子集定义吧!TS里{a:1,b:""} 的类型都是这种表。此外 {[K in keyof T]: } 可作转化这个表里[num,str] 是 num|str 的意思,因此若有 P={a:num,b:str} 则 P[keyof P] ,就是并集类型。类同{}类型,
{[K in KS]: }[KS] 给并集list 作转化let v: (() => void) extends Function的类型是true(lit type). 以下 is=extends
type T={a:num,b:str} //v:{a:Num|never} ,never=kotlin.Nothing |的不动(0值)点let v:{[K in keyof T]:
T[K] is number? T[K] : never }[keyof T] //收集并转换子类型中 Int is Num, Num is Num 。is是 <= (never不大与任何类型)的意思,如何实现(=)呢?
type Equal<T, U> = T is U ? (U is T ? true : false) : false //TS类型上无&& || !TS只支持 recursive mapped types,“递归函数”只能返回 dict。设想 T={xx: T|Promise<U>} ;把T内所有Promise.resolve 的函数类型是啥?
let v: Equal<Func, Function> // v: true //最后一遍:这是编译期可知
type Unwrapped<T> = { [K in keyof T]: T is Promise<infer U> ? U : Unwrapped<T> }
type Unwrap<T> = (wrapped: T) => Unwrapped<T> 这里也以infer语法来引入新的 typevar <U> ,算是某种意义上的“模式匹配”。在Haskl 对 ADT 的值作模式匹配;在这儿,我们对有着“代数类型 类型”的TS类型作模式匹配。
ADT 有普通的函数状 data constructor;Type 也有 type constructor,比如 Promise就是 T->Promise<T>的“类型函数”。它是 lit,list,dict 外第三种组合方法
type:
Nat<N> = Zero | Succ<N>
Zero = void; type Succ<N> = { pred: N } //0, +1
_1 = Succ<Zero>
_2 = Succ<_1>
IsNat<T> = T is Nat<infer N> ? true : false
q1 = IsNat<_2> // true
q2 = IsNat<number> // false
IsNatIsNat = IsNat<IsNat> //err: IsNat require param 然后是:
一开始的时候,我把 Coq induction 和数学归纳法搞混了。要用数学归纳法证明一个命题 P,你需要先证明一个基础步骤 P(0),然后在 P(n) 成立的情况下证明一个递推步骤 P(n+1)。但是在 induction 里面没有“基础步骤”和“递推步骤”之分,甚至 induction 产生的小目标的数量都不一定等于2。之后,我发现你可以把 induction 理解成数学归纳法的一种扩展。数学归纳法是作用在自然数上面的,而自然数是一种递归定义的归纳类型:
Inductive nat : Set :=要证明 len_repeat,我们就要对 n 进行归纳,因为 repeat 是定义在 n 上的一个递归
| O : nat
| S : nat -> nat.
Lemma len_repeat: --n(s rep k)=k*n(s)
forall s n,
String.length (repeat s n) = n * String.length s.
intros s n. induction n
(s rep 0)=0*n(s)—无归纳假设, 下递归定义,有.
(s rep N+1)=(N+1)*n(s)
Lemma len_app_plus: --n(s+s1)=n(s)+n(s1)
forall s1 s2,
String.length (s1 ++ s2) = String.length s1 + String.length s2.
证明 len_app_plus,就对 s1 进行归纳,因为 String.length 在每次迭代中会消耗字符串的第一个字符。当你对 s1 进行归纳的时候,第二个情况会是 s1 = String char s,这就对应了 String.length 的定义
作者:陈乐群
链接:https://zhuanlan.zhihu.com/p/54164515 能够看出来写得很好,还带FAQ..可对外道入门逻辑式还不够唉
#rust #PLT 自由程续-阴阳谜题 手动脱call/cc解
Rust 阴阳谜题,及纯基于代码的分析与化简 - 知乎用户FGAvTw的文章 - 知乎
https://zhuanlan.zhihu.com/p/52249705
#Python 5行yield解 https://zhuanlan.zhihu.com/p/43207643
如何制造SCP018 - 圆角骑士魔理沙的文章 - 知乎 — 函数式尾调用优化
https://zhuanlan.zhihu.com/p/43163820
形式验证、依赖类型与动态类型 - 老废物千里冰封的文章 - 知乎 讲了 Nullable,静态长Vec,运行时报错的type兼容
https://zhuanlan.zhihu.com/p/50792280
知乎专栏
TypeScript Type-Level Programming
TypeScript 有着足够强大(?)的类型系统,我们可以用它做类型层面的编程。首先来看如何在类型层面表达编程的几个要素:数据(广义地指可供编写者操作的所有实体)、操作变换数据的原语和控制流(广义,包括命令…
依云的技术资源分享
https://addons.mozilla.org/firefox/addon/header-editor/ #software #http #firefox #chrome #web ---- 一个强大而好用的 HTTP 修改器,给请求头添加 Accept 或者给响应头添加 CORS 头都挺好用
^1 Android也有较知名基于内开VPN的 Packet Capture 和 #Python fiddler WLAN热点/proxy
2. https://www.shadertoy.com/view/ltlXzl 仿造了原场景。
https://www.shadertoy.com/view/MttGDr 点人挖土游戏..emm
2. https://www.shadertoy.com/view/ltlXzl 仿造了原场景。
https://www.shadertoy.com/view/MttGDr 点人挖土游戏..emm
#cg #python
要展示100个人头像的最好方法是瓷块式拼合,再在上面盖层mask,像"Meta","Google"大字样,使部分头像变黑,但一些人的头像就比较黑,如果能让它们处在mask更黑的地方,岂不更好?
mask 里w=h=1 ,只要提供宽度切出每像素,以与下者对应
*.png 里只用返(),需要视每张wh来布局,因此网应是返()的参数
如此就能按 mask 组合能补满其w*h的 png 们,sortMerge(a,b,f):把b按f序对应到a索引
sort(保留a索引号,f) 再把 sort(b,f) 以a位置填充即可
以此顺序调用返(),输出里mask高亮(f=lum)位置就是较白头像
#js
漩涡扭曲位图里半径l的区间,需在xy建立圆心座标系,从 xy-l 迭到 xy+l 算与xy差的 sqrt,atan2 确定距离分组再以在圆弧度 排序像素不难,然后 push(shift(扭力)) 取圈重排再画回去
其实直接支持 xy=2l 的2D数组,靠与其索引 i-l 的角距,即得 xy和旋转后的 ai=a[ti] 映射关系,不必每次创建许多分组和数组只为旋转圆内圈;直接生成 t[y*w+x] 存储旧位 如此利用 getImageData.data 更方便
要展示100个人头像的最好方法是瓷块式拼合,再在上面盖层mask,像"Meta","Google"大字样,使部分头像变黑,但一些人的头像就比较黑,如果能让它们处在mask更黑的地方,岂不更好?
imwall.py mask.png *.png 首项宽高很低,其后图宽高统一,试以lum(img)为目标将其后图像瓷砖排列。class 砖图:如此我们就能以网格座标来处理一张图,比如滤镜五颜六色。但 网(ims,m=columns) 有两个版本
def 入(im,网)#以网格项(x,y,w,h) im.crop 出列表,记下i-xy对应
def 返(a)#paste 回旧图原位
mask 里w=h=1 ,只要提供宽度切出每像素,以与下者对应
*.png 里只用返(),需要视每张wh来布局,因此网应是返()的参数
如此就能按 mask 组合能补满其w*h的 png 们,sortMerge(a,b,f):把b按f序对应到a索引
sort(保留a索引号,f) 再把 sort(b,f) 以a位置填充即可
以此顺序调用返(),输出里mask高亮(f=lum)位置就是较白头像
#js
漩涡扭曲位图里半径l的区间,需在xy建立圆心座标系,从 xy-l 迭到 xy+l 算与xy差的 sqrt,atan2 确定距离分组再以在圆弧度 排序像素不难,然后 push(shift(扭力)) 取圈重排再画回去
其实直接支持 xy=2l 的2D数组,靠与其索引 i-l 的角距,即得 xy和旋转后的 ai=a[ti] 映射关系,不必每次创建许多分组和数组只为旋转圆内圈;直接生成 t[y*w+x] 存储旧位 如此利用 getImageData.data 更方便
Telegram
duangsuse::Echo
谈谈命名问题。圆座标系(POLar)上,角度和距离一般称 theta-rho , angle/arc-radius 即a-r,这是物理采用较少的几个希腊字
我的物理命名法则用 rl:rotation-length 表示这个,因为编程上a理应代表数组..而一些人也会用r标记角度a记面积 真混乱
对同一个像素图,可用直角(xy)和圆座标(rl)自00点等效描述其上每点位置(座标系的意义就是编码位置),这样就容易进行变换,例如圆翘曲和拧转
->rl=(atan2(x,y), sqrt(xx+yy))
<-rl=(lsinr…
我的物理命名法则用 rl:rotation-length 表示这个,因为编程上a理应代表数组..而一些人也会用r标记角度a记面积 真混乱
对同一个像素图,可用直角(xy)和圆座标(rl)自00点等效描述其上每点位置(座标系的意义就是编码位置),这样就容易进行变换,例如圆翘曲和拧转
->rl=(atan2(x,y), sqrt(xx+yy))
<-rl=(lsinr…