Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Complex Function Plotter

Brandon Pelfrey edited this page Oct 11, 2015 · 4 revisions

Plotter Screenshot

What is this?

This tool allows you to visualize, in real-time, in a browser, how complex functions distort the complex plane, like in the Conformal Pictures Wikipedia entry.

The rendered image is created by evaluating the user-supplied function and then using the results of that function to look up a color in an image which is infinitely tiled over the Complex Plane. By changing the expression in the input field, you can visualize how various functions distort the plane.

It's important to note that When rendering with these infinitely-tiled images, the mapping that is rendered is actually the inverse of the function given. This is because it is prohibitively expensive to compute images of the function itself. (In fact, we are rendering a kind of "pull-back".) Specifically, when rendering a pixel in the image, the location of that pixel in the complex plane is passed to your function, which produces a complex value. That transformed value specifies a location in the original image. This procedure is fast, but plots the inverse of the function given. So, if you want to plot e.g. log(z), then you should instead put in e^z.

Available Functions and Variables

There are a large number of functions and variables at your disposal.

  • Basic arithmetic operators -- "+ - * /" for combining various complex numbers
  • Functions -- "sin, cos, log, ^" for computing sinus and cosine, along with complex power and logarithms
  • Constants -- "<a,b>" for defining a complex number (a,b) from two real-values.
  • Pre-Defined Constants -- "pi, e, a, b" for using common constants. a and b will take on the value of the real and complex part of the point in the complex plane.
  • "Animated" Parameter -- "t" can be used in place of a real value to provide some animation to your plot. It slowly oscillates between -1 and 1.

Neat Examples

How does it work?

This tool runs in real-time thanks to a few other libraries.

  1. Expressions given by the user are parsed using the PEG.js library along with a grammar written specifically for this plotter that encapsulates complex-valued arithmetic and functions. The grammar is fed to PEG.js which produces a parser, and that parser is then used to transform mathematical expressions into a WebGL-compatible snippet of code. The generated code is placed into a WebGL shader template and compiled to give a new rendering based on the expression supplied by the user. All of this happens ~instantly, even on a phone.
  2. THREE.js is used to set up the full-window Quad, manage GLSL uniforms, shader compilation, etc. (Basically all the boilerplate display logic).
  3. jQuery is used for some very minor setup logic (could be easily removed...)