I am thrilled to announce that Social Street View has won the Best Paper Award at Web3D 2016, which was held next to SIGGRAPH 2016 in late August! Please visit the project website for more details: http://www.socialstreetview.com I also published my slides and videos.
Some issues in VR – A personal note
Vergenceaccommodation conflict Vergence movements are closely connected to accommodation of the eye. Under normal conditions, changing the focus of the eyes to look at an object at a different distance will automatically cause vergence and accommodation, sometimes known as the accommodationconvergence reflex. Visual odometry Match moving VR in practice GPUbased rendering (almost) as usual (OpengGL,…
My Chatbot in WeChat Platform
It is nothing related with AR and VR. But in the era of AI, who wouldn’t want to develop a cute chatbot? Feel free to scan the QR code below to follow our cute pet 🙂 Most of the code is based upon Python. I have developed the following functionalities. AIML matching Dictionary Idiom Wikipedia…
PostProcessing: Brightness, Contrast, Hue, Saturation, and Vibrance
Realtime image manipulation is always fascinating. With the power of the modern GPU, it is possible to achieve the postprocessing effects all in a single shader. Remember that in GLSL, matrix are column major. Brightness is a float between [1, 1], directly adding to the RGB Contrast is a float between [0, 1, ∞], directly…
[Leetcode] 691. Stickers to Spell Word
Leetcode 691 is an interesting problem, I didn’t notice that T <= 15. BFS is good enough (and even faster) for this, but dynamic programming with bit compression is the ultimate solution with more words.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 
class Solution { public: // 691. Stickers to spell word // Time: O(2^T * S * T), // T <= 15 // T is the number of letters in the target word, // S is the total number of letters in all stickers // Space: O(2^T) int minStickers(vector<string>& stickers, string target) { using Freq = vector<int>; const int MAX_ALPHABET = 26; const int T = target.size(); vector<Freq> freqs(stickers.size()); // calc frequency statistics auto buildFreqFromString = [=](const string &s) { Freq ans(MAX_ALPHABET); for (const auto &c : s) ++ans[c  'a']; return ans; }; Freq targetFreq = buildFreqFromString(target); for (int i = 0; i < stickers.size(); ++i) { freqs[i] = buildFreqFromString(stickers[i]); // remove higher frequency than the target for (int j = 0; j < MAX_ALPHABET; ++j) freqs[i][j] = min(freqs[i][j], targetFreq[j]); } // test if a is the proper subset of b auto isProperSubset = [=](const Freq &a, const Freq &b) { for (int i = 0; i < a.size(); ++i) if (a[i] >= b[i]) return false; return true; }; // remove the proper subset of stickets for (int i = freqs.size()  1; i >= 0; i) { for (int j = 0; j < freqs.size(); ++j) if (i != j && isProperSubset(freqs[i], freqs[j])) freqs.erase(freqs.begin() + i); } auto getStringFromFreq = [=](const Freq &a) { string ans = ""; for (int i = 0; i < a.size(); ++i) { ans += string(a[i], 'a' + i); } return ans; }; vector<string> pieces(freqs.size()); for (int i = 0; i < freqs.size(); ++i) { pieces[i] = getStringFromFreq(freqs[i]); cout << i << " " << pieces[i] << endl; } const int MAX_T = 1 << T; vector<int> f(MAX_T, 1); f[0] = 0; for (int i = 0; i < MAX_T; ++i) { if (f[i] < 0) continue; for (const auto &piece : pieces) { int j = i; for (const auto &c : piece) { // find the first k that does not appear in state i for (int k = 0; k < T; ++k) { if ((j >> k) & 1) continue; if (target[k] == c) { j = (1 << k); break; } } if (f[j] < 0  f[j] > f[i] + 1) { f[j] = f[i] + 1; } } } } return f[MAX_T  1]; } // BFS, slower version // Time: O(N^{T+1} T^2), N is the number of tickers, T is the number of letters in the target word // In fact, it's O(C(N + T  1, T  1) T^2) int minStickers2(vector<string>& stickers, string target) { using Freq = vector<int>; const int MAX_ALPHABET = 26; vector<Freq> freqs(stickers.size()); // calc frequency statistics auto buildFreqFromString = [=](const string &s) { Freq ans(MAX_ALPHABET); for (const auto &c : s) { ++ans[c  'a']; } return ans; }; Freq targetFreq = buildFreqFromString(target); for (int i = 0; i < stickers.size(); ++i) { freqs[i] = buildFreqFromString(stickers[i]); // remove higher frequency than the target for (int j = 0; j < MAX_ALPHABET; ++j) { freqs[i][j] = min(freqs[i][j], targetFreq[j]); } } // test if a is the proper subset of b auto isProperSubset = [=](const Freq &a, const Freq &b) { for (int i = 0; i < a.size(); ++i) { if (a[i] >= b[i]) return false; } return true; }; // remove the proper subset of stickets for (int i = freqs.size()  1; i >= 0; i) { for (int j = 0; j < freqs.size(); ++j) { if (i != j && isProperSubset(freqs[i], freqs[j])) { freqs.erase(freqs.begin() + i); } } } using Item = pair<int, Freq>; // q stores the current step and current goal // the default queue queue<Item*> q; unordered_map<string, bool> vd; q.push(new Item(0, targetFreq)); vd[target] = true; auto hasOverlap = [=](const Freq &a, const Freq &b) { for (int i = 0; i < a.size(); ++i) { if (a[i] > 0 && b[i] > 0) return true; } return false; }; auto subtractFreq = [=](const Freq &a, const Freq &b) { Freq ans(26); for (int i = 0; i < a.size(); ++i) { ans[i] = max(0, a[i]  b[i]); } return ans; }; auto getStringFromFreq = [=](const Freq &a) { string ans = ""; for (int i = 0; i < a.size(); ++i) { ans += string(char(int('a') + i), a[i]); } return ans; }; auto isEmpty = [=](const Freq &a) { for (int i = 0; i < a.size(); ++i) if (a[i] > 0) return false; return true; }; // BFS while (!q.empty()) { auto current = q.front(); q.pop(); for (auto &freq : freqs) { if (!hasOverlap(current>second, freq)) continue; auto next = subtractFreq(current>second, freq); auto next_str = getStringFromFreq(next); if (isEmpty(next)) return current>first + 1; if (vd.find(next_str) == vd.end()) { q.push( new Item(current>first + 1, next) ); vd[next_str] = true; } } // we should delete the pointers, but not this time // other solutions are to use vectors instead of queue // and remove the vector in the end // delete current; } return 1; } }; 
[Summary] PatchTable: Efficient Patch Queries for Large Datasets and Applications
Dr. Connelly Barnes have led the research on patchbased algorithms over the years. Some of his most famous patchbased research are: PatchMatch (SIGGRAPH 2009, EECV 2010, CAF) Image Melding (SIGGRAPH 2012) Patchbased HDR video (SIGGRAPH Asia 2013) Synthesis of Complex (SIGGRAPH 2015) PatchTable (SIGGRAPH 2015) Artistic Media Digital BasRelief (SIGGRAPH 2007) RealBrush (SIGGRAPH 2013) DecoBrush…
Code Golf: Halftone Image
This is a code golf with the help of Dr. Neyret and coyote. Demo Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 
// forked from my: https://www.shadertoy.com/view/lsSfWV // taken Dr. Neyret and coyote's advices void mainImage( out vec4 O, vec2 u ) { vec2 R = iResolution.xy, M = iMouse.xy / R, S = ( M.y < 1e3 ? 6. : mix(3., 5.5, M.x/M.y) ) / R; O = vec4( length( M= mod( u/R, S)  S*.5 ) < dot( texture(iChannel0, u/R  M), vec4( .21, .72, .07, 0) ) * S.x * ( 1. + .3 * sin(iTime) ) ); } 
Hopf Fibration
According to Wikipedia: In the mathematical field of differential topology, the Hopf fibration (also known as the Hopf bundleor Hopf map) describes a 3sphere (a hypersphere in fourdimensional space) in terms of circles and an ordinary sphere. Discovered by Heinz Hopf in 1931, it is an influential early example of a fiber bundle. Technically, Hopf found a manytoone continuous function (or “map”) from the 3sphere onto the 2sphere such that each distinct point of the 2sphere comes from…
Dotted Drawing / Sketch Effect
After lunch, I want to replicate the sketch shader I wrote for the PencilvsCamera project. Additionally, I wrote a onepass shader for dotted drawing / sketch post processing effect, which I think is more aesthetically pleasing. Dotted Drawing Demo Click on the play button in the left bottom corner of the embedded ShaderToy window below, to…
Unified Gnomonic and Stereographic Projections
Gnomonic projection, or rectilinear projection, together with stereographic projection, are two most commonly used projection in rendering 360 degree videos, or other VR applications. Recently, I found the inverse converting function from screen coordinates to the two projections can be unified within a single function. It’s not really surprising since both projection uses spherical lens,…
Equirectangular, Gnomonic Projections, and Cubemaps
Background According to MathWorld, the gnomonic projection is a nonconformal map projection obtained by projecting points P_1 (or P_2) on the surface of sphere from a sphere’s center O to point P in a plane that is tangent to a point S (Coxeter 1969, p. 93). In a gnomonic projection, great circles are mapped to…
Clock
World
Random Posts
Share
Slideshow

Recent Posts
Twitter
My TweetsRecent Comments
 starea on Equirectangular, Gnomonic Projections, and Cubemaps
 Monty on Equirectangular, Gnomonic Projections, and Cubemaps
 Week 5: Being a Digital Curator – Site Title on Quick Tutorial on Refereces Management using Mendeley / Endnote / Word / ShareLaTeX
 starea on Tutorial of Ray Casting, Ray Tracing, Path Tracing and Ray Marching
 Ron Francis on Tutorial of Ray Casting, Ray Tracing, Path Tracing and Ray Marching
Archives
 October 2017
 August 2017
 July 2017
 April 2017
 March 2017
 February 2017
 January 2017
 December 2016
 November 2016
 October 2016
 September 2016
 June 2016
 April 2016
 March 2016
 February 2016
 December 2015
 November 2015
 October 2015
 September 2015
 August 2015
 July 2015
 June 2015
 May 2015
 September 2012
 October 2010
 May 2010
 July 2008
Categories
Meta