{"id":24655178,"url":"https://github.com/xtenzq/2d-metaballs","last_synced_at":"2025-03-21T02:16:38.708Z","repository":{"id":115827700,"uuid":"103397700","full_name":"xtenzQ/2D-metaballs","owner":"xtenzQ","description":"💧 Two dimensional metaballs Java implementation using OpenGL","archived":false,"fork":false,"pushed_at":"2022-04-08T07:14:43.000Z","size":2859,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-25T22:40:10.611Z","etag":null,"topics":["2d-metaballs","blobs","java","jogl","liquid-simulations","metaball","metaballs","opengl","physics","simulation","university-project","water-simulation"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xtenzQ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-13T12:36:27.000Z","updated_at":"2024-11-03T05:06:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"84cc69da-58f8-4fef-89f6-b2ffcdad8b9c","html_url":"https://github.com/xtenzQ/2D-metaballs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xtenzQ%2F2D-metaballs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xtenzQ%2F2D-metaballs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xtenzQ%2F2D-metaballs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xtenzQ%2F2D-metaballs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xtenzQ","download_url":"https://codeload.github.com/xtenzQ/2D-metaballs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244722744,"owners_count":20499154,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2d-metaballs","blobs","java","jogl","liquid-simulations","metaball","metaballs","opengl","physics","simulation","university-project","water-simulation"],"created_at":"2025-01-25T22:36:20.460Z","updated_at":"2025-03-21T02:16:38.702Z","avatar_url":"https://github.com/xtenzQ.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Metaballs 2D\n\n## Contents\n\n1. [Before we start](#before-we-start)\n2. [IDEs and plugins used](#ides-and-plugins-used)\n3. [Definition](#definition)\n4. [Defining circles](#defining-circles)\n5. [Marching squares method](#marching-squares-method)\n6. [Project structure](#project-structure)\n7. [Screenshots](#screenshots)\n\n## Before we start\nThis project is based on following articles:\n1. \"[Metaballs and Marching Squares](http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares/)\" by [Jamie Wong](https://github.com/jlfwong)\n2. \"[Marching Squares Implementation](http://www.tomgibara.com/computer-vision/marching-squares)\" by Tom Gibara\n3. \"[Polygonising a scalar field](http://paulbourke.net/geometry/polygonise/)\" by [Paul Bourke](http://paulbourke.net/)\n4. \"[Metaballs](https://en.wikipedia.org/wiki/Metaballs)\" from [Wikipedia](https://en.wikipedia.org/)\n\nSpecial thanks to [@aptem336](https://github.com/aptem336) for helping me to seek for information and implementations of similar projects. Go check his own [implementation of 3D metaballs](https://github.com/aptem336/MetaBalls).\n\n*The application is developed as the part of the project for computer graphics course at [Irkutsk National Research Techincal University](http://www.istu.edu/eng/).*\n\n## IDEs and plugins used\n- NetBeans IDE ([Download](https://netbeans.org/downloads/index.html))\n- NetBeans OpenGL Pack ([Download](http://plugins.netbeans.org/plugin/3260/netbeans-opengl-pack))\n\n## Definition\n\u003e **Metaballs** are organic-looking objects that can be defined as a function in n-dimensions. - _Wikipedia_\n\n![Metaballs from Wikipedia](https://upload.wikimedia.org/wikipedia/commons/6/6d/Metaball_contact_sheet.png)\n\n*Metaballs from [Wikipedia](https://en.wikipedia.org/wiki/Metaballs)*\n\nI'm gonna show you the way to code 2D metaballs and explain some math-related stuff.\n\n## Defining circles\n\n_Based on Jamie Wong article [1]_\n\nAs we have two dimensional metaballs the problem is to find all the points inside a circle limited by its bounds. Let’s look at equation defining a circle with center at (x0,y0) and radius r:\n\n![Circle equation](https://i.imgur.com/Gwz2ObP.png?1)\n\nIf we want to model all the points inside circle including its bound:\n\n![Circle equation](https://i.imgur.com/S93vAWS.png?1)\n\nHaving all the interacting circles we can model all the points inside them if a circle of i is defined with center at (xi,yi) and radius ri:\n\n![Circle equation](https://i.imgur.com/1AmbnoU.png?1)\n\nAnd finally we get the equation defining two dimensional metaballs:\n\n![Circle equation](https://i.imgur.com/OjrIRQr.png?1)\n\nCode:\n```Java\npublic static double f(double[] B) {\n    double sum = 0;\n    for (Circle circle : Data.Balls) {\n        // SUM (r_i)^2 / ((x - x_i)^2 + (y - y_i)^2)\n        sum += Math.pow(Data.circleSize, 2) / ((Math.pow(B[0] - circle.x, 2) + Math.pow(B[1] - circle.y, 2)));\n    }\n    return sum;\n}\n```\n## Marching squares method\n\n\u003e **Marching squares** is a computer graphics algorithm that generates contours for a two-dimensional scalar field (rectangular array of individual numerical values) - _Wikipedia_\n\n_Best solution with detailed explanation is given in Paul Bourke article [3]_.\n\n![Imgur](https://i.imgur.com/E8jT2fd.png)\n\nAll kinds of grid cell angles\n\nBinary tables:\n\n```Java\n/**\n * Binary tables\n */\nstatic int[] edgeTable = {\n    0x0, 0x9, 0x3, 0xA,\n    0x6, 0xF, 0x5, 0xC,\n    0xC, 0x5, 0xF, 0x6,\n    0xA, 0x3, 0x9, 0x0\n};\n\nstatic int[][] lineTable = {\n    {-1, -1, -1, -1},\n    {3, 0, -1, -1, -1, -1},\n    {0, 1, -1, -1, -1, -1},\n    {1, 3, -1, -1, -1, -1},\n    {1, 2, -1, -1, -1, -1},\n    {1, 2, 3, 0, -1, -1},\n    {0, 2, -1, -1, -1, -1},\n    {2, 3, -1, -1, -1, -1},\n    {2, 3, -1, -1, -1, -1},\n    {0, 2, -1, -1, -1, -1},\n    {0, 1, 2, 3, -1, -1},\n    {1, 2, -1, -1, -1, -1},\n    {1, 3, -1, -1, -1, -1},\n    {0, 1, -1, -1, -1, -1},\n    {3, 0, -1, -1, -1, -1},\n    {-1, -1, -1, -1, -1, -1}\n};\n```\n\nMarching squares method:\n\n```Java\nprivate static void buildSquare(int i, int j) {\n\n    double[][] gridP = wMath.gridPoints(i, j);\n    double[] gridV = wMath.gridValues(i, j);\n    int squareIndex = wMath.squareIndex(gridV);\n    int edges = wMath.edgeTable[squareIndex];\n    if (edges != 0) {\n\n        double[][] vertList = new double[4][2];\n\n        if ((edges \u0026 1) \u003e 0) {\n            vertList[0] = wMath.vertexInter(gridP[0], gridP[1], gridV[0], gridV[1]);\n        }\n        if ((edges \u0026 2) \u003e 0) {\n            vertList[1] = wMath.vertexInter(gridP[1], gridP[2], gridV[1], gridV[2]);\n        }\n        if ((edges \u0026 4) \u003e 0) {\n            vertList[2] = wMath.vertexInter(gridP[2], gridP[3], gridV[2], gridV[3]);\n        }\n        if ((edges \u0026 8) \u003e 0) {\n            vertList[3] = wMath.vertexInter(gridP[3], gridP[0], gridV[3], gridV[0]);\n        }\n\n        double[][][] lines = new double[2][2][2];\n        int nlines = 0;\n        for (i = 0; wMath.lineTable[squareIndex][i] != -1; i += 2) {\n\n            lines[nlines][0] = vertList[wMath.lineTable[squareIndex][i]];\n            lines[nlines][1] = vertList[wMath.lineTable[squareIndex][i + 1]];\n            nlines++;\n        }\n\n        for (j = 0; j \u003c nlines; j++) {\n            Grid.createLine(lines[j], Data.metaColor);\n        }\n    }\n}\n```\n\nLinear interpolation:\n```Java\n    public static double[] vertexInter(double[] D, double[] B, double fD, double fB) {\n        double[] mS = new double[]{(D[0] + B[0]) / 2, (D[1] + B[1]) / 2};\n        double[] Q = new double[2];\n        if (Math.abs(1 - fD) \u003c 0.0005) {\n            return D;\n        } else if (Math.abs(1 - fB) \u003c 0.0005) {\n            return B;\n        } else if (Math.abs(fD - fB) \u003c 0.0005) {\n            return mS;\n        } else {\n            double exp = (1 - fB) / (fD - fB);\n            Q[0] = B[0] + (D[0] - B[0]) * exp;\n            Q[1] = B[1] + (D[1] - B[1]) * exp;\n        }\n        return Q;\n    }\n\n```\n\n## Project structure\n\nThe project is made up of 8 classes:\n- [Circle](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/Circle.java) class defines metaballs' structure and methods and implements basic physics\n- [Data](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/Data.java) class stores fields of parameters for metaballs\n- [Grid](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/Grid.java) class stands for grid definition\n- [Impulse](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/Impulse.java) class contains a method giving impusle to metaball\n- [Interface](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/Interface.java) class builds interface\n- [Listener](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/Listener.java) class is obviously to listen to different program events like keyboard or mouse events\n- [Metaballs](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/MetaBalls.java) class is the main class of the program\n- [wMath](https://github.com/xtenzQ/2D-metaballs/blob/master/src/Main/wMath.java) class defines all the methods calculating all math-related parameters\n\n## Screenshots\n\nMain window:\n\n![Main Window](https://i.imgur.com/YgTBaLW.png?1)\n\nShowing grid inside circles:\n\n![Grid inside circles](https://i.imgur.com/zKZG4e2.png?1)\n\nMarching squares mode enabled:\n\n![Marching squares](https://i.imgur.com/cPyVp28.png?1)\n\nWith enabled interpolation:\n\n![Enable interpolation](https://i.imgur.com/kSVVwKh.png?1)\n\nScaling up a grid:\n\n![Scaling up a grid](https://i.imgur.com/CeRcjqH.png?1)\n# UNDER CONSTRUCTION\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxtenzq%2F2d-metaballs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxtenzq%2F2d-metaballs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxtenzq%2F2d-metaballs/lists"}