8 पॉइंट द्वारा GN⁺ 2023-08-10 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • g9.js एक interactive graphics library है, जो numeric key-value data को render function से जोड़ती है; जब user किसी graphic element को drag करता है, तो यह नए data values खोजकर पूरे scene को फिर से draw करती है
  • मुख्य API सिर्फ g9(initialData, render[, onChange]) है, जो initialData और drawing context को render(data, ctx) में पास करके points, lines, circles, images आदि draw करता है
  • drag जैसी manipulation होने पर, g9 संभावित data-value space को optimize करके इच्छित बदलाव के सबसे करीब value ढूंढता है, और जरूरत पड़ने पर onChange से नया data पास करता है
  • gallery basic point mirroring से लेकर Bézier curves, तीन points से define होने वाला circle, cube, dragon curve, images, clock, LOGO Turtle, Grid Warp, Crank and Piston तक के examples step-by-step दिखाती है
  • affects, ctx.pure, getData, setData, isManipulating, Math.max/Math.min जैसे patterns से manipulable variables की range, re-rendering, और animation के दौरान user input handling को configure किया जा सकता है

g9.js का operation flow

  • g9.js एक single function g9(initialData, render[, onChange]) expose करता है
  • पहले numeric values वाला key-value data बनाया जाता है
    • example में foo: 10 जैसा initialData object इस्तेमाल होता है
    • संबंधित documentation initialData in the docs में है
  • data और drawing context render(data, ctx) को दिए जाते हैं, और render function data values के आधार पर तय करता है कि क्या draw करना है
    • example में ctx.point(data.foo, 17) से point draw किया जाता है
    • संबंधित documentation render in the docs में है
  • जब user किसी element को नई position पर drag करता है, तो g9 संभावित data-value space में सबसे करीबी बदलाव पैदा करने वाली value खोजता है
    • circle को left की ओर drag करने पर example में {foo: 8} जैसा नया data मिल सकता है
  • नया data तय हो जाने पर consistency बनाए रखने के लिए पूरा scene फिर से render किया जाता है
    • अगर onChange callback दिया गया हो, तो g9 नया data पास करता है ताकि page के दूसरे हिस्से update किए जा सकें
  • पूरा API Docs में देखा जा सकता है

Basic shapes और data constraints

  • Basic example सिर्फ दो points इस्तेमाल करने वाला minimal example है
    • render function एक point को (x, y) पर और दूसरे point को (y, x) पर draw करता है
    • एक point को drag करने पर दूसरा point ऐसे move करता है जैसे वे एक-दूसरे के mirror हों
  • Rings radius और angle data को trigonometric functions में डालकर points को दो circles के रूप में arrange करता है
    • inner points लाल रंग में draw किए जाते हैं
    • commented-out ctx.line(...) को enable करने पर दो circles के points के बीच lines जोड़ी जा सकती हैं
  • The affects option g9 के basic shapes को मिलने वाला affects option दिखाता है
    • affects specify करता है कि shape data के किस हिस्से को बदल सकता है
    • तीन lines अलग-अलग affects values इस्तेमाल करती हैं
    • एक line सिर्फ l2_start_x, l2_start_y बदलती है, और दूसरी line l3_start_x, l3_end_y बदलती है
  • Using Max and Min to limit a point's range of motion Math.max(Math.min(...)) से point की movement range को limit करता है
    • middle point की position x1 + 20 और x3 - 20 के बीच सीमित रहती है
    • एक अलग point data.x2 value को ज्यों का त्यों दिखाता है

Curves, geometry, 3D examples

  • Bézier Curve Wikipedia के quadratic Bézier curve animation को interactive version में बदलने वाला example है
    • start, middle, end coordinates और t value को data के रूप में इस्तेमाल करता है
    • tween= label दिखाता है, और कई चरणों के line segments से smooth curve बनाता है
    • intermediate helper lines और curve segments में affects: ['t'] specify किया गया है
  • Three points define a circle तीन points से circle define करता है
    • तीन points के बीच line segments, midpoints, और perpendicular direction lines calculate करता है
    • calculated center point पर point लगाता है, और पहले point तक की दूरी को radius मानकर green circle draw करता है
  • cube cube के vertices और edges बनाकर 3D rotation, translation, और projection के बाद उन्हें 2D lines के रूप में draw करता है
    • rx, ry, rz functions से axis rotations calculate किए जाते हैं
    • project function 300 * p[0] / p[2], 300 * p[1] / p[2] तरीके से projection करता है
    • edges affects: ['ax', 'ay'] का इस्तेमाल करते हैं, जिससे drag करके rotation values बदली जा सकती हैं

Fractals, procedural drawing, images

  • dragon recursive function dragon(...) से dragon curve draw करता है
    • data में squareness, fromX, fromY, toX, toY शामिल हैं
    • line option affects: ['squareness'] का इस्तेमाल करके curve shape manipulate करता है
    • start और end points radius 5 वाले points के रूप में दिखाए जाते हैं
  • tree recursively tree draw करता है
    • data deltaAngle, attenuation, startLength है
    • branch endpoints और lines affects: ['deltaAngle', 'attenuation'] इस्तेमाल करते हैं
    • अगर n > 3 हो, तो line का color brown, वरना green रखा जाता है
    • onChange callback बदला हुआ data console में output करता है
  • LOGO Turtle simulator make_turtle(ctx) से simple Turtle interface बनाता है और बार-बार lines draw करता है
    • data r और theta है
    • forward current direction में move करके line draw करता है, और dturn degree-based rotation को radians में बदलता है
  • Grid Warp grid points को warp करने वाला transform apply करता है
    • data spin और scale है
    • प्रत्येक point की दूरी r और angle theta calculate करने के बाद theta + data.spin * r से rotation amount बदलता है
    • -10 से 10 तक के i, j combinations से points draw करता है
  • image ctx.image से image draw करता है
    • image URL, x, y, width 200, height 200 specify करता है

Mechanical devices और time-based interaction

  • Kevin Clock time data इस्तेमाल करके clock shape draw करता है
    • minute hand data.time / 60, second hand data.time का इस्तेमाल करके Math.cos, Math.sin से endpoints calculate करता है
    • setInterval हर 50ms में time को 0.01 बढ़ाता है
    • graphics.isManipulating true न होने पर ही getData() और setData(data) से time update करता है
  • Crank and Piston crank और piston structure draw करता है
    • data सिर्फ time है
    • housing color Math.cos(data.time) से बने HSL value के अनुसार बदलता है
    • crank, shaft, और piston को lines, rectangles, circles से draw करता है
    • animation block commented out है; enable करने पर यह हर 10ms में time को 0.05 बढ़ाने के लिए बना है
  • tongs rotation और repeated line segments से tongs जैसा shape बनाता है
    • data a, b है
    • rotate(x, y, a) से coordinates rotate करता है, और चार iterations में दो rows के line segments draw करता है
    • onChange callback changed data को console में output करता है

1 टिप्पणियां

 
GN⁺ 2023-08-10
Hacker News टिप्पणियां
  • रिकर्सिव ट्री की 5–6 स्तर गहराई पर render हुए node को पकड़कर हिलाने पर बाकी ट्री का react करना जादू जैसा दिखता है
    किसी भी leaf node position से ट्री के शुरुआती parameters को स्पष्ट रूप से infer करने वाला function न होने पर भी यह काम करता है
    उत्सुकता है कि यह कैसे implement किया गया है, और जब points की positions किसी ठीक-ठाक smooth function से जुड़ी नहीं होतीं तो यह कितना अच्छा काम करता है

    • मेरा अनुमान है कि हिलाए गए object के लिए हर parameter के प्रभाव को function sampling दो बार करके partial differentiate किया जाता होगा, फिर सामान्य gradient descent चलाया जाता होगा, और convergence तक इसे दोहराया जाता होगा
      या फिर कोई off-the-shelf optimizer डाल देने से भी काम हो सकता है
    • यह inverse kinematics जैसा तरीका लगता है
      inverse kinematics problems को model और solve करने के कई तरीके हैं
      उनमें सबसे flexible तरीके आम तौर पर iterative optimization से approximate solution ढूंढते हैं, क्योंकि forward kinematics equations को उल्टा solve करना कठिन होता है और solution space खाली भी हो सकता है
      कई तरीकों का मूल विचार forward kinematics equations को Taylor series expansion से model करना है, जिसे मूल system की तुलना में उलटकर solve करना आसान हो सकता है
  • पहले मुझे लगा कि यह cool और साफ-सुथरा simple API है, और वही काम करने के लिए d3 से ज्यादा पसंद आएगा
    लेकिन “जब कोई graphics के साथ interact करता है, जैसे किसी element को नई position पर drag करने की कोशिश करता है, तो g9 संभावित data values के space में optimize करके उस बदलाव के सबसे करीब वाली value ढूंढता है” पढ़ने के बाद, यह काफी जादुई DOM manipulation जैसा महसूस हुआ
    जिन applications में chart को manipulate करके data बदलना हो, वे ज्यादातर काफी special लगती हैं, लेकिन मजे के लिए use करना universal है
    ऐसा use case आए तो बहुत आनंद आएगा

    • यह charts के लिए नहीं, बल्कि interactive demos के लिए है
      उत्सुक हूं कि क्या आपने page के दूसरे examples भी खुद आजमाए हैं
    • applications के लिहाज से, ऐसे कई STEM concepts हैं जिन्हें interaction allow करने पर प्रभावी ढंग से समझाया जा सकता है
    • मैं इसे advanced science नहीं कहूंगा
      drag event के शुरुआती कुछ frames में speed और vector का average लें, फिर और frames के साथ average को लगातार update करें, और predicted endpoint की ओर सब कुछ smooth ease-in-out से move करना शुरू कर दें, तो यह “संभावित values के space में optimization” के काफी करीब हो जाता है
  • पहले HN पर जब इस पर चर्चा हुई थी, तब कुछ दिलचस्प comments थे: https://news.ycombinator.com/item?id=12572412

  • यह कैसे काम करता है, इसका explanation देखना चाहूंगा। मुझे यह black magic जैसा लगता है
    उदाहरण के लिए, दो points हैं, एक (0, 10) पर और दूसरा (10, 0) पर; अगर बाद वाले point को (20, 0) तक drag करें, तो system कैसे जानता है कि पहले point को भी उसी दूरी से reflect होना चाहिए?
    फिर कहूंगा, यह magic है, और बनाने वाले ने सच में बहुत अच्छा काम किया है

    • drawn element की position और drag action द्वारा मांगी गई नई position के बीच error measure करने वाला function define किया जाता है
      इस function को data variables के संबंध में partial differentiate किया जाता है, function को minimize करके नए data values ढूंढे जाते हैं, फिर नए optimal data values से सब कुछ फिर से render किया जाता है
      थोड़ा confusing इसलिए है क्योंकि यहां जिसे आम तौर पर “data” कहा जा रहा है, वह mathematical optimization में parameters, और statistics/machine learning में weights कहलाने वाली चीज है
      machine learning में fixed चीज को “data” कहा जाएगा, इसलिए यहां dragged element की position data के बराबर है
    • पर्याप्त विकसित mathematics को magic से अलग नहीं पहचाना जा सकता, और यहां “पर्याप्त विकसित” का threshold उम्मीद से काफी कम है
  • काफी शानदार दिखता है
    एक कमी यह है कि markers या selection indicators नहीं हैं, इसलिए explanation पहले न पढ़ें तो यह बहुत स्पष्ट नहीं होता कि objects को drag किया जा सकता है
    object positions को readjust करने का तरीका भी थोड़ा confusing है
    आम तौर पर pointer handler define करके input के हिसाब से transform किया जाता, लेकिन अगर मेरी समझ सही है तो engine उसे automate करने के लिए अपना best guess लगा रहा है

  • कुछ साल पहले इसे देखकर उत्साहित हुआ था, और browser में PyTorch जैसी library के साथ चलाने के लिए इसे Pyodide में port किया था: https://srush.github.io/g9py/
    JavaScript से थोड़ा ज्यादा अटकता है, लेकिन शुरुआत में इसका चलना ही हैरान करने वाला है

  • यह witchcraft जैसा महसूस होता है। बेहद impressive है

  • 2D CAD के constraint-based sketch tools से इसमें समानता दिखती है

  • इसे कहां इस्तेमाल करना चाहिए, यह ठीक से नहीं पता, लेकिन इसे सच में clever तरीके से बनाया गया है

    • संभावित रूप से इसे किसी भी drag-and-drop interface में इस्तेमाल किया जा सकता है
      problem को देखने का तरीका इतना अलग है कि intuition बनाने के लिए इसे किसी चीज में खुद इस्तेमाल करके देखना पड़ेगा
  • शिक्षा में trigonometry या दूसरे math concepts समझाने के लिए यह बहुत उपयोगी हो सकता है
    कई visual learners को formulas को visual space से map करने में कठिनाई होती है, और थोड़ा interaction जोड़ने से समझ को मजबूत करने में बहुत मदद मिलती है