/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
/tmp/duangsuse.sock
https://github.com/ice1k/FindLine... 虽然代码风格不好,但还是看到了我意料之外的东西(之前一直以为 init {} 块是用来初始化类本身的... 现在想来,Kotlin 里类其实还是很特别的... 真正能被访问的不是类,只有对象,所以 companion object 的 init 才应该是构造器?而且我不知道 META-INF/ 还可以直接放) 简单说一下不重要的 utils 包, debug:logstdout, Binarization:二值化, java:没用的Boolean矩阵…
模型的总结:

Area(其实这个和 Box 有点混淆的说):就是一个 java.awt.image.BufferedImage 的扩展

+ 可以 draw 一个 Point
+ 可以 drawLine 一组 Point 构成的 Line
+ 可以 drawTriangle 一组 Line 构成的 Triangle

fun draw(points: Set<Point>) = points.forEach { p -> draw(p) }
fun draw(p: Point) = image.setRGB(p.x, p.y, if (this[p.x, p.y]) Color.BLUE.rgb else Color.ORANGE.rgb)

对于扩展, operator fun get(x: Axis, y: Axis) = Binarization.rgb2bw(super(x, y)),... 好吧,其实原来的版本是二值化滥用了(而且不得不说三年前冰封的编程风格也很... 虽然风格不好但是算法也能写的)
返回 Boolean, true 代表 B、false 代表 W...(所以 utils 包里有 java.BooleanMap,我开始还以为是位运算压缩)

protected infix fun Point.connect(point: Point): Boolean
fun init()

这两个操作,写的质量都有点...(的确是这样的...)

protected fun Point.legal()

虽然限制了 Point 原来的定义(本来主要打算是用作 Position.... 怎么感觉又混淆了)
但是也不至于很差

@Deprecated("Will take too much time") fun getArea(point: Point): Set<Point>

用到了 BooleanMap 和 LinkedBlockingQueue...
看的时候觉得 queue.pool().surrounded() 会是调用 Point 的操作,不得不检查了一下 class Point 的定义
总之就是 BFS (广度优先搜索)这个 Point,如果 legal (在 Area 里)并且是 Area 的 pos 是 black 的话,就加入点集合里

而且还不能是输入的点 p... 什么鬼

val mark = BooleanMap(origin.width, origin.height)
queue.put(p)

while (queue.isNotEmpty()) {
val p0 = queue.peek()
mark[p0.y][p0.x] = true
set.add(p0)
val ps = queue.poll().surround().filter { it.legal() && it.rgbFrom(this) == RGB_BLACK && mark[it.y][it.x] == false }
queue.addAll(ps)
}
... 噢
我明白了,的确这个 BFS 程序利用 mark 的副作用操作,这样就只有某块区域边角才能被标记出来...

四周,只要 valid 都可以
mark 之前是优先添加的,不过这... 好吧,看来这只是一种解决无限循环问题的方式而已 😮

(如果要『只有边角被标记』,判断 marks 是否包含这一点,不包含则添加?)
...总之单靠 bfs 应该还是可以做到?不过有点麻烦,可能涉及一些点的计算
边缘检测是矩阵求卷积然后二值化的...

Point 的计算就是 distance, surround 没了
distance 就是毕加哥拉斯公式嘛(勾股定理...)
sqrt( (p1.x - p0.x)^2 + (p1.y - p.y)^2 )
考虑一下边长^2 = 面积... 好像没啥关系

噢是有关系的,考虑到『点之间的距离』,我们想到的是 f(p0, p1),并且两点『距离』越大值越大(否则正好相反)
这就是性质定义,为什么不把从『面积』公式修改呢?
于是就:
(p1.x - p0.x)^2 + (p1.y - p.y)^2
再开方(顺便就绝对值了)得到了距离(注意不能提升 ^2 到 (+) 之上)
(+) 是混合项目用的操作符
数形结合是一种优秀的思维方式,并且必须要使用。


Position 就是象限的计算,不过这里有个『优化』(虽然比较 hack...

g += if (x >=0) 1 else 2
g += if (y >=0) 0 else 3
if (g == 5) g = 3

我们来分析一下常量控制流

x >=0 => g = 1 (第一象限 x < 0、y < 0)
x < 0 => g = 2(第二象限 x > 0、y < 0)
y >=0 => g += 0
y <0 => g += 3

值得注意的是这个 y,当 y 小于零

x >= 0 => g = 1+3 = 4(第四象限 x > 0, y < 0)
x < 0 => g = 1+0 = 3(第三象限 y < 0, x > 0)

怎么『构造』这种优化可以手动堆(因为这种加减法不是很难,何况你对应一下,从 y 的 case 往下分支也就可以了)
也可以按照固定的模式转化,以后可能会有分析

后面的 if (==5) 本来应该是死代码... 虽然因为封装的不好,可能就没有那么死了
等等不是死代码,2+3 可能等于 5... 这种情况就是 (x,y -> >0 的情况)

2|1
4|3

Triangle(Point a, Point b, Point c) 这个没啥好说的,连 sin cos 都没用到
setOf((a, b) (b, c) (c, a)).forEach(::draw) 即可

最后要点:也是我绝对不会的,因为目前我数学和几何很菜

Line.kt

问题:如何枚举线段 (x0, y0) — (x1, y1) 里的点 🤔

private val a = two.y - one.y
private val b = one.x - two.x
private val c = two.x * one.y - one.x * two.y

这是三个对 xy 进行综合的量,前两个一看就知道,
后一个需要思考一下,为什么要进行交叉?
如果没有图示的话还的确不 immediate

我画图....
比较简陋...
/tmp/duangsuse.sock
比较简陋...
就可以 immediate 地发现一点:其实两个乘法都构筑了一个长方形的面积(最开始我没有这个感觉,因为对命名来说太不可思议了)

他们的减可以表示一个... 综合了方向的差
关键是 a.x 和 b.y 要交叉乘,然后减法就算出了这个矢量差

A(2, 10) B(1,0)
算得 c 有两个 case,其中两个参数分别为
(2 * 0) — (1 * 10)

1. (2 * 0) - (1 * 10) = (-10)
2. (1 * 10) - (2 * 0) = 10

... 因为正好是相反数,所以应该说,矢量差是正确的(虽然好像都是这样吧...
/tmp/duangsuse.sock
比较简陋...
This media is not supported in your browser
VIEW IN TELEGRAM
刚才才发现弄错了一点... 这个 y x (数轴)它放反了.... 不过因为两个都是反的所以没关系
我没有保存图表的... 所以不能修正了
fun x2y(x: Int) = if (b == 0) c / a else -(a * x + c) / b
fun y2x(y: Int) = if (a == 0) c / b else -(b * y + c) / a

(Math.min(one.x, two.x)..Math.max(one.x, two.x)).forEach { x -> set.add(Point(x, x2y(x))) }
(Math.min(one.y, two.y)..Math.max(one.y, two.y)).forEach { y -> set.add(Point(y2x(y), y)) }

这是两个算点的公式,首先有一个 case 优化:x2y, 如果 y 是一条直线上(平行 y 轴),则直接返回 (c / a)

(two.x * one.y - one.x * two.y) / two.y - one.y

... 不明白,虽然之前说了是对『方向』的综合
y2x 同理

-(b * y + c) / a
这个情况就用到了参数 y 了,是一般的直线,首先我们得求斜率,然后去 c 是什么鬼...
(b*y) 还是『当前』长方形的面积,然后 c 的作用是叠加一个方向,a 则是最终求关于原矩形的位置?不懂...
/tmp/duangsuse.sock
模型的总结: Area(其实这个和 Box 有点混淆的说):就是一个 java.awt.image.BufferedImage 的扩展 + 可以 draw 一个 Point + 可以 drawLine 一组 Point 构成的 Line + 可以 drawTriangle 一组 Line 构成的 Triangle fun draw(points: Set<Point>) = points.forEach { p -> draw(p) } fun draw(p: Point) = image.setRGB(p.x…
#Math 总而言之,数学尤其是这类解析几何是十分复杂难懂的...

因为模拟需要消耗大量的资源 而且我不是一般的不擅长计算 所以一次,显然是不够用的,还是做我其他的事情吧

这个内容,其实还不如拿纸笔去算

其实我觉得数学家是尤其值得被尊重的,视计算机科学完全独立于数学或者说数学存在着各种各样非常不好的地方,是原罪,而且比 CS 差 是十分错误的想法

不应该继续这种傲慢和偏见,尤其是现在当的确,很多工程师就不知道自己做的其实是非常 trivial 的事情,我现在觉得 真的不如数学,数学是真的难,是深度上不一般的变化而不是死着傻记

作为一个 还没有彻底脱离复杂而且愚蠢的编程的人来说,我是没有资格去对数学评头论足的,做概论的都是傻瓜

上面这种公式,我是无法列出来的... 应该说要我去弄可能要算斜率、比较两个点的位置情况什么的,我无法理解那个 c 对数值的综合,我不知道为啥 c 是在 dy 后才被加上的,显然这些得笔纸做很多实验才好...

简洁虽然是难懂,但是背后真正暗含着金玉珠玑才是真正应该关注的内容

数学的逻辑、推导和变形 是非常巧妙的事情,尤其是如果这些东西能够被显示地列出来的话 就更好了

计算机图形学是对于 CS 爱好者来说,接触数学的一个相当好的方法,当然机器学习也是

这次的话会推荐一篇关于线性代数的博客文章(和一个博客)
和 Telegram 上一个学数学的开发者 @LEXUGE 学弟,曾经写了 XCH 化学等式配平器,在他的频道上可以找到关于 XCH 原理的文章(就是转化为关于原子个数的齐次线性方程组,然后高斯—约当法消元求解)

计算机科学是解决问题的科学,但是也和数学有着一样的本性,可以从 Scala, Haskell, Agda, Racket 之类稍微好一点的代码里看到 其实都是对自己想法的描述而已,但思路才是最重要的,trivial 的东西 才不算什么
This media is not supported in your browser
VIEW IN TELEGRAM
冰封还说自己数学不好,如果公式不是抄的的话,这 16 年的水平已经很正常甚至属于湖北靠前的那种人了
比起我一直是数学菜鸡来说,真的很难熬啊
/tmp/duangsuse.sock
比起我一直是数学菜鸡来说,真的很难熬啊
也是最近的事,这个暑假之前我从没动过数学
就很菜,而且数学能力居然可以和算法能力是绑定的... 之前一直不这么想,现在看来还真是有点意思

为什么一个人会把树图转来转去 的 却不能把数字和图形扭来扭去呢... 也是很正规思路

现在我还太工程(指水平)了,从抽象和模拟、模式识别开始,吃枣有一天要学数学的,💊
#Project #Math #statement https://duangsuse-valid-projects.github.io/Share/

里面放了很多闲杂分享,基本都是那种特别长... 的东西,也算是代表了我现在的水平(虽然一直也就那样,不高不低)
也有不是我的东西,比如打算学高斯-约当消元法没学成(好像是因为数学基础太差)排版的原文 PDF

也有这个暑假的东西,比如那两篇超长的文本... 链接放在后面
/tmp/duangsuse.sock pinned «#Project #Math #statement https://duangsuse-valid-projects.github.io/Share/ 里面放了很多闲杂分享,基本都是那种特别长... 的东西,也算是代表了我现在的水平(虽然一直也就那样,不高不低) 也有不是我的东西,比如打算学高斯-约当消元法没学成(好像是因为数学基础太差)排版的原文 PDF 也有这个暑假的东西,比如那两篇超长的文本... 链接放在后面»
/tmp/duangsuse.sock
其实,我应该认清楚现况。 一方面,我学的知识的确是很『冷门』 冷门到资深的工程派里很少有人会出来讲,因为它也不是热门学科的知识(比如永远热门的算法、信息学、计算机图形学、软件工程和软件架构、数据库、大数据分析、分布式、机器学习、计算机视觉、实时处理什么的) 另一方面,我学的的确不够深,比如我都没有用 LLVM 写哪怕一个编译器出来 再从读者的角度看,一方面,Telegram 中文圈多是『工程』居多的人,而且基本都是『做出来就行』的风格,找到一个或者几个支持的库、服务,会用即可,他们不追求我所想的东西…
改天我就会拿 LLVM 写我的第一个能用的语言实现了,现在二元解析的问题已经解决、Essay-LLVM-FirstTry 的 IR 构造 API 也基本了解了(虽然 JIT 一直 Segfault...) C++ 也基本入门