摄影透视的原理

透视的原理 单点透视 根据常识我们可以知, 走廊两边的墙一般是平行的直线, 但在摄影作品中我们会发现, 体现在照片中的走廊趋势并不是平行的, 具体体现 画一下透视可以看出 所有物理上不平行于视线的线, 延长后最终趋近于一点, 本文是探讨一下为什么会出现这种结果. 设这么一个场景 已知摄像机位置, 也就是漫画中我们读者的视角或者照片中相机所在的位置. 其距离1点的物理距离为 $L_1=\sqrt{x^2+R^2}$ , 距离2点则为$L_2=\sqrt{x^2+(2R)^2}$, 即距离n点的位置为$L_n=\sqrt{x^2+(nR)^2}$, x固定不变, 当n逐渐增大的时候, $\lim\limits_{\substack{n\to\infty }} L_n=nR$, x可以忽略不计, 此时两点的距离(图中橙色的部分) 两个橙色的长度在极限距离可以视作相等, 根据上述距离公式$L_n=\sqrt{x^2+(nR)^2}$(自变量为$n$)可以知道, 此函数一阶导数为$L_n’=\dfrac{R^2}{\sqrt{\dfrac{x^2}{n^2}+R^2}}$, 随着n的增大, 导数值逐渐变大, 最终趋向1, 即最终L最终等于R(常数),

2020-09-08 · Moo

算法: 只出现一次的数字

只出现一次的数字 问题描述 给定一个非空整数数组, 除了某个元素只出现一次以外, 其余每个元素均出现两次. 找出那个只出现了一次的元素. 题目地址: https://leetcode-cn.com/problems/single-number/ 说明 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 输入: [2,2,1] 输出: 1 输入: [4,1,2,1,2] 输出: 4 解答 开始想的是用collection函数来统计次数, 但发现题目的说明讲到了不使用额外的空间, 所以作罢. 后来想用sort来进行排序, 再进行for num in nums进行遍历, 来判断相邻两个是否相同从而找出不同的元素, 但这样O(n)的时间复杂度就太高了. 而且严格来说sort也使用了额外的空间(见下文解释) python的sort方法 见python源码中的sort实现 int PyList_Sort(PyObject *v) { if (v == NULL || !PyList_Check(v)) { PyErr_BadInternalCall(); return -1; } v = list_sort_impl((PyListObject *)v, NULL, 0); if (v == NULL) return -1; Py_DECREF(v); return 0; } 使用的是Timsort算法, 从时间复杂度来讲, 这个算法是高效的. 从空间复杂度来讲,需要的开销在数量大的时候会增大. 下面是JSE7 中Timsort实现代码中的一段话,可以很好的说明Timsort的优势: A stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when running on partially sorted arrays, while offering performance comparable to a traditional mergesort when run on random arrays. Like all proper mergesorts, this sort is stable and runs O(n log n) time (worst case). In the worst case, this sort requires temporary storage space for n/2 object references; in the best case, it requires only a small constant amount of space. ...

2020-09-08 · Moo

算法: 代表字母的整形数组组合字符串的可能性

问题描述 已知有一个长度为 26 的整型数组, 分别代表 26 个字母的个数, 问这些字母能组成多少种不同的字符串(取模 1000000007). 问题求解 纯暴力 开始觉得很简单, 纯迭代问题, 抬手就来. int calc(int[] nums) { int ret = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] > 0) { nums[i]--; ret += calc(nums); ret %= 1000000007; nums[i]++; } } return ret > 0 ? ret : 1; } 结果超时, 不行, 看来只能用数学方法求解. 数学方法 $$ Sum=\dfrac{A_{字母总数}^{字母总数}}{A_{A的数量}^{A的数量}\times……\times A_{2}^{2}} $$ 题目没有讲太清楚(是否这些字母一定要全部使用), 这里为了简单就假设全部使用. 解法一:排列组合. 生成字符串长度是 $sum=a_0+a_1+a_2+…+a_{25}$. 放 $a$ , 有$(sum, a0)$种选择的方法; 放$ b$, 有$(sum - a0, a1)$种方法; 放 $c$, 有$(sum - a0 - a1, a2)$种方法…..直到最后 程序 private long solve1(int[] letters) { int sum = 0; for (int c : letters) { sum += c; } BigInteger r = BigInteger.ONE; for (int c : letters) { BigInteger s = choose(sum, c); r = r.multiply(s); sum -= c; } return r.longValue(); } private static BigInteger choose(int n, int k) { BigInteger r = BigInteger.ONE; for (int i=0; i<k; i++) { r = r.multiply(BigInteger.valueOf(n - i)); } for (int i=2; i<=k; i++) { r = r.divide(BigInteger.valueOf(i)); } return r; } 解法 2: EGF (指数生成函数)。 这是个排列问题所以用指数生成函数. ...

2020-09-07 · Moo