Showing preview only (210K chars total). Download the full file or copy to clipboard to get everything.
Repository: sdsmdg/trianglify
Branch: develop
Commit: e3ba5f976cb8
Files: 77
Total size: 187.4 KB
Directory structure:
gitextract_a4up19b2/
├── .gitignore
├── .project
├── .settings/
│ └── org.eclipse.buildship.core.prefs
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DOCUMENTATION.md
├── LICENSE.md
├── README.md
├── app/
│ ├── .classpath
│ ├── .gitignore
│ ├── .project
│ ├── .settings/
│ │ └── org.eclipse.buildship.core.prefs
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── sdsmdg/
│ │ └── kd/
│ │ └── trianglifyexample/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── sdsmdg/
│ │ │ └── kd/
│ │ │ └── trianglifyexample/
│ │ │ ├── AboutActivity.java
│ │ │ ├── CustomPalettePickerActivity.java
│ │ │ └── MainActivity.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── color_picked_imageview_border.xml
│ │ │ ├── ok_icon.xml
│ │ │ └── palette_icon.xml
│ │ ├── layout/
│ │ │ ├── activity_about.xml
│ │ │ ├── activity_custom_palette_picker.xml
│ │ │ └── activity_main.xml
│ │ ├── menu/
│ │ │ ├── menu.xml
│ │ │ └── menu_custom_palette_picker.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ └── test/
│ └── java/
│ └── com/
│ └── sdsmdg/
│ └── kd/
│ └── trianglifyexample/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── resources/
│ └── tables/
│ ├── palette-methods-table.tgn
│ └── trianglify-view-attributes-table.tgn
├── settings.gradle
└── trianglify/
├── .classpath
├── .gitignore
├── .project
├── .settings/
│ └── org.eclipse.buildship.core.prefs
├── build.gradle
├── proguard-rules.pro
└── src/
├── androidTest/
│ └── java/
│ └── com/
│ └── sdsmdg/
│ └── kd/
│ └── trianglify/
│ └── ExampleInstrumentedTest.java
├── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── com/
│ │ └── sdsmdg/
│ │ └── kd/
│ │ └── trianglify/
│ │ ├── models/
│ │ │ ├── Grid.java
│ │ │ ├── Palette.java
│ │ │ └── Triangulation.java
│ │ ├── presenters/
│ │ │ └── Presenter.java
│ │ ├── utilities/
│ │ │ ├── ExtendedColor.java
│ │ │ ├── Point.java
│ │ │ ├── ThreadLocalRandom.java
│ │ │ ├── Utilities.java
│ │ │ ├── colorizers/
│ │ │ │ ├── Colorizer.java
│ │ │ │ └── FixedPointsColorizer.java
│ │ │ ├── patterns/
│ │ │ │ ├── Circle.java
│ │ │ │ ├── Patterns.java
│ │ │ │ └── Rectangle.java
│ │ │ └── triangulator/
│ │ │ ├── DelaunayTriangulation.java
│ │ │ ├── DelaunayTriangulator.java
│ │ │ ├── Edge2D.java
│ │ │ ├── EdgeDistancePack.java
│ │ │ ├── NotEnoughPointsException.java
│ │ │ ├── Triangle2D.java
│ │ │ ├── TriangleSoup.java
│ │ │ └── Vector2D.java
│ │ └── views/
│ │ ├── TrianglifyView.java
│ │ └── TrianglifyViewInterface.java
│ └── res/
│ └── values/
│ ├── attrs.xml
│ └── strings.xml
└── test/
└── java/
└── com/
└── sdsmdg/
└── kd/
└── trianglify/
└── ExampleUnitTest.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# IntelliJ files
.idea
*.iml
# Maven output folder
target
# Misc
.DS_Store
Thumbs.db
*.swp
*.bak
================================================
FILE: .project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>trianglify</name>
<comment>Project trianglify created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>
================================================
FILE: .settings/org.eclipse.buildship.core.prefs
================================================
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
================================================
FILE: .travis.yml
================================================
language: android
jdk: oraclejdk8
sudo: required
android:
components:
- tools
- platform-tools
- tools
- build-tools-26.0.2
- android-27
- extra-google-m2repository
- extra-android-m2repository
script:
- ./gradlew build
- ./gradlew test
before_install:
- python <(curl -s https://raw.githubusercontent.com/TouK/sputnik-ci/master/sputnik-ci.py)
env:
global:
- secure: PIbHGVr+Bv0HbK6qOE6C0FrVqcsm/Q6kzFCOa4y9ixT8+2i82DDP4kyyy2ymKevmps+7+SCeJiW8KQkZa7gztSG0h1BoHJo0C6f0xiMYG4kY/7Gq4ZX3mehOVFUymxqhVED/NMK4a7JJxqcSH7JIkBLkuEaueqxc3CmHjI7LCqTr9yMdu/8ulhOeEL/Drg0zsNK9424K6BtxnTh6nNmbNfRnvxCgFc3mLuZ4J6/YN7lBagNiBhpr3XsXdvUC/W89UCcQCIkl/xBKPTxoUGxD6YG+IhapEJrQvqsFkvwFcsUUa9iL7+23QDlK7VGXeKZxwcMYWjRSVai3np94cHZwqivL1okoMFnIjqcAAzX5NOgd0VvM1dUqIwkXQDhp9IPGqDe/H1BiuRb8rmbJyRsxx5YjwksuPugDcG/B24qhyz4NM+gupMx0UE1DXS20xtE1kItEMzCyOJGXDwD9VR13ED0kYkcZoovPFdGFUOpAyAE9UYe1wDpDbmxF8o24tM5ICTcaATpiowWvBmS3i2qsEg8akpxmOqwWK//aOg2aNRiiX5we1H8QK8QNT0MoRf7B9bh59BHL6aOJ/jCeiYXb1jjWGQCGO9Vh3lzJWw2V9f2CvnUaZfeJOCzLgVPqtrI9E1LoPLiVT0Izx9DZ+aINrBxhNfndz5UZ4VQPHF8DDe4=
notifications:
slack: sdsmdg:hvFSzqFNHm3t6NDR2H2Twiio
================================================
FILE: CHANGELOG.md
================================================
# Trianglify Releases
## Latest
* [Version 1.0.0](https://bintray.com/suyashmahar/trianglify/trianglify/1.0.0)
| [Google Play](http://bit.ly/trianglifyDemo)
**First stable release of Trianglify**
* Updated documents so that Trianglify can be seamlessly integrated anywhere
* Fixed bugs in demo app
## Previous
* [Version 0.9 beta](https://bintray.com/suyashmahar/trianglify/trianglify/0.9-beta)
| [demo apk](https://drive.google.com/open?id=0Bz_2jvdEtUlrWEpxQ2Y2RnJGc1U)
* Added custom palette demonstration to demo app
* Added method `fillViewCompletely` to check if view is incompletely filled
* Fixes many bugs - [#23](https://github.com/sdsmdg/trianglify/issues/23), [#33](https://github.com/sdsmdg/trianglify/issues/33), [#34](https://github.com/sdsmdg/trianglify/issues/34), [#35](https://github.com/sdsmdg/trianglify/issues/35) & [#36](https://github.com/sdsmdg/trianglify/issues/36)
* [Version 0.8 beta](https://bintray.com/suyashmahar/trianglify/trianglify/0.8-beta)
| [demo apk](https://www.dropbox.com/s/cn85g497nkwmx14/trianglify-release-0.8-beta.apk?dl=0)
* Generation of triangulation on worker thread to prevent UI freezing [#20](https://github.com/sdsmdg/trianglify/issues/20)
* Correct coloring of view, color now drawn matches its name [#18](https://github.com/sdsmdg/trianglify/issues/18)
* Support for custom palette ([usage](#26-using-custom-palettes)) [#17](https://github.com/sdsmdg/trianglify/issues/17)
* [Version 0.7 beta](https://bintray.com/suyashmahar/trianglify/trianglify/0.7-beta)
[Google Play](https://suyashmahar.me/404)
* Added library to jCenter | [Link](https://bintray.com/suyashmahar/trianglify/trianglify/)
================================================
FILE: CONTRIBUTING.md
================================================
Contributing to Trianglify
==========================
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
If you'd like to report a bug or join in the development
of Trianglify, then here are some notes on how to do that.
## Contents
* [Reporting bugs and opening issues](#reporting-bugs-and-opening-issues)
* [Coding Guidelines](#coding-guidelines)
* [Pull Requests](#pull-requests)
* [MVP architecture](#mvp-architecture)
* [Style Check](#style-check)
* [Git Commit Messages](#git-commit-messages)
* [MDG Chat Room](#mdg-chat-room)
* [Security](#security)
## Reporting bugs and opening issues
If you'd like a report a bug or open an issue then please:
**Check if there is an existing issue.** If there is then please add
any more information that you have, or give it a 👍.
When submitting an issue please describe the issue as clearly as possible, including how to
reproduce the bug, which situations it appears in, what you expected to happen, and what actually happens.
If you can include a screenshot for front end issues that is very helpful.
## Coding Guidelines
### Pull Requests
We love pull requests, so be bold with them! Don't be afraid of going ahead
and changing something, or adding a new feature. We're very happy to work with you
to get your changes merged into Trianglify.
If you've got an idea for a change then please discuss it in the open first,
either by opening an issue, or by joining us in our
[MDG public chat room](https://mdg.sdslabs.co/chat).
If you're looking for something to work on, have a look at the open issues in the repository [here](https://github.com/sdsmdg/trianglify/issues).
> We don't have a set format for Pull requests, but we expect you to list changes, bugs generated and other relevant things in PR message.
### MVP architecture
Trianglify is built keeping [MVP (model-view-presenter)](https://en.wikipedia.org/wiki/Model–view–presenter) architecture in mind, so any changes that are proposed to Trianglfiy should follow MVP architecture. If you are confused regarding where a method should be, join us at [MDG public chat room](https://mdg.sdslabs.co/chat), we'll be happy to help.
### Style Check
Trianglify uses Sputnik for performing style checks on the codebase, which helps us in maintaining the quality of the code. Sputnik checks for violation upon submission of Pull Requests. If Sputnik reports a violation and you believe that it is not applicable, just comment `N/A` on the sputnik review with the reason of why it is not applicable. **Pull Requests will only be merged once all the violations are resolved**.
### Git Commit Messages
* Use the present tense ("Add feature" not "Added feature")
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
* Limit the first line to 72 characters or less
* Reference issues and pull requests liberally
* When only changing documentation, include `[ci skip]` in the commit description
* Consider starting the commit message with an applicable emoji:
* :art: `:art:` when improving the format/structure of the code
* :racehorse: `:racehorse:` when improving performance
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
* :memo: `:memo:` when writing docs
* :bug: `:bug:` when fixing a bug
* :fire: `:fire:` when removing code or files
* :green_heart: `:green_heart:` when fixing the CI build
* :white_check_mark: `:white_check_mark:` when adding tests
* :lock: `:lock:` when dealing with security
* :arrow_up: `:arrow_up:` when upgrading dependencies
* :arrow_down: `:arrow_down:` when downgrading dependencies
* :shirt: `:shirt:` when removing linter warnings
## MDG Chat Room
If you want to ask any questions in real-time, or get a feel for what's going on
then please drop into our [MDG public chat room](https://mdg.iitr.ac.in/chat).
If no one is online then you can still leave a message that will hopefully get a reply
when we return.
## Security
Please do not publish security vulnerabilities publicly until we've had a chance
to address them. All security related issues/patches should be sent directly to
[mdg@iitr.ac.in](mailto:mdg@iitr.ac.in) where we will attempt to address them quickly. If you're
unsure whether something is a security issue or not, then please be cautious and contact us at [mdg@iitr.ac.in](mailto:mdg@iitr.ac.in) first.
================================================
FILE: DOCUMENTATION.md
================================================
Welcome to the Trianglify documentation! Here's the ultimate guide to using Trianglify in your app.
# Documentation
## Contents
1. [Usages](#1-usages)
1. [Java](#11-java)
2. [XML](#12-xml)
2. [APIs](#2-api-documentation)
1. [Attributes and Methods](#21-attributes-and-methods)
1. [TrianglifyView](#211-trianglifyview)
2. [Palette](#212-palette)
2. [Details of Bleed and Grid Dimensions](#22-details-of-bleed-and-grid-dimensions)
4. [Note on Units of CellSize, Variance, Bleed & Grid Height](#24-note-on-units-of-cellsize-variance-bleed-and-grid-height)
5. [Setting Palette using setPalette](#25-setting-palette-using-setpalette-method)
6. [Using Custom Palettes](#26-using-custom-palettes)
7. [Updating the View](#27-updating-the-view)
8. [Exporting Bitmap](#28-exporting-bitmap)
3. [Performance Analysis](#3-performance-analysis)
## 1. Usages
### 1.1 Java
#### Import Statements
Include following lines along with other import statements at the beginning of your activity's java class:
```java
import com.sdsmdg.kd.trianglify.views.TrianglifyView;
import com.sdsmdg.kd.trianglify.models.Palette;
```
To use trianglify view include the following lines to get an instance of view and set its properties:
```java
trianglifyView = (TrianglifyView) findViewById(R.id.trianglify_main_view);
trianglifyView.setGridWidth(trianglifyView.getWidth())
.setGridHeight(trianglifyView.getHeight())
.setBleedX(50)
.setBleedY(50)
.setCellSize(20)
.setVariance(10)
.setTypeGrid(0)
.setPalette(Palette.getPalette(26))
.setDrawStrokeEnabled(true);
```
### 1.2 XML
```xml
<com.sdsmdg.kd.trianglify.views.TrianglifyView
android:id="@+id/trianglify_main_view"
app:cellSize="20dp"
app:variance="10dp"
app:bleedX="50dp"
app:bleedY="50dp"
app:gridType="rectangle"
app:palette="Spectral"
app:fillStrokes="true"
app:fillTriangle="true" />
```
## 2. API Documentation
### 2.1 Attributes and Methods
#### 2.1.1 TrianglifyView
| Property | Default values | Java method | Attribute | Description |
|-----------------------------|----------------|-------------------------|-----------------|-------------------------------------------------------------------------------------------------------------------------------|
| Grid Height | NA | .setGridHeight(...) | grid_height | Height of the grid to generate |
| Grid Width | NA | .setGridWidth(...) | grid_width | Width of the grid to generate |
| X-axis Bleed | 0 px | .setBleedX(...) | bleed_x | TrianglifyView generates total area having width = gridWidth + 2*bleedX to avoid unfilled triangles at the edges of the view |
| Y-Axis Bleed | 0 px | .setBleedY(...) | bleed_y | TrianglifyView generates total area having height = gridHeight + 2*bleedY to avoid unfilled triangles at the edges of the view |
| Variance | 10 px | .setVariance(...) | variance | Displacement of points from original grid position to create triangles of different sizes |
| Cell Size | 40 px | .setCellSize(...) | cell_size | Size of cells of rectangular grid used to generated vertices of the triangles |
| Grid Type* | 0 | .setTypeGrid(...) | grid_type | Type of grid 0 for Rectangular |
| Fill Triangles with color | true | .setFillTriangle(...) | fill_triangles | Fills the triangle generated with color chosen |
| Draw strokes | false | .setDrawStrokes(...) | draw_strokes | Draws triangle's border with neighboring triangle's color |
| Color Palette | YlGn | .setPalette(...) | palette | Set of existing colors to color triangles |
| Random Coloring | false | .setRandomColoring(...) | random_coloring | If random coloring is on triangles will be colored randomly instead of linear interpolation |
| Fill the View Completely | false | .setFillViewCompletely(...) | fillViewCompletely| If fillViewCompletely is true, then it will throw illegalArgumentsException whenever both `BleedX` and `BleedY` are not greater than `cellSize`. Refer to [Section 2.2](#22-details-of-bleed-and-grid-dimensions)
*Current release contains only one GridType accessible with id `0`
**Other methods**
The following methods are getters for corresponding properties and are not covered in the table above:
* isDrawStrokeEnabled
* isRandomColoringEnabled
* isFillTriangle
* isFillViewCompletely
* getVariance
* getTypeGrid
* getPalette
* getGridWidth
* getGridHeight
* getCellSize
* getBleedX
* getBleedY
The following are additional methods provided for the developer:
**`getViewState`**
This method returns the state of the view. For more information on states of view read **Smart update of view using smartUpdate** in [Section 2.7 Updating the View](#27-updating-the-view).
**`clearView`**
This method clears the triangulation of the view and sets it to `null`.
#### 2.1.2 Palette
| Method | Return Type | Type | Parameters | Description |
|-------------|-------------|-------------|------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|
| Constructor | - | Constructor | int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8 | Takes nine parameters as colors to construct palette |
| Constructor | - | Constructor | int[] colors | Takes nine parameters as an array of colors to construct palette |
| getPalette | Palette | static | int paletteIndex | Returns palette object corresponding to passed value of paletteIndex, palette is constructed from a predefined set of colors. |
| indexOf | int | static | Palette palette | Returns index of palette object in predefined palette, -1 if doesn't exists |
| getColor | int | - | int index | Returns color corresponding to index passed from the set of colors for a palette |
<p>
### 2.2 Details of Bleed and Grid Dimensions
* **Bleed:** Bleed defines the dimensions of extra size that TrianglifyView view generates so that triangles on the edge don't appear to be chopped off. In most of the cases `min{bleedX, bleedY} > cellSize` would ensure that the view is completely filled.
* **Grid Dimensions:** `GridHeight` and `GridWidth` defines the dimensions of the visible area of the view.
Total area generated by TrianglifyView is (`gridHeight` + 2 * `BleedY`) * (`gridWidth` + 2 * `BleedX`) while total area visible is (`gridHeight`) * (`gridWidth`)
Following image demonstrates region covered by `gridHeight`, `gridWidth`, `bleedX` and `bleedY`
<p>
<img src="resources/default_pattern_explained.jpg" data-canonical-src="resources/default_pattern_explained.jpg" width="350" height="350" />
### 2.4 Note on Units of CellSize, Variance, Bleed and Grid Height
Attributes of `CellSize`, `Variance`, `Bleed` and `GridHeight` supplied to TrianglifyView using Java are interpreted as `px`. To convert px to dp or vice-versa define and use following methods:
```java
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
public int pxToDp(int px) {
DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
```
### 2.5 Setting Palette using setPalette method
`TrianglifyView`'s `setPalette` method accepts `Palette` object. Palette can be set using one of the following methods:
* To use one of the predefined palette, for example **Spectral** use `trianglifyView.setPalette(Palette.getPalette(Palette.Spectral))`.
* To use palette referring to its index use `Palette.getPalette(<index>)`.
* To use custom palette refer to section [2.6 Using custom Palettes](#26-using-custom-palettes).
> **Note:** Index used for addressing palette should be less than `Palette.DEFAULT_PALETTE_COUNT`, if index is greater than `DEFAULT_PALETTE_COUNT` `IllegalArgumentException` is thrown.
**Note: Palette enum defines total of 28 named palettes that can be used to generate views without specifying colors.**
### 2.6 Using Custom Palettes
Custom Palettes can be used by creating new palette using one of the following constructor:
```java
Palette customPalette = new Palette(int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8);
```
or
```java
Palette customPalette = new Palette(int colors[]);
```
> Array based constructor will throw `IllegalArgumentException` if size of array is not exactly 9.
### 2.7 Updating the View
`TrianglifyView` should be updated on change of any of the parameter for changes to take effect. `TrianglifyView` can be updated by the following two methods:
**Smart update of view using `smartUpdate`**
`smartUpdate` updates the view smartly by looking at the parameter changes in the view since the last update, and accordingly decides which parts of the view should be updated. More formal description is:
* If only the `drawStroke` or `fillTriangle` values have been changed since the last update, the triangulation is only replotted in accordance to the new paint strokes.
* If the `randomColoring` or `palette` have been changed without any changes in the grid parameters, only the new colors are assigned to the triangulation without regenerating the grid and delaunay triangulation, after which the view is plotted in accordance to the `fillTriangle` and `drawStrokes` parameters.
* If there are changes in the grid parameters, the whole triangulation has to be generated from scratch. The method generates a new grid according to the parameters and fits a delaunay triangulation. This is followed by colorization and plotting of the triangulation onto the view.
**Complete regeneration using `generateAndInvalidate`**
This is used when the triangulation is to be generated from scratch. The method generates a grid according to the parameters and fits a delaunay triangulation. This is followed by colorization and plotting of the triangulation onto the view.
**(Basic) Performance Comparision of the Two Methods**
`smartUpdate` method regenerates the whole triangulation only when the grid parameters have been changed, thereby bypassing the unnecessary regeneration of grid and delaunay triangulation in situations when parameters other than grid parameters have been changed. This leads to a faster rendering of view.
The `generateAndInvalidate` method regenerates the whole triangulation irrespective of which parameters have been changed, carrying out steps that might not be necessary, hence causing hindrance to performance.
### 2.8 Exporting Bitmap
`TrianglifyView` can export Bitmap object of the triangulation plotted, to get a bitmap object use `getBitmap` method of trianglifyView. `getBitmap` returns a mutable bitmap object that is of `ARGB_8888` configuration.
Quality of the bitmap obtained can be set using `setQuality` method of TrianglifyView which accepts one of the three possible parameter `TrianglifyView.DRAWING_CACHE_QUALITY_HIGH`, `TrianglifyView.DRAWING_CACHE_QUALITY_LOW` and `TrianglifyView.DRAWING_CACHE_QUALITY_AUTO`.
## 3. Performance Analysis
Few notes on performance of Trianglify
* Performance takes a serious hit with decrease in cell size. Time complexity of the algorithm to generate triangles from grid of points is Ω(n*log(n)). Decreasing cell size increases n (number of points on the grid).
* Performance of coloring is faster on the use of random coloring rather than gradient.
* On use of smartUpdate, performance of coloring depends on the parameters changed since last triangulation. Check [2.7 Updating the View](#27-updating-the-view) for more details.
================================================
FILE: LICENSE.md
================================================
Copyright 2016-17 SDSMDG
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
<!--
<br>
<br>
<div align="center"><img src="resources/trianglify-logo-with-text-close-fit.png" data-canonical-src="trianglify-logo-180.png" width="154" height="154" /></div>
<br>
<br>
-->
# Trianglify
<!-- [](https://travis-ci.com/sdsmdg/trianglify) -->
[](https://www.android.com)
[](https://android-arsenal.com/api?level=16s)
[](https://opensource.org/licenses/MIT)
[](http://mdg.iitr.ac.in)
<img src="resources/splash.png" data-canonical-src="resources/default_pattern_explained.jpg"/>
<a href='http://bit.ly/trianglifyDemo'><img alt='Get it on Google Play' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png' width="200"/></a>
Trianglify is an Android library that helps creates views with beautiful patterns. Trianglify is based on MVP architecture and licensed under MIT license.
# How to Apply
Include following line in the gradle script of your application to include latest release of Trianglify:
```gradle
compile 'com.sdsmdg.kd:trianglify:1.0.0'
```
# Features
**Cell Size**

**Random Coloring**

# Examples
**Navigation Panes**

**Action Bars**

# Latest Release
* [Version 1.0.0](https://bintray.com/suyashmahar/trianglify/trianglify/1.0.0)
| [Google Play](http://bit.ly/trianglifyDemo)
**First stable release of Trianglify**
* Updated documents so that Trianglify can be seamlessly integrated anywhere
* Fixed bugs in demo app
For more check complete [change log](/CHANGELOG.md).
# Usages and Documentation
For details on usage and documentation of Trianglify, check documentation [here](DOCUMENTATION.md).
# Credits
Trianglify is inspired from qrohlf's work to generate triangle art, [Trianglify](https://github.com/qrohlf/trianglify)
Development of Trianglify wouldn't have been possible without following libraries:
* [Delaunay Triangulator by jdiemke](https://github.com/jdiemke/delaunay-triangulator)
* [Color Picker by QuadFlask](https://github.com/QuadFlask/colorpicker)
# Guidelines for Contributors
If you want to contribute to improve this library, please read [our guidelines](CONTRIBUTING.md).
# License
Trianglify is licensed under `MIT license`. View license [here](LICENSE.md).
================================================
FILE: app/.classpath
================================================
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin"/>
</classpath>
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/.project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>app</name>
<comment>Project app created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>
================================================
FILE: app/.settings/org.eclipse.buildship.core.prefs
================================================
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=..
eclipse.preferences.version=1
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.sdsmdg.kd.trianglifyexample"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
//----Testing frameworks
compile project(':trianglify')
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.github.QuadFlask:colorpicker:0.0.13'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.11.0'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /root/Android/Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: app/src/androidTest/java/com/sdsmdg/kd/trianglifyexample/ExampleInstrumentedTest.java
================================================
package com.sdsmdg.kd.trianglifyexample;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.sdsmdg.kd.trianglifyexample", appContext.getPackageName());
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sdsmdg.kd.trianglifyexample">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AboutActivity" />
<activity android:name=".CustomPalettePickerActivity"/>
</application>
</manifest>
================================================
FILE: app/src/main/java/com/sdsmdg/kd/trianglifyexample/AboutActivity.java
================================================
package com.sdsmdg.kd.trianglifyexample;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.SpannableString;
import android.text.style.UnderlineSpan;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class AboutActivity extends AppCompatActivity {
private static final String TAG = "AboutActivity";
ImageView githubLinkBtn, reviewLinkBtn, shareLink, backBtn;
TextView fragTitle, openSourceLicense, versiontTextView;
View bottomMarginLayout;
PackageInfo pInfo;
String versionName;
int versionCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
// To add underline effect in open source license textView
SpannableString content = new SpannableString("view license");
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
// Gets version and build number from package manager
try {
pInfo = this.getPackageManager().getPackageInfo(this.getPackageName(), 0);
versionName = pInfo.versionName;
versionCode = pInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(getString(R.string.about_activity_title));
}
try {
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
} catch (java.lang.NullPointerException e) {
Log.e(TAG, "Null pointer exception in generating back action button");
}
versiontTextView = this.findViewById(R.id.about_version_text);
openSourceLicense = this.findViewById(R.id.about_license_text);
openSourceLicense.setText(content);
githubLinkBtn = this.findViewById(R.id.about_github_link);
reviewLinkBtn = this.findViewById(R.id.about_rate_link);
shareLink = this.findViewById(R.id.about_share_link);
versiontTextView.setText(getString(R.string.about_activity_version) + versionName);
openSourceLicense.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
displayOpenSourceLicenses();
}
});
githubLinkBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("https://github.com/sdsmdg/trianglify");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
reviewLinkBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("market://details?id=" + v.getContext().getPackageName());
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY |
Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
}
try {
startActivity(goToMarket);
} catch (ActivityNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("http://play.google.com/store/apps/details?id=" + v.getContext().getPackageName())));
}
}
});
//TODO: Update link when app releases to marketplace
shareLink.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.share_application_text) +
" " + getResources().getString(R.string.trianglify_store_short_link));
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
});
}
public void displayOpenSourceLicenses() {
final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle(this.getApplicationInfo().name);
alertDialog.setMessage(getResources().getString(R.string.license_text));
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "view license", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(getResources().getString(R.string.license_link))));
}
});
alertDialog.show();
}
// Sets action for Action Bar Items
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
================================================
FILE: app/src/main/java/com/sdsmdg/kd/trianglifyexample/CustomPalettePickerActivity.java
================================================
package com.sdsmdg.kd.trianglifyexample;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import com.flask.colorpicker.ColorPickerView;
import com.flask.colorpicker.OnColorSelectedListener;
import com.flask.colorpicker.builder.ColorPickerClickListener;
import com.flask.colorpicker.builder.ColorPickerDialogBuilder;
import com.sdsmdg.kd.trianglify.models.Palette;
import com.sdsmdg.kd.trianglify.views.TrianglifyView;
public class CustomPalettePickerActivity extends AppCompatActivity {
private static final String TAG = "CustomPalleteActivity";
private Palette palette;
private TrianglifyView trianglifyView;
private Context context;
private ImageView[] imageViews = new ImageView[9];
private int[] colors = {Color.BLACK, Color.BLUE, Color.BLACK, Color.CYAN, Color.DKGRAY, Color.GREEN, Color.RED, Color.MAGENTA, Color.LTGRAY};
public static final String CUSTOM_PALETTE_COLOR_ARRAY = "Custom Palette Color Array";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
setContentView(R.layout.activity_custom_palette_picker);
try {
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
} catch (java.lang.NullPointerException e) {
Log.e(TAG, "Null pointer exception in generating back action button");
}
try {
if (actionBar != null) {
actionBar.setTitle("Custom Palette Picker");
}
} catch (java.lang.NullPointerException e) {
Log.e(TAG, "Null pointer exception on setting About activity title");
}
colors = getIntent().getIntArrayExtra(getResources().getString(R.string.palette_color_array));
context = this;
trianglifyView = findViewById(R.id.trianglify_custom_palette_view);
trianglifyView.setPalette(new Palette(colors));
trianglifyView.smartUpdate();
for (int i = 0; i < imageViews.length; i++) {
String imageViewNumber = "custom_palette_c" + String.valueOf(i);
int resID = getResources().getIdentifier(imageViewNumber, "id", getPackageName());
imageViews[i] = findViewById(resID);
imageViews[i].setBackgroundColor(colors[i] + 0xff000000);
final int finalI = i;
imageViews[i].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final AlertDialog dialog = ColorPickerDialogBuilder
.with(context)
.initialColor(colors[finalI] + 0xff000000)
.setTitle("Choose Color")
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
.density(9)
.showColorEdit(true)
.lightnessSliderOnly()
.setColorEditTextColor(0xff000000)
.showColorPreview(true)
.setOnColorSelectedListener(new OnColorSelectedListener() {
@Override
public void onColorSelected(int color) {
}
})
.setPositiveButton("ok", new ColorPickerClickListener() {
@Override
public void onClick(DialogInterface dialog, int color, Integer[] allColors) {
imageViews[finalI].setBackgroundColor(color);
colors[finalI] = color - 0xff000000;
palette = new Palette(colors);
trianglifyView.setPalette(palette);
trianglifyView.smartUpdate();
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.build();
dialog.show();
}
});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_custom_palette_picker, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
case R.id.custom_palette_ok:
Intent intent = new Intent();
intent.putExtra(CUSTOM_PALETTE_COLOR_ARRAY, colors);
setResult(RESULT_OK, intent);
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
================================================
FILE: app/src/main/java/com/sdsmdg/kd/trianglifyexample/MainActivity.java
================================================
package com.sdsmdg.kd.trianglifyexample;
import android.Manifest;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.SeekBar;
import android.widget.Toast;
import com.sdsmdg.kd.trianglify.models.Palette;
import com.sdsmdg.kd.trianglify.views.TrianglifyView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
public TrianglifyView trianglifyView;
private SeekBar varianceSeekBar;
private SeekBar cellSizeSeekBar;
private SeekBar paletteSeekBar;
private CheckBox strokeCheckBox;
private CheckBox fillCheckBox;
private CheckBox randomColoringCheckbox;
private CheckBox customPaletteCheckbox;
private Palette customPalette;
private final int PERMISSION_CODE = 69;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
trianglifyView = findViewById(R.id.trianglify_main_view);
trianglifyView.setBitmapQuality(TrianglifyView.DRAWING_CACHE_QUALITY_HIGH);
customPalette = trianglifyView.getPalette();
varianceSeekBar = findViewById(R.id.variance_seekbar);
varianceSeekBar.setMax(100);
varianceSeekBar.setProgress(trianglifyView.getVariance());
varianceSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
trianglifyView.setVariance(progress + 1);
trianglifyView.smartUpdate();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
cellSizeSeekBar = findViewById(R.id.cell_size_seekbar);
int maxCellSize = 150;
cellSizeSeekBar.setMax(maxCellSize);
cellSizeSeekBar.setProgress(trianglifyView.getCellSize() - 100);
cellSizeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
trianglifyView.setCellSize(progress + 100);
trianglifyView.smartUpdate();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
paletteSeekBar = findViewById(R.id.palette_seekbar);
paletteSeekBar.setMax(Palette.DEFAULT_PALETTE_COUNT - 1);
paletteSeekBar.setProgress(Palette.indexOf(trianglifyView.getPalette()));
paletteSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
trianglifyView.setPalette(Palette.getPalette(progress));
customPaletteCheckbox.setChecked(false);
trianglifyView.smartUpdate();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
strokeCheckBox = findViewById(R.id.draw_stroke_checkbox);
strokeCheckBox.setChecked(trianglifyView.isDrawStrokeEnabled());
strokeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked || trianglifyView.isFillTriangle()) {
trianglifyView.setDrawStrokeEnabled(isChecked);
strokeCheckBox.setChecked(isChecked);
trianglifyView.smartUpdate();
} else {
strokeCheckBox.setChecked(!isChecked);
showColoringError();
}
}
});
fillCheckBox = findViewById(R.id.draw_fill_checkbox);
fillCheckBox.setChecked(trianglifyView.isFillTriangle());
fillCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked || trianglifyView.isDrawStrokeEnabled()) {
trianglifyView.setFillTriangle(isChecked);
fillCheckBox.setChecked(isChecked);
trianglifyView.smartUpdate();
} else {
fillCheckBox.setChecked(!isChecked);
showColoringError();
}
}
});
randomColoringCheckbox = findViewById(R.id.random_coloring_checkbox);
randomColoringCheckbox.setChecked(trianglifyView.isRandomColoringEnabled());
randomColoringCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
trianglifyView.setRandomColoring(isChecked);
trianglifyView.smartUpdate();
}
});
customPaletteCheckbox = findViewById(R.id.custom_palette_checkbox);
customPaletteCheckbox.setChecked(false);
customPaletteCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
trianglifyView.setPalette(customPalette);
trianglifyView.smartUpdate();
} else {
trianglifyView.setPalette(Palette.getPalette(paletteSeekBar.getProgress()));
trianglifyView.smartUpdate();
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
public void updateUIElements(TrianglifyView trianglifyView) {
fillCheckBox.setChecked(trianglifyView.isFillTriangle());
strokeCheckBox.setChecked(trianglifyView.isDrawStrokeEnabled());
randomColoringCheckbox.setChecked(trianglifyView.isRandomColoringEnabled());
varianceSeekBar.setProgress(trianglifyView.getVariance());
cellSizeSeekBar.setProgress(trianglifyView.getCellSize());
paletteSeekBar.setProgress(Palette.indexOf(trianglifyView.getPalette()));
}
public void randomizeTrianglifyParameters(TrianglifyView trianglifyView) {
Random rnd = new Random(System.currentTimeMillis());
trianglifyView.setCellSize(dpToPx(rnd.nextInt(10) + 35))
.setPalette(Palette.getPalette(rnd.nextInt(28)))
.setRandomColoring(rnd.nextInt(2) == 0)
.setFillTriangle(rnd.nextInt(2) == 0)
.setDrawStrokeEnabled(rnd.nextInt(2) == 0)
.setVariance(rnd.nextInt(60));
if (!trianglifyView.isFillTriangle() && !trianglifyView.isDrawStrokeEnabled()) {
trianglifyView.setDrawStrokeEnabled(true);
trianglifyView.setFillTriangle(true);
}
updateUIElements(trianglifyView);
}
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
public int pxToDp(int px) {
DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
// Click handlers for action bar menu items
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save:
try {
exportImage();
} catch (IOException e) {
Toast.makeText(MainActivity.this,
"Storage access failed!",Toast.LENGTH_LONG).show();
}
break;
case R.id.action_about:
Intent aboutActivityIntent = new Intent(this, AboutActivity.class);
startActivity(aboutActivityIntent);
break;
case R.id.action_refresh:
randomizeTrianglifyParameters(trianglifyView);
trianglifyView.generateAndInvalidate();
break;
case R.id.custom_palette_picker:
Intent customPalettePickerIntent = new Intent(this, CustomPalettePickerActivity.class);
customPalettePickerIntent.putExtra(getResources().getString(R.string.palette_color_array),
trianglifyView.getPalette().getColors());
startActivityForResult(customPalettePickerIntent, 1);
customPaletteCheckbox.setChecked(true);
break;
case R.id.action_set_wall:
setWallpaper(MainActivity.this.trianglifyView);
break;
default:
break;
}
return true;
}
public void showColoringError() {
Toast.makeText(this, "View should at least be set to draw strokes or fill triangles or both.",
Toast.LENGTH_LONG).show();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK) {
customPalette = new Palette(data.getIntArrayExtra(CustomPalettePickerActivity.CUSTOM_PALETTE_COLOR_ARRAY));
if (customPaletteCheckbox.isChecked()) {
trianglifyView.setPalette(customPalette);
trianglifyView.smartUpdate();
}
}
}
private void exportImage() throws IOException {
// Checks if permission is required for android version > 6
boolean permissionStatus = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
if (permissionStatus) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_CODE);
} else {
Bitmap bitmap = trianglifyView.getBitmap();
if (bitmap != null)
addImageToGallery(bitmap, this);
else
Toast.makeText(this, "Unable to generate image, please try again",
Toast.LENGTH_LONG).show();
}
}
public static void addImageToGallery(Bitmap bitmap, Context context) throws IOException {
String timeStamp = "IMG_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".png";
OutputStream os = new FileOutputStream(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + timeStamp);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
Toast.makeText(context, "Saved!", Toast.LENGTH_SHORT).show();
}
// Sets bitmap from trianglify view as wallpaper of device
public void setWallpaper(final TrianglifyView view) {
AlertDialog.Builder alertDgBuilder = new AlertDialog.Builder(this);
alertDgBuilder.setMessage(getString(R.string.wall_alert_dg_text));
alertDgBuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
WallpaperManager trianglifyWallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
trianglifyWallpaperManager.setBitmap(view.getBitmap());
Toast.makeText(MainActivity.this, "Wallpaper set successfuly",
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(MainActivity.this, "Something went wrong, please try again.",
Toast.LENGTH_LONG).show();
}
}
});
alertDgBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Perform inbuilt functions
}
});
alertDgBuilder.create().show();
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_CODE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
exportImage();
} catch (IOException e) {
Toast.makeText(MainActivity.this,
"Storage access failed!",Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "Storage access failed, check permission",
Toast.LENGTH_LONG).show();
}
break;
}
}
}
================================================
FILE: app/src/main/res/drawable/color_picked_imageview_border.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="2dp" android:color="#bdbdbd"/>
<padding android:left="1dp" android:top="1dp" android:right="1dp" android:bottom="1dp"/>
</shape>
================================================
FILE: app/src/main/res/drawable/ok_icon.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:width="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#fff" android:pathData="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
</vector>
================================================
FILE: app/src/main/res/drawable/palette_icon.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:width="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#efeaeaea" android:pathData="M17.5,12A1.5,1.5 0 0,1 16,10.5A1.5,1.5 0 0,1 17.5,9A1.5,1.5 0 0,1 19,10.5A1.5,1.5 0 0,1 17.5,12M14.5,8A1.5,1.5 0 0,1 13,6.5A1.5,1.5 0 0,1 14.5,5A1.5,1.5 0 0,1 16,6.5A1.5,1.5 0 0,1 14.5,8M9.5,8A1.5,1.5 0 0,1 8,6.5A1.5,1.5 0 0,1 9.5,5A1.5,1.5 0 0,1 11,6.5A1.5,1.5 0 0,1 9.5,8M6.5,12A1.5,1.5 0 0,1 5,10.5A1.5,1.5 0 0,1 6.5,9A1.5,1.5 0 0,1 8,10.5A1.5,1.5 0 0,1 6.5,12M12,3A9,9 0 0,0 3,12A9,9 0 0,0 12,21A1.5,1.5 0 0,0 13.5,19.5C13.5,19.11 13.35,18.76 13.11,18.5C12.88,18.23 12.73,17.88 12.73,17.5A1.5,1.5 0 0,1 14.23,16H16A5,5 0 0,0 21,11C21,6.58 16.97,3 12,3Z" />
</vector>
================================================
FILE: app/src/main/res/layout/activity_about.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fancy="http://schemas.android.com/apk/res-auto"
android:theme="@android:style/Theme.Holo.NoActionBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:clipToPadding="false">
<com.sdsmdg.kd.trianglify.views.TrianglifyView
android:id="@+id/trianglify_main_view"
android:layout_centerHorizontal="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cellSize="50dp"
app:variance="5dp"
app:bleedX="50dp"
app:bleedY="50dp"
app:gridType="rectangle"
app:palette="PuBu"
app:fillStrokes="true"
app:fillTriangle="true"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="32dp"
android:layout_alignParentTop="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/about_mdg_logo"
android:layout_marginTop="32dp"
android:layout_width="175dp"
android:layout_height="175dp"
android:layout_centerHorizontal="true"
android:src="@drawable/web_hi_res_512" />
<TextView
android:id="@+id/about_trianglify_title"
android:layout_below="@id/about_mdg_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:text="Trianglify"
android:textSize="18sp"
android:textAlignment="center"
android:textColor="#FFF"/>
<TextView
android:id="@+id/about_version_text"
android:layout_below="@id/about_trianglify_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp"
android:text="Version 1.1.0"
android:textSize="11sp"
android:textAlignment="center"
android:textColor="#FFF"/>
<TextView
android:id="@+id/about_brought_by"
android:layout_below="@id/about_version_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp"
android:layout_marginTop="64dp"
android:text="developed by"
android:textSize="12sp"
android:textStyle="italic"
android:textAlignment="center"
android:textColor="#FFF"/>
<ImageView
android:id="@+id/about_trianglify_logo"
android:layout_below="@id/about_brought_by"
android:layout_width="140dp"
android:layout_height="70dp"
android:layout_centerHorizontal="true"
android:src="@drawable/logo_mdg"
android:scaleType="centerInside"
/>
<TextView
android:id="@+id/about_text"
android:layout_below="@id/about_trianglify_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="32dp"
android:layout_marginRight="32dp"
android:layout_marginTop="8dp"
android:text="@string/mdg_description"
android:textAlignment="center"
android:textColor="#FFF"
android:textSize="12dp" />
<ImageView
android:id="@+id/about_github_link"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_github"
android:layout_below="@+id/about_text"
android:layout_marginBottom="12dp"
android:layout_marginRight="4dp"
android:layout_toLeftOf="@+id/about_rate_link"
android:padding="2dp"
/>
<ImageView
android:id="@+id/about_rate_link"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_rate_play"
android:layout_below="@+id/about_text"
android:layout_marginBottom="12dp"
android:layout_centerHorizontal="true"
android:padding="8dp"
/>
<ImageView
android:id="@+id/about_share_link"
android:layout_toRightOf="@id/about_rate_link"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="4dp"
android:src="@drawable/ic_share_app"
android:layout_below="@+id/about_text"
android:layout_marginBottom="12dp"
android:padding="10dp"
/>
<TextView
android:id="@+id/about_license_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:layout_marginBottom="32dp"
android:text="View license"
android:textAlignment="center"
android:textColor="@color/colorAccent"
android:autoLink="web"
android:clickable="true"
android:layout_below="@+id/about_share_link"
android:textSize="14sp"
/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/activity_custom_palette_picker.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_custom_palette_picker"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sdsmdg.kd.trianglifyexample.CustomPalettePickerActivity">
<com.sdsmdg.kd.trianglify.views.TrianglifyView
android:id="@+id/trianglify_custom_palette_view"
android:layout_centerHorizontal="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cellSize="30dp"
app:variance="5dp"
app:bleedX="50dp"
app:bleedY="50dp"
app:palette="RdBu"
app:gridType="rectangle"
app:fillStrokes="true"
app:fillTriangle="true"
app:randomColoring="false"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?android:attr/actionBarSize">
<ImageView
android:id="@+id/custom_palette_c0"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_marginLeft = "16dp"
android:layout_marginTop="32dp"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c1"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_margin ="32dp"
android:layout_centerHorizontal="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c2"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_marginRight = "16dp"
android:layout_marginTop="32dp"
android:layout_alignParentRight="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c3"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_margin="16dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c4"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_marginRight="16dp"
android:layout_marginBottom="32dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c5"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_marginBottom="32dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c6"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_marginLeft="16dp"
android:layout_marginBottom="32dp"
android:layout_alignParentBottom="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c7"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_margin="16dp"
android:layout_centerVertical="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
<ImageView
android:id="@+id/custom_palette_c8"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#ffffff"
android:layout_centerInParent="true"
android:clickable="true"
android:src="@drawable/color_picked_imageview_border"
/>
</RelativeLayout>
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D3D3D3"
tools:context="com.sdsmdg.kd.trianglifyexample.MainActivity">
<com.sdsmdg.kd.trianglify.views.TrianglifyView
android:id="@+id/trianglify_main_view"
android:layout_centerHorizontal="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cellSize="30dp"
app:variance="5dp"
app:bleedX="75dp"
app:bleedY="75dp"
app:gridType="rectangle"
app:palette="RdBu"
app:fillStrokes="true"
app:fillTriangle="true"
app:randomColoring="false"
/>
<RelativeLayout
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="10dp"
android:background="#84FFFFFF"
android:layout_margin="8dp"
android:padding="16dp">
<TextView
android:id="@+id/variance_textview"
android:layout_width="72dp"
android:text="Variance: "
android:textColor="#212121"
android:layout_margin="4dp"
android:layout_height="wrap_content" />
<SeekBar
android:id="@+id/variance_seekbar"
android:layout_alignParentRight="true"
android:layout_toRightOf="@id/variance_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
/>
<TextView
android:id="@+id/cell_size_textview"
android:layout_below="@id/variance_textview"
android:layout_width="72dp"
android:textColor="#212121"
android:layout_margin="4dp"
android:text="Cell Size: "
android:layout_height="wrap_content" />
<SeekBar
android:id="@+id/cell_size_seekbar"
android:layout_toRightOf="@id/cell_size_textview"
android:layout_below="@+id/variance_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
/>
<TextView
android:id="@+id/palette_textview"
android:layout_below="@id/cell_size_textview"
android:layout_width="72dp"
android:textColor="#212121"
android:layout_margin="4dp"
android:text="Palette: "
android:layout_height="wrap_content" />
<SeekBar
android:id="@+id/palette_seekbar"
android:layout_toRightOf="@id/palette_textview"
android:layout_below="@+id/cell_size_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/palette_textview"
android:layout_marginTop="4dp"
>
<View
android:id="@+id/layout_middle_point"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerInParent="true"
/>
<CheckBox
android:id="@+id/random_coloring_checkbox"
android:layout_toRightOf="@id/layout_middle_point"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Random Coloring"
android:checked="false"
/>
<CheckBox
android:id="@+id/custom_palette_checkbox"
android:layout_toLeftOf="@id/layout_middle_point"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Custom Palette"
/>
<CheckBox
android:id="@+id/draw_stroke_checkbox"
android:layout_below="@id/custom_palette_checkbox"
android:layout_toLeftOf="@id/layout_middle_point"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Draw Strokes"
/>
<CheckBox
android:id="@+id/draw_fill_checkbox"
android:layout_below="@id/random_coloring_checkbox"
android:layout_toRightOf="@id/layout_middle_point"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fill Triangles"
/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
================================================
FILE: app/src/main/res/menu/menu.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_refresh"
android:orderInCategory="100"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_refresh"
android:title="@string/menu_refresh"/>
<item
android:id="@+id/action_set_wall"
android:orderInCategory="100"
android:icon="@drawable/ic_about_icon"
android:title="@string/menu_set_as_wallpaper"/>
<item
android:id="@+id/action_save"
android:orderInCategory="100"
android:icon="@drawable/ic_action_save"
android:title="@string/menu_save"/>
<item
android:id="@+id/custom_palette_picker"
android:orderInCategory="100"
app:showAsAction="ifRoom"
android:icon="@drawable/palette_icon"
android:title="@string/menu_custom_color"/>
<item
android:id="@+id/action_about"
android:orderInCategory="100"
android:icon="@drawable/ic_about_icon"
android:title="@string/menu_about"/>
</menu>
================================================
FILE: app/src/main/res/menu/menu_custom_palette_picker.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/custom_palette_ok"
android:orderInCategory="100"
app:showAsAction="always"
android:icon="@drawable/ok_icon"
android:title="OK"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</menu>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#009688</color>
<color name="colorPrimaryDark">#00796B</color>
<color name="colorAccent">#3F51B5</color>
</resources>
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">Trianglify Demo</string>
<!-- About Fragment strings -->
<string name="mdg_description">A place where \nIdeas meet reality!</string>
<string name="share_application_text">Check out trianglify a library to generate beautiful view for Android. Link: </string>
<string name="trianglify_store_short_link">http://bit.ly/trianglifyDemo</string>
<string name="license_text">Trianglify library and all related material are distributed under \'MIT license\' a copy of which can be obtained from link provided.</string>
<string name="license_link">https://github.com/sdsmdg/trianglify/blob/develop/LICENSE.md</string>
<!-- Main Activity overflow menu strings -->
<string name="menu_save">Save</string>
<string name="menu_refresh">Refresh</string>
<string name="menu_custom_color">Customize colors</string>
<string name="menu_about">About</string>
<string name="menu_set_as_wallpaper">Set as wallpaper</string>
<!-- Main Activity strings -->
<string name="wall_alert_dg_text">Set current art as wallpaper?</string>
<string name="palette_color_array">Palette Color Array</string>
<!-- About Activity strings -->
<string name="about_activity_title">About</string>
<string name="about_activity_version">Version</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
</style>
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
</resources>
================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: app/src/test/java/com/sdsmdg/kd/trianglifyexample/ExampleUnitTest.java
================================================
package com.sdsmdg.kd.trianglifyexample;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
google()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
subprojects {
tasks.withType(Javadoc).all { enabled = false }
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Feb 07 13:07:53 IST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: resources/tables/palette-methods-table.tgn
================================================
{"rows_views":[[{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"middle","padding":{"top":10,"right":5,"bottom":10,"left":5}}}]],"model":{"rows":[[{"value":"Method","cspan":1,"rspan":1},{"value":"Return Type\n","cspan":1,"rspan":1},{"value":"Type\n","cspan":1,"rspan":1},{"value":"Parameters","cspan":1,"rspan":1},{"value":"Description","cspan":1,"rspan":1}],[{"value":"Constructor","cspan":1,"rspan":1},{"value":"-","cspan":1,"rspan":1},{"value":"Constructor","cspan":1,"rspan":1},{"value":"int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8","cspan":1,"rspan":1},{"value":"Takes eight parameters as colors to construct palette\n","cspan":1,"rspan":1}],[{"value":"Constructor","cspan":1,"rspan":1},{"value":"-","cspan":1,"rspan":1},{"value":"Constructor","cspan":1,"rspan":1},{"value":"int[] colors","cspan":1,"rspan":1},{"value":"Takes eight parameters as an array of colors to construct palette","cspan":1,"rspan":1}],[{"value":"getPalette","cspan":1,"rspan":1},{"value":"Palette","cspan":1,"rspan":1},{"value":"static","cspan":1,"rspan":1},{"value":"int paletteIndex\n","cspan":1,"rspan":1},{"value":"Returns palette object corresponding to supplied value of paletteIndex, palette is constructed from a predefined set of colors.","cspan":1,"rspan":1}],[{"value":"indexOf","cspan":1,"rspan":1},{"value":"int","cspan":1,"rspan":1},{"value":"static","cspan":1,"rspan":1},{"value":"Palette palette","cspan":1,"rspan":1},{"value":"Returns index of palette object in predefined palette, -1 if doesn't exists\n","cspan":1,"rspan":1}],[{"value":"","cspan":1,"rspan":1},{"value":"int","cspan":1,"rspan":1},{"value":"-\n","cspan":1,"rspan":1},{"value":"int index","cspan":1,"rspan":1},{"value":"Returns color corresponding to index passed from the set of color for a palette","cspan":1,"rspan":1}]]},"theme":null,"fixed_layout":false}
================================================
FILE: resources/tables/trianglify-view-attributes-table.tgn
================================================
{"rows_views":[[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}],[{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}},{"style":{"borders":"lrtb","font_style":{},"text_color":"","bg_color":"","halign":"left","valign":"top","padding":{"top":10,"right":5,"bottom":10,"left":5}}}]],"model":{"rows":[[{"value":"Property","cspan":1,"rspan":1},{"value":"Default values\n","cspan":1,"rspan":1},{"value":"Java method\n","cspan":1,"rspan":1},{"value":"Attribute\n","cspan":1,"rspan":1},{"value":"Description","cspan":1,"rspan":1}],[{"value":"Grid Height\n","cspan":1,"rspan":1},{"value":"NA","cspan":1,"rspan":1},{"value":".setGridHeight(...)","cspan":1,"rspan":1},{"value":"grid_height","cspan":1,"rspan":1},{"value":"Height of the grid to generate","cspan":1,"rspan":1}],[{"value":"Grid Width\n","cspan":1,"rspan":1},{"value":"NA","cspan":1,"rspan":1},{"value":".setGridWidth(...)","cspan":1,"rspan":1},{"value":"grid_width\n","cspan":1,"rspan":1},{"value":"Width of the grid to generate","cspan":1,"rspan":1}],[{"value":"X-axis Bleed\n","cspan":1,"rspan":1},{"value":"0","cspan":1,"rspan":1},{"value":".setBleedX(...)","cspan":1,"rspan":1},{"value":"bleed_x","cspan":1,"rspan":1},{"value":"TrianglifyView generates total area having width = gridWidth + 2*bleedX to avoid unfilled triangles at the edges of the view","cspan":1,"rspan":1}],[{"value":"Y-Axis Bleed\n","cspan":1,"rspan":1},{"value":"0 \n","cspan":1,"rspan":1},{"value":".setBleedY(...)","cspan":1,"rspan":1},{"value":"bleed_y","cspan":1,"rspan":1},{"value":"TrianglifyView generates total area having height = gridWidth + 2*bleedY to avoid unfilled triangles at the edges of the view","cspan":1,"rspan":1}],[{"value":"Variance","cspan":1,"rspan":1},{"value":"10 px\n","cspan":1,"rspan":1},{"value":".setVariance(...)","cspan":1,"rspan":1},{"value":"variance\n","cspan":1,"rspan":1},{"value":"Displacement of points from original grid position to create triangles of different sizes","cspan":1,"rspan":1}],[{"value":"Cell Size\n","cspan":1,"rspan":1},{"value":"40 px","cspan":1,"rspan":1},{"value":".setCellSize(...)","cspan":1,"rspan":1},{"value":"cell_size\n","cspan":1,"rspan":1},{"value":"Size of cells of rectangular grid used to generated vertices of the triangles","cspan":1,"rspan":1}],[{"value":"Grid Type*\n","cspan":1,"rspan":1},{"value":"0","cspan":1,"rspan":1},{"value":".setGridType(...)","cspan":1,"rspan":1},{"value":"grid_type\n","cspan":1,"rspan":1},{"value":"Type of grid 0 for Rectangular","cspan":1,"rspan":1}],[{"value":"Fill Triangles with color**\n","cspan":1,"rspan":1},{"value":"true\n","cspan":1,"rspan":1},{"value":".setFillTriangle(...)","cspan":1,"rspan":1},{"value":"fill_triangles","cspan":1,"rspan":1},{"value":"Fills the triangle generated with color chosen","cspan":1,"rspan":1}],[{"value":"Draw strokes\n","cspan":1,"rspan":1},{"value":"false","cspan":1,"rspan":1},{"value":".setDrawStrokes(...)","cspan":1,"rspan":1},{"value":"draw_strokes","cspan":1,"rspan":1},{"value":"Draws triangle's border with neighboring triangle's color","cspan":1,"rspan":1}],[{"value":"Color Palette\n","cspan":1,"rspan":1},{"value":"YlGn","cspan":1,"rspan":1},{"value":".setPalette(...)","cspan":1,"rspan":1},{"value":"palette","cspan":1,"rspan":1},{"value":"Set of existing colors to color triangles","cspan":1,"rspan":1}],[{"value":"Random Coloring\n","cspan":1,"rspan":1},{"value":"false","cspan":1,"rspan":1},{"value":".setRandomColoring(...)","cspan":1,"rspan":1},{"value":"random_coloring","cspan":1,"rspan":1},{"value":"If random coloring is on triangles will be colored randomly instead of linear interpolation","cspan":1,"rspan":1}],[{"value":"","cspan":1,"rspan":1},{"value":"","cspan":1,"rspan":1},{"value":"","cspan":1,"rspan":1},{"value":"","cspan":1,"rspan":1},{"value":"","cspan":1,"rspan":1}]]},"theme":null,"fixed_layout":false}
================================================
FILE: settings.gradle
================================================
include ':app', ':trianglify'
================================================
FILE: trianglify/.classpath
================================================
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin"/>
</classpath>
================================================
FILE: trianglify/.gitignore
================================================
/build
================================================
FILE: trianglify/.project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>trianglify-trianglify</name>
<comment>Project trianglify-trianglify created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>
================================================
FILE: trianglify/.settings/org.eclipse.buildship.core.prefs
================================================
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=..
eclipse.preferences.version=1
================================================
FILE: trianglify/build.gradle
================================================
apply plugin: 'com.android.library'
ext {
bintrayRepo = 'trianglify'
bintrayName = 'trianglify' // Has to be same as library module name
PUBLISH_GROUP_ID = 'com.sdsmdg.kd'
PUBLISH_ARTIFACT_ID = 'trianglify'
PUBLISH_VERSION = '1.0.0'
publishedGroupId = 'com.sdsmdg.kd'
libraryName = 'trianglify'
artifact = 'trianglify' // Has to be same as library module name
siteUrl = 'https://github.com/sdsmdg/trianglify'
gitUrl = 'https://github.com/sdsmdg/trianglify.git'
githubRepository= 'sdsmdg/trianglify'
libraryVersion = '1.0.0'
libraryDescription = 'Generate beautiful view for android.'
developerId = 'sdsmdg'
developerName = 'SDS, MDG'
developerEmail = 'sdsmdg@gmail.com'
licenseName = 'MIT License'
licenseUrl = 'https://github.com/sdsmdg/trianglify/blob/develop/LICENSE.md'
allLicenses = ["MIT"]
}
android {
compileSdkVersion 27
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 16
targetSdkVersion 27
versionCode 0
versionName "1.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:27.0.2'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.13.0'
}
//apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
//apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
================================================
FILE: trianglify/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /root/Android/Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: trianglify/src/androidTest/java/com/sdsmdg/kd/trianglify/ExampleInstrumentedTest.java
================================================
package com.sdsmdg.kd.trianglify;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.sdsmdg.kd.trianglify.test", appContext.getPackageName());
}
}
================================================
FILE: trianglify/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sdsmdg.kd.trianglify">
<application android:label="@string/app_name">
</application>
</manifest>
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Grid.java
================================================
package com.sdsmdg.kd.trianglify.models;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;
import java.util.List;
/**
* Created by shyam on 12-Mar-17.
*/
public class Grid {
private List<Vector2D> gridPoints;
public Grid(List<Vector2D> gridPoints) {
this.gridPoints = gridPoints;
}
public List<Vector2D> getGridPoints() {
return gridPoints;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Palette.java
================================================
package com.sdsmdg.kd.trianglify.models;
/**
* <h1>Palette</h1>
* <b>Description : </b>
* Set of 9 colors that are used to color a triangulation. Palette contains few predefined color sets
* as well as method to perform operations on palette.
*
* @author kriti
* @since 18/3/17.
*/
public class Palette {
public static final int DEFAULT_PALETTE_COUNT = 28;
private static final int YL_GN = 0;
private static final int YL = 1;
private static final int YL_GN_BU = 2;
private static final int GN_BU = 3;
private static final int BU_GN = 4;
private static final int PU_BU_GN = 5;
private static final int PU_BU = 6;
private static final int BU_PU = 7;
private static final int RD_PU = 8;
private static final int PU_RD = 9;
private static final int OR_RD = 10;
private static final int YL_OR_RD = 11;
private static final int YL_OR_BR = 12;
private static final int PURPLES = 13;
private static final int BLUES = 14;
private static final int GREENS = 15;
private static final int ORANGES = 16;
private static final int REDS = 17;
private static final int GREYS = 18;
private static final int PU_OR = 19;
private static final int BR_BL = 20;
private static final int PU_RD_GN = 21;
private static final int PI_YL_GN = 22;
private static final int RD_BU = 23;
private static final int RD_GY = 24;
private static final int RD_YL_BU = 25;
private static final int SPECTRAL = 26;
private static final int RD_YL_GN = 27;
private int[] colors;
public int[] getColors() {
return colors;
}
public void setColors(int[] colors) {
if (colors.length != 9) {
throw new IllegalArgumentException("Colors array length should exactly be 9");
}
this.colors = colors;
}
/**
* Return palette object corresponding to supplied value of paletteIndex, palette is constructed
* from a predefined set of colors
* @param paletteIndex Index of palette to return
* @return Palette object generated from predefined set of colors
*/
public static Palette getPalette(int paletteIndex) {
switch (paletteIndex) {
case YL:
return new Palette(0xffffe0, 0xffffcc, 0xfffacd, 0xffff00, 0xffef00, 0xffd300, 0xf8de7e, 0xffd700, 0xc3b091);
case YL_GN:
return new Palette(0xffffe5, 0xf7fcb9, 0xd9f0a3, 0xaddd8e, 0x78c679, 0x41ab5d, 0x238443, 0x006837, 0x004529);
case YL_GN_BU:
return new Palette(0xffffd9, 0xedf8b1, 0xc7e9b4, 0x7fcdbb, 0x41b6c4, 0x1d91c0, 0x225ea8, 0x253494, 0x081d58);
case GN_BU:
return new Palette(0xf7fcf0, 0xe0f3db, 0xccebc5, 0xa8ddb5, 0x7bccc4, 0x4eb3d3, 0x2b8cbe, 0x0868ac, 0x084081);
case BU_GN:
return new Palette(0xf7fcfd, 0xe5f5f9, 0xccece6, 0x99d8c9, 0x66c2a4, 0x41ae76, 0x238b45, 0x006d2c, 0x00441c);
case PU_BU_GN:
return new Palette(0xfff7fb, 0xece2f0, 0xd0d1e6, 0xa6bddb, 0x67a9cf, 0x3690c0, 0x02818a, 0x016c59, 0x014636);
case PU_BU:
return new Palette(0xfff7fb, 0xece7f2, 0xd0d1e6, 0xa6bddb, 0x74a9cf, 0x3690c0, 0x0570b0, 0x045a8d, 0x023858);
case BU_PU:
return new Palette(0xf7fcfd, 0xe0ecf4, 0xbfd3e6, 0x9ebcda, 0x8c96c6, 0x8c6bb1, 0x88419d, 0x810f7c, 0x4d004b);
case RD_PU:
return new Palette(0xfff7f3, 0xfde0dd, 0xfcc5c0, 0xfa9fb5, 0xf768a1, 0xdd3497, 0xae017e, 0x7a0177, 0x49006a);
case PU_RD:
return new Palette(0xf7f4f9, 0xe7e1ef, 0xd4b9da, 0xc994c7, 0xdf65b0, 0xe7298a, 0xce1256, 0x980043, 0x67001f);
case OR_RD:
return new Palette(0xfff7ec, 0xfee8c8, 0xfdd49e, 0xfdbb84, 0xfc8d59, 0xef6548, 0xd7301f, 0xb30000, 0x7f0000);
case YL_OR_RD:
return new Palette(0xffffcc, 0xffeda0, 0xfed976, 0xfeb24c, 0xfd8d3c, 0xfc4e2a, 0xe31a1c, 0xbd0026, 0x800026);
case YL_OR_BR:
return new Palette(0xffffe5, 0xfff7bc, 0xfee391, 0xfec44f, 0xfe9929, 0xec7014, 0xcc4c02, 0x993404, 0x662506);
case PURPLES:
return new Palette(0xfcfbfd, 0xefedf5, 0xdadaeb, 0xbcbddc, 0x9e9ac8, 0x807dba, 0x6a51a3, 0x54278f, 0x3f007d);
case BLUES:
return new Palette(0xf7fbff, 0xdeebf7, 0xc6dbef, 0x9ecae1, 0x6baed6, 0x4292c6, 0x2171b5, 0x08519c, 0x08306b);
case GREENS:
return new Palette(0xf7fcf5, 0xe5f5e0, 0xc7e9c0, 0xa1d99b, 0x74c476, 0x41ab5d, 0x238b45, 0x006d2c, 0x00441b);
case ORANGES:
return new Palette(0xfff5eb, 0xfee6ce, 0xfdd0a2, 0xfdae6b, 0xfd8d3c, 0xf16913, 0xd94801, 0xa63603, 0x7f2704);
case REDS:
return new Palette(0xfff5f0, 0xfee0d2, 0xfcbba1, 0xfc9272, 0xfb6a4a, 0xef3b2c, 0xcb181d, 0xa50f15, 0x67000d);
case GREYS:
return new Palette(0xffffff, 0xf0f0f0, 0xd9d9d9, 0xbdbdbd, 0x969696, 0x737373, 0x525252, 0x252525, 0x000000);
case PU_OR:
return new Palette(0x7f3b08, 0xb35806, 0xe08214, 0xfdb863, 0xfee0b6, 0xf7f7f7, 0xd8daeb, 0xb2abd2, 0x8073ac);
case BR_BL:
return new Palette(0x543005, 0x8c510a, 0xbf812d, 0xdfc27d, 0xf6e8c3, 0xf5f5f5, 0xc7eae5, 0x80cdc1, 0x35978f);
case PU_RD_GN:
return new Palette(0x40004b, 0x762a83, 0x9970ab, 0xc2a5cf, 0xe7d4e8, 0xf7f7f7, 0xd9f0d3, 0xa6dba0, 0x5aae61);
case PI_YL_GN:
return new Palette(0x8e0152, 0xc51b7d, 0xde77ae, 0xf1b6da, 0xfde0ef, 0xf7f7f7, 0xe6f5d0, 0xb8e186, 0x7fbc41);
case RD_BU:
return new Palette(0x67001f, 0xb2182b, 0xd6604d, 0xf4a582, 0xfddbc7, 0xf7f7f7, 0xd1e5f0, 0x92c5de, 0x4393c3);
case RD_GY:
return new Palette(0x67001f, 0xb2182b, 0xd6604d, 0xf4a582, 0xfddbc7, 0xffffff, 0xe0e0e0, 0xbababa, 0x878787);
case RD_YL_BU:
return new Palette(0xa50026, 0xd73027, 0xf46d43, 0xfdae61, 0xfee090, 0xffffbf, 0xe0f3f8, 0xabd9e9, 0x74add1);
case SPECTRAL:
return new Palette(0x9e0142, 0xd53e4f, 0xf46d43, 0xfdae61, 0xfee08b, 0xffffbf, 0xe6f598, 0xabdda4, 0x66c2a5);
case RD_YL_GN:
return new Palette(0xa50026, 0xd73027, 0xf46d43, 0xfdae61, 0xfee08b, 0xffffbf, 0xd9ef8b, 0xa6d96a, 0x66bd63);
default:
throw new IllegalArgumentException("Index should be less Palette.DEFAULT_PALETTE_COUNT");
}
}
/**
* Returns index of palette object passed from list of palettes predefined in Palette
* @param palette Object for finding index
* @return Index from predefined pallete or -1 if not found
*/
public static int indexOf(Palette palette) {
int pos = -1;
int[] passedPaletteColors = palette.getColors();
for (int i = 0; i < Palette.DEFAULT_PALETTE_COUNT; i++) {
int[] calledPaletteColors = Palette.getPalette(i).getColors();
for (int j = 0; j < 9; j++) {
if (passedPaletteColors[j] != calledPaletteColors[j]) {
break;
}
if (j == 8) {
return i;
}
}
}
return pos;
}
public Palette(int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8) {
colors = new int[9];
colors[0] = c0;
colors[1] = c1;
colors[2] = c2;
colors[3] = c3;
colors[4] = c4;
colors[5] = c5;
colors[6] = c6;
colors[7] = c7;
colors[8] = c8;
}
public Palette(int[] colors) {
if (colors.length != 9) {
throw new IllegalArgumentException("Colors array length should exactly be 9");
}
this.colors = colors;
}
/**
* Returns color corresponding to index passed from the set of color for a palette
* @param index Index of color in set of color for current palette object
* @return color as int without alpha channel
*/
public int getColor(int index) {
switch (index) {
case 0:
return colors[0];
case 1:
return colors[1];
case 2:
return colors[2];
case 3:
return colors[3];
case 4:
return colors[4];
case 5:
return colors[5];
case 6:
return colors[6];
case 7:
return colors[7];
case 8:
return colors[8];
default:
throw new IllegalArgumentException("Index should be less than 9");
}
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Triangulation.java
================================================
package com.sdsmdg.kd.trianglify.models;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Triangle2D;
import java.util.List;
/**
* Created by shyam on 12-Mar-17.
*/
public class Triangulation {
private List<Triangle2D> triangleList;
public Triangulation(List<Triangle2D> triangleList) {
this.triangleList = triangleList;
}
public List<Triangle2D> getTriangleList() {
return triangleList;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/presenters/Presenter.java
================================================
package com.sdsmdg.kd.trianglify.presenters;
import android.os.AsyncTask;
import com.sdsmdg.kd.trianglify.models.Triangulation;
import com.sdsmdg.kd.trianglify.utilities.colorizers.Colorizer;
import com.sdsmdg.kd.trianglify.utilities.colorizers.FixedPointsColorizer;
import com.sdsmdg.kd.trianglify.utilities.patterns.Circle;
import com.sdsmdg.kd.trianglify.utilities.patterns.Patterns;
import com.sdsmdg.kd.trianglify.utilities.patterns.Rectangle;
import com.sdsmdg.kd.trianglify.utilities.triangulator.DelaunayTriangulator;
import com.sdsmdg.kd.trianglify.utilities.triangulator.NotEnoughPointsException;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;
import com.sdsmdg.kd.trianglify.views.TrianglifyViewInterface;
import java.util.List;
/**
* <h1>Presenter.java</h1>
* <b>Description :</b>
* P of MVP implemented to present data generated using models
* to a view.
*
* @author suyash
* @since 18/3/17.
*/
public class Presenter {
private TrianglifyViewInterface view;
private Triangulation triangulation;
private TriangleGeneratorTask generatorTask;
/**
* Flag for keeping track of changes in attributes of the view. Helpful in increasing
* performance by stopping unnecessary regeneration of triangulation. Look at smartUpdate method for more.
* if triangulation is null then value is NULL_TRIANGULATION
* if triangulation is unchanged then value is UNCHANGED_TRIANGULATION
* if change in fillTriangle or drawStroke then value is PAINT_STYLE_CHANGED
* if change in grid width, grid height, variance, bleedX, bleedY, typeGrid or cell size then value is GRID_PARAMETERS_CHANGED
* if change in palette or random coloring then value is COLOR_SCHEME_CHANGED
*/
public ViewState viewState = ViewState.NULL_TRIANGULATION;
public enum ViewState {
NULL_TRIANGULATION,
UNCHANGED_TRIANGULATION,
PAINT_STYLE_CHANGED,
COLOR_SCHEME_CHANGED,
GRID_PARAMETERS_CHANGED
}
/**
* flag that keeps track of whether just the color of the triangulation is to be changed or not.
*/
private boolean generateOnlyColor;
public Presenter(TrianglifyViewInterface view) {
this.view = view;
}
public void setGenerateOnlyColor(boolean generateOnlyColor) {
this.generateOnlyColor = generateOnlyColor;
}
public void updateView() {
viewState = view.getViewState();
if (viewState == ViewState.PAINT_STYLE_CHANGED || viewState == ViewState.UNCHANGED_TRIANGULATION) {
view.invalidateView(triangulation);
} else if (viewState == ViewState.COLOR_SCHEME_CHANGED) {
generateNewColoredSoupAndInvalidate();
} else if (viewState == ViewState.GRID_PARAMETERS_CHANGED || viewState == ViewState.NULL_TRIANGULATION) {
generateOnlyColor = false;
generateSoupAndInvalidateView();
}
}
/**
* generateNewColoredSoupAndInvalidate method is called when only the coloration of the view is to be changed. It sets the
* GenerateOnlyColor boolean of presenter to true, so that when generateSoupAndInvalidateView is
* called, only the new colors are assigned to the triangles in the triangulation, since the
* grid parameters have not been changed, thereby bypassing the unnecessary regeneration of grid and delaunay triangulation.
*/
private void generateNewColoredSoupAndInvalidate() {
setGenerateOnlyColor(true);
generateSoupAndInvalidateView();
}
/**
* Generates a grid on basis of selected grid type
* @return Grid of Vector2D
*/
private List<Vector2D> generateGrid() {
int gridType = view.getTypeGrid();
Patterns patterns;
switch (gridType) {
case TrianglifyViewInterface.GRID_RECTANGLE:
patterns = new Rectangle(
view.getBleedX(), view.getBleedY(), view.getGridHeight(),
view.getGridWidth(), view.getCellSize(), view.getVariance());
break;
case TrianglifyViewInterface.GRID_CIRCLE:
patterns = new Circle(
view.getBleedX(), view.getBleedY(), 8, view.getGridHeight(),
view.getGridWidth(), view.getCellSize(), view.getVariance());
break;
default:
patterns = new Rectangle(
view.getBleedX(), view.getBleedY(), view.getGridHeight(),
view.getGridWidth(), view.getCellSize(), view.getVariance());
break;
}
return patterns.generate();
}
/**
* Generates soup corresponding to current instance parameters
* @return triangulation generated
*/
private Triangulation getSoup() {
if (generateOnlyColor) {
triangulation = generateColoredSoup(triangulation);
} else {
generateSoup();
}
return triangulation;
}
/**
* Generates colored triangulation.
*/
private void generateSoup() {
triangulation = generateTriangulation(generateGrid());
triangulation = generateColoredSoup(triangulation);
}
/**
* Creates triangles from a list of points
* @param inputGrid Grid of points for generating triangles
* @return List of Triangles generated from list of input points
*/
private Triangulation generateTriangulation(List<Vector2D> inputGrid) {
DelaunayTriangulator triangulator = new DelaunayTriangulator(inputGrid);
try {
triangulator.triangulate();
} catch (NotEnoughPointsException e) {
e.printStackTrace();
}
return new Triangulation(triangulator.getTriangles());
}
/**
* Colors each triangle in triangulation and stores color as triangle's color variable
* @param inputTriangulation triangulation to color
* @return Colored triangulation of input triangulation
*/
private Triangulation generateColoredSoup(Triangulation inputTriangulation) {
Colorizer colorizer = new FixedPointsColorizer(inputTriangulation,
view.getPalette(), view.getGridHeight() + 2*view.getBleedY(),
view.getGridWidth() + 2*view.getBleedX(), view.isRandomColoringEnabled());
return colorizer.getColororedTriangulation();
}
public void clearSoup() {
triangulation = null;
viewState = ViewState.NULL_TRIANGULATION;
}
/**
* generateSoupAndInvalidateView method starts a new thread to regenerate the triangulation so
* that the regeneration is not done on the UI thread, thereby reducing the workload on the UI thread.
*/
public void generateSoupAndInvalidateView() {
if (generatorTask != null) {
generatorTask.cancel(true);
}
generatorTask = new TriangleGeneratorTask();
generatorTask.execute();
}
/**
* TriangleGeneratorTask specifies the task of the thread. It regenerates the triangulation in the background in
* accordance to the value of the generateOnlyColor boolean. Upon the generation of the triangulation, it calls
* upon the invalidateView method to render the triangulation to the view.
*/
class TriangleGeneratorTask extends AsyncTask<Void, Void, Triangulation> {
@Override
protected Triangulation doInBackground(Void... params) {
return getSoup();
}
@Override
protected void onPostExecute(Triangulation triangulation) {
super.onPostExecute(triangulation);
view.invalidateView(triangulation);
}
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/ExtendedColor.java
================================================
package com.sdsmdg.kd.trianglify.utilities;
/**
* <h1>Title</h1>
* <b>Description : Extends android.graphics.Color to add function that helps colorizer work.</b>
* <p>
*
* @author suyash
* @since 1/4/17.
*/
public class ExtendedColor extends android.graphics.Color {
public int a;
public int r;
public int g;
public int b;
public ExtendedColor(int palleteColor) {
this(0xFF,
(palleteColor >> 4*4),
((palleteColor >> 4*2) & 0xFF),
((palleteColor) & 0xFF));
}
public ExtendedColor(int r, int g, int b) {
this(0xFF, r, g, b);
}
private ExtendedColor(int a, int r, int g, int b) {
this.a = a;
this.r = r;
this.g = g;
this.b = b;
}
public static ExtendedColor avg(ExtendedColor c0, ExtendedColor c1) {
return new ExtendedColor((c0.a + c1.a) / 2,
(c0.r + c1.r) / 2,
(c0.g + c1.g) / 2,
(c0.b + c1.b) / 2
);
}
public int toInt() {
return argb(a, r, g, b);
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/Point.java
================================================
package com.sdsmdg.kd.trianglify.utilities;
/**
* <h1>Title</h1>
* <b>Description :</b>
* <p>
*
* @author suyash
* @since 25/3/17.
*/
public class Point{
public int x;
public int y;
public Point() {
this(0, 0);
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public static Point subtract(Point a, Point b) {
return new Point(a.x - a.y, b.x - b.y);
}
public static Point add(Point a, Point b) {
return new Point(a.x + a.y, b.x + b.y);
}
/**
* Calculates mid point of two given points using integer arithmetic
* @param a First Point
* @param b Second Point
* @return Mid Point
*/
public static Point midPoint(Point a, Point b) {
return new Point((a.x + a.y) / 2, (b.x + b.y) / 2);
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/ThreadLocalRandom.java
================================================
package com.sdsmdg.kd.trianglify.utilities;
/**
* <h1>Thread Local Random</h1>
* <b>Description : Generates Random numbers that are local to a thread thus reducing instructions
* needed to generate a random number.</b>
*
* @author suyash
* @since 2/5/17.
*/
public class ThreadLocalRandom {
private long seed = 0x5DEECE66DL;
public ThreadLocalRandom() {
}
public ThreadLocalRandom(long seed) {
this.seed = seed;
}
/**
* Generates a psuedoRandom integer that has computational costs of several instructions less
* than that of java.util.random.nextInt().
* @param mod limit for generation of pseudo random number
* @return Random number between 0 and mod (exclusive)
*/
public int nextInt(int mod) {
if ( mod != 0 ) {
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int) (seed % mod);
}
return 0;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/Utilities.java
================================================
package com.sdsmdg.kd.trianglify.utilities;
import android.content.Context;
import android.util.DisplayMetrics;
/**
* <h1>Title</h1>
* <b>Description :</b>
* <p>
*
* @author suyash
* @since 5/5/17.
*/
public class Utilities {
public int dpToPx(int dp, Context context) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
public int pxToDp(int px, Context context) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/colorizers/Colorizer.java
================================================
package com.sdsmdg.kd.trianglify.utilities.colorizers;
import com.sdsmdg.kd.trianglify.models.Triangulation;
/**
* <h1>Title</h1>
* <b>Description :</b>
* <p>
*
* @author suyash
* @since 24/3/17.
*/
public interface Colorizer {
Triangulation getColororedTriangulation();
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/colorizers/FixedPointsColorizer.java
================================================
package com.sdsmdg.kd.trianglify.utilities.colorizers;
import android.util.Log;
import com.sdsmdg.kd.trianglify.models.Palette;
import com.sdsmdg.kd.trianglify.models.Triangulation;
import com.sdsmdg.kd.trianglify.utilities.ExtendedColor;
import com.sdsmdg.kd.trianglify.utilities.Point;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Triangle2D;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;
import com.sdsmdg.kd.trianglify.utilities.ThreadLocalRandom;
import static android.content.ContentValues.TAG;
/**
* <h1>Fixed Point Colorizer</h1>
* <b>Description :</b>
* Fixed point colorizer contains methods that colorize triangles
* based on the color palette provided in the constructor.
*
* @author suyash
* @since 24/3/17.
*/
public class FixedPointsColorizer implements Colorizer {
private ThreadLocalRandom random;
private Triangulation triangulation;
private Palette colorPalette;
private int gridWidth;
private int gridHeight;
private Boolean randomColoring = false;
public Palette getColorPalette() {
return colorPalette;
}
public void setColorPalette(Palette colorPalette) {
this.colorPalette = colorPalette;
}
public Triangulation getTriangulation() {
return triangulation;
}
public void setTriangulation(Triangulation triangulation) {
this.triangulation = triangulation;
}
public FixedPointsColorizer(Triangulation triangulation, Palette colorPalette,
int gridHeight, int gridWidth) {
this(triangulation, colorPalette, gridHeight, gridWidth, false);
}
public FixedPointsColorizer(Triangulation triangulation, Palette colorPalette,
int gridHeight, int gridWidth, Boolean randomColoring) {
this.randomColoring = randomColoring;
random = new ThreadLocalRandom(System.currentTimeMillis());
this.triangulation = triangulation;
this.colorPalette = colorPalette;
this.gridHeight = gridHeight;
this.gridWidth = gridWidth;
}
@Override
public Triangulation getColororedTriangulation() {
if (triangulation != null) {
for (Triangle2D triangle : triangulation.getTriangleList()) {
triangle.setColor(getColorForPoint(triangle.getCentroid()));
}
} else {
Log.i(TAG, "colorizeTriangulation: Triangulation cannot be null!");
}
return getTriangulation();
}
/**
* Returns color corresponding to the point passed in parameter by
* calculating average of specified by the palette.
*
*
* Relation between palette color and position on rectangle is
* depicted in the following figure:
*
*(c1 are corresponding int values representing color in ColorPalette.java)
* c0 c1 c2
* +-------------+--------------+
* | | |
* | r1 | r2 |
* | | |
* c7 +------------c8--------------+ c3
* | | |
* | r3 | r4 |
* | | |
* +-------------+--------------+
* c6 c5 c4
*
*
* <b>Algorithm</b>
* Grid provided is divided into four regions r1 to r4. Each of the region
* is considered independent on calculating color for a point.
*
* Sub-rectangle in which given point lies has four vertices, denoted by
* Point topLeft, topRight, bottomLeft and bottomRight. Algorith then
* calculates weighted mean of color corresponding to vertices (seperately
* in x-axis and y-axis). Result of this calculation is returned as int.
*
* @param point Point to get color for
* @return Color corresponding to current point
*/
// Sorry for such long method, here's a ASCII potato
// __
// / \
// / o \
// | o \
// / o |
// / o |
// \______o__/
//
private int getColorForPoint(Vector2D point) {
if (randomColoring) {
return colorPalette.getColor(random.nextInt(9));
} else {
ExtendedColor topLeftColor, topRightColor;
ExtendedColor bottomLeftColor, bottomRightColor;
Point topLeft, topRight;
Point bottomLeft, bottomRight;
// Following if..else identifies which sub-rectangle given point lies
if (point.x < gridWidth/2 && point.y < gridHeight/2) {
topLeftColor = new ExtendedColor(colorPalette.getColor(0));
topRightColor = new ExtendedColor(colorPalette.getColor(1));
bottomLeftColor = new ExtendedColor(colorPalette.getColor(7));
bottomRightColor = new ExtendedColor(colorPalette.getColor(8));
} else if (point.x >= gridWidth/2 && point.y < gridHeight/2) {
topLeftColor = new ExtendedColor(colorPalette.getColor(1));
topRightColor = new ExtendedColor(colorPalette.getColor(2));
bottomLeftColor = new ExtendedColor(colorPalette.getColor(8));
bottomRightColor = new ExtendedColor(colorPalette.getColor(3));
} else if (point.x >= gridWidth/2 && point.y >= gridHeight/2) {
topLeftColor = new ExtendedColor(colorPalette.getColor(8));
topRightColor = new ExtendedColor(colorPalette.getColor(3));
bottomLeftColor = new ExtendedColor(colorPalette.getColor(5));
bottomRightColor = new ExtendedColor(colorPalette.getColor(4));
} else {
topLeftColor = new ExtendedColor(colorPalette.getColor(7));
topRightColor = new ExtendedColor(colorPalette.getColor(8));
bottomLeftColor = new ExtendedColor(colorPalette.getColor(6));
bottomRightColor = new ExtendedColor(colorPalette.getColor(5));
}
// Calculate corners of sub rectangle in which point is identified
topLeft = new Point(
(point.x >= gridWidth/2) ? gridWidth/2 : 0,
(point.y >= gridHeight/2) ? gridHeight/2 : 0);
topRight = new Point(
(point.x >= gridWidth/2) ? gridWidth : gridWidth/2,
(point.y >= gridHeight/2) ? gridHeight/2 : 0);
bottomLeft = new Point(
(point.x >= gridWidth/2) ? gridWidth/2 : 0,
(point.y >= gridHeight/2) ? gridHeight : gridHeight/2);
bottomRight = new Point(
(point.x >= gridWidth/2) ? gridWidth : gridWidth/2,
(point.y >= gridHeight/2) ? gridHeight : gridHeight/2);
// Calculates weighted mean of colors
ExtendedColor weightedTopColor = new ExtendedColor(
(int)((topRightColor.r*(point.x - topLeft.x) + (topLeftColor.r)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x))),
(int)((topRightColor.g*(point.x - topLeft.x) + (topLeftColor.g)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x))),
(int)((topRightColor.b*(point.x - topLeft.x) + (topLeftColor.b)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x)))
);
ExtendedColor weightedBottomColor = new ExtendedColor(
(int) ((bottomRightColor.r*(point.x - topLeft.x) + (bottomLeftColor.r)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x))),
(int)((bottomRightColor.g*(point.x - topLeft.x) + (bottomLeftColor.g)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x))),
(int)((bottomRightColor.b*(point.x - topLeft.x) + (bottomLeftColor.b)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x)))
);
ExtendedColor weightedLeftColor = new ExtendedColor(
(int)((bottomLeftColor.r*(point.y - topLeft.y) + (topLeftColor.r)*(bottomLeft.y - point.y))
/ ((bottomLeft.y - topLeft.y))),
(int)((bottomLeftColor.g*(point.y - topLeft.y) + (topLeftColor.g)*(bottomLeft.y - point.y))
/ ((bottomLeft.y - topLeft.y))),
(int)((bottomLeftColor.b*(point.y - topLeft.y) + (topLeftColor.b)*(bottomLeft.y - point.y))
/ ((bottomLeft.y - topLeft.y)))
);
ExtendedColor weightedRightColor = new ExtendedColor(
(int)((bottomRightColor.r*(point.y - topRight.y)
+ (topRightColor.r)*(bottomRight.y - point.y))
/ ((bottomRight.y - topRight.y))),
(int)((bottomRightColor.g*(point.y - topRight.y)
+ (topRightColor.g)*(bottomRight.y - point.y))
/ ((bottomRight.y - topRight.y))),
(int)((bottomRightColor.b*(point.y - topRight.y)
+ (topRightColor.b)*(bottomRight.y - point.y))
/ ((bottomRight.y - topRight.y)))
);
ExtendedColor weightedYColor = new ExtendedColor(
(int)((weightedRightColor.r*(point.x - topLeft.x)
+ (weightedLeftColor.r)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x))),
(int)((weightedRightColor.g*(point.x - topLeft.x)
+ (weightedLeftColor.g)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x))),
(int)((weightedRightColor.b*(point.x - topLeft.x)
+ (weightedLeftColor.b)*(topRight.x - point.x))
/ ((topRight.x - topLeft.x)))
);
ExtendedColor weightedXColor = new ExtendedColor(
(int)((weightedBottomColor.r*(point.y - topLeft.y)
+ (weightedTopColor.r)*(bottomLeft.y - point.y))
/ ((bottomLeft.y - topLeft.y))),
(int)((weightedBottomColor.g*(point.y - topLeft.y)
+ (weightedTopColor.g)*(bottomLeft.y - point.y))
/ ((bottomLeft.y - topLeft.y))),
(int)((weightedBottomColor.b*(point.y - topLeft.y)
+ (weightedTopColor.b)*(bottomLeft.y - point.y))
/ ((bottomLeft.y - topLeft.y)))
);
return ExtendedColor.avg(weightedXColor, weightedYColor).toInt();
}
}
/**
* Calculates average of given numbers without using floating point
* operations
*
* @param args Values to calculate average of
* @return Average of values provided
*/
private int avg(int...args) {
int sum = 0;
for (int arg : args) {
sum += arg;
}
return sum/args.length;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Circle.java
================================================
package com.sdsmdg.kd.trianglify.utilities.patterns;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;
import java.util.List;
import java.util.Random;
/**
* Created by suyash on 12/3/17.
*/
public class Circle implements Patterns {
private final Random random = new Random();
private int bleedX = 0;
private int bleedY = 0;
private int pointsPerCircle = 8;
private int height = 0;
private int width = 0;
private int cellSize = 0;
private int variance = 0;
public List<Vector2D> grid;
public Random getRandom() {
return random;
}
public int getBleedX() {
return bleedX;
}
public void setBleedX(int bleedX) {
this.bleedX = bleedX;
}
public int getBleedY() {
return bleedY;
}
public void setBleedY(int bleedY) {
this.bleedY = bleedY;
}
public int getPointsPerCircle() {
return pointsPerCircle;
}
public void setPointsPerCircle(int pointsPerCircle) {
this.pointsPerCircle = pointsPerCircle;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getCellSize() {
return cellSize;
}
public void setCellSize(int cellSize) {
this.cellSize = cellSize;
}
public int getVariance() {
return variance;
}
public void setVariance(int variance) {
this.variance = variance;
}
public Circle(int bleedX, int bleedY, int pointsPerCircle, int height, int width, int cellSize, int variance) {
this.bleedX = bleedX;
this.bleedY = bleedY;
this.pointsPerCircle = pointsPerCircle;
this.height = height;
this.width = width;
this.cellSize = cellSize;
this.variance = variance;
}
public List<Vector2D> generate() {
Vector2D center = new Vector2D(width / 2, height / 2);
grid.clear();
int maxRadius = Math.max(width + bleedX, height + bleedY);
this.grid.add(center);
double slice, angle;
int x, y;
for (int radius = cellSize; radius < maxRadius; radius += cellSize) {
slice = 2 * Math.PI / pointsPerCircle;
for (int i = 0; i < pointsPerCircle; i++) {
angle = slice * i;
x = (int) (center.x + radius * Math.cos(angle)) + random.nextInt(variance);
y = (int) (center.y + radius * Math.sin(angle)) + random.nextInt(variance);
this.grid.add(new Vector2D(x, y));
}
}
return grid;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Patterns.java
================================================
package com.sdsmdg.kd.trianglify.utilities.patterns;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;
import java.util.List;
/**
* Created by suyash on 17/3/17.
*/
public interface Patterns {
public List<Vector2D> generate();
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Rectangle.java
================================================
package com.sdsmdg.kd.trianglify.utilities.patterns;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.sdsmdg.kd.trianglify.utilities.ThreadLocalRandom;
/**
* Created by suyash on 12/3/17.
*/
public class Rectangle implements Patterns {
private final ThreadLocalRandom random;
private int bleedX = 0;
private int bleedY = 0;
private int height= 0;
private int width= 0;
private int cellSize = 0;
private int variance= 0;
List<Vector2D> grid;
public Rectangle(int bleedX, int bleedY, int height, int width, int cellSize, int variance) {
this.bleedX = bleedX;
this.bleedY = bleedY;
this.variance = variance;
this.cellSize = cellSize;
this.height = height;
this.width = width;
random = new ThreadLocalRandom();
grid = new ArrayList<>();
}
/**
* Generates array of points arranged in a grid of rectangles with deviation from their positions
* on the basis of bleed value.
* @return List of Vector2D containing points that resembles rectangular grid
*/
@Override
public List<Vector2D> generate() {
grid.clear();
int x, y;
for (int j = 0; j < height + 2*bleedY; j += cellSize) {
for (int i = 0; i < width + 2*bleedX; i += cellSize) {
x = i + random.nextInt(variance);
y = j + random.nextInt(variance);
this.grid.add(new Vector2D(x, y));
}
}
return grid;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/DelaunayTriangulation.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
//import Triangulation.Triagulation;
/**
* <h1>Title</h1>
* <b>Description :</b>
* <p>
*
* @author suyash
* @since 31/3/17.
*/
public class DelaunayTriangulation {
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/DelaunayTriangulator.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A Java implementation of an incremental 2D Delaunay triangulation algorithm.
*
* @author Johannes Diemke
*/
public class DelaunayTriangulator {
private List<Vector2D> pointSet;
private TriangleSoup triangleSoup;
/**
* Constructor of the SimpleDelaunayTriangulator class used to create a new
* triangulator instance.
*
* @param pointSet
* The point set to be triangulated
* @throws NotEnoughPointsException
* Thrown when the point set contains less than three points
*/
public DelaunayTriangulator(List<Vector2D> pointSet) {
this.pointSet = pointSet;
this.triangleSoup = new TriangleSoup();
}
/**
* This method generates a Delaunay triangulation from the specified point
* set.
*
* @throws com.sdsmdg.kd.trianglify.utilities.triangulator.NotEnoughPointsException
*/
public void triangulate() throws NotEnoughPointsException {
triangleSoup = new TriangleSoup();
if (pointSet == null || pointSet.size() < 3) {
throw new NotEnoughPointsException("Less than three points in point set.");
}
/**
* In order for the in circumcircle test to not consider the vertices of
* the super triangle we have to start out with a big triangle
* containing the whole point set. We have to scale the super triangle
* to be very large. Otherwise the triangulation is not convex.
*/
float maxOfAnyCoordinate = 0.0f;
for (Vector2D vector : getPointSet()) {
maxOfAnyCoordinate = Math.max(Math.max(vector.x, vector.y), maxOfAnyCoordinate);
}
maxOfAnyCoordinate *= 16.0d;
float newCoordinate = 3.0f * maxOfAnyCoordinate;
final Vector2D p1 = new Vector2D(0.0f, newCoordinate);
final Vector2D p2 = new Vector2D(newCoordinate, 0.0f);
final Vector2D p3 = new Vector2D(-newCoordinate, -newCoordinate);
final Triangle2D superTriangle = new Triangle2D(p1, p2, p3);
triangleSoup.add(superTriangle);
for (int i = 0; i < pointSet.size(); i++) {
Triangle2D triangle = triangleSoup.findContainingTriangle(pointSet.get(i));
if (triangle == null) {
/**
* If no containing triangle exists, then the vertex is not
* inside a triangle (this can also happen due to numerical
* errors) and lies on an edge. In order to find this edge we
* search all edges of the triangle soup and select the one
* which is nearest to the point we try to add. This edge is
* removed and four new edges are added.
*/
final Edge2D edge = triangleSoup.findNearestEdge(pointSet.get(i));
final Triangle2D first = triangleSoup.findOneTriangleSharing(edge);
final Triangle2D second = triangleSoup.findNeighbour(first, edge);
final Vector2D firstNoneEdgeVertex = first.getNoneEdgeVertex(edge);
final Vector2D secondNoneEdgeVertex = second.getNoneEdgeVertex(edge);
triangleSoup.remove(first);
triangleSoup.remove(second);
final Triangle2D triangle1 = new Triangle2D(edge.a, firstNoneEdgeVertex, pointSet.get(i));
final Triangle2D triangle2 = new Triangle2D(edge.b, firstNoneEdgeVertex, pointSet.get(i));
final Triangle2D triangle3 = new Triangle2D(edge.a, secondNoneEdgeVertex, pointSet.get(i));
final Triangle2D triangle4 = new Triangle2D(edge.b, secondNoneEdgeVertex, pointSet.get(i));
triangleSoup.add(triangle1);
triangleSoup.add(triangle2);
triangleSoup.add(triangle3);
triangleSoup.add(triangle4);
legalizeEdge(triangle1, new Edge2D(edge.a, firstNoneEdgeVertex), pointSet.get(i));
legalizeEdge(triangle2, new Edge2D(edge.b, firstNoneEdgeVertex), pointSet.get(i));
legalizeEdge(triangle3, new Edge2D(edge.a, secondNoneEdgeVertex), pointSet.get(i));
legalizeEdge(triangle4, new Edge2D(edge.b, secondNoneEdgeVertex), pointSet.get(i));
} else {
/**
* The vertex is inside a triangle.
*/
final Vector2D a = triangle.a;
final Vector2D b = triangle.b;
final Vector2D c = triangle.c;
triangleSoup.remove(triangle);
final Triangle2D first = new Triangle2D(a, b, pointSet.get(i));
final Triangle2D second = new Triangle2D(b, c, pointSet.get(i));
final Triangle2D third = new Triangle2D(c, a, pointSet.get(i));
triangleSoup.add(first);
triangleSoup.add(second);
triangleSoup.add(third);
legalizeEdge(first, new Edge2D(a, b), pointSet.get(i));
legalizeEdge(second, new Edge2D(b, c), pointSet.get(i));
legalizeEdge(third, new Edge2D(c, a), pointSet.get(i));
}
}
/**
* Remove all triangles that contain vertices of the super triangle.
*/
triangleSoup.removeTrianglesUsing(superTriangle.a);
triangleSoup.removeTrianglesUsing(superTriangle.b);
triangleSoup.removeTrianglesUsing(superTriangle.c);
}
/**
* This method legalizes edges by recursively flipping all illegal edges.
*
* @param triangle
* The triangle
* @param edge
* The edge to be legalized
* @param newVertex
* The new vertex
*/
private void legalizeEdge(Triangle2D triangle, Edge2D edge, Vector2D newVertex) {
final Triangle2D neighbourTriangle = triangleSoup.findNeighbour(triangle, edge);
/**
* If the triangle has a neighbor, then legalize the edge
*/
if (neighbourTriangle != null) {
if (neighbourTriangle.isPointInCircumcircle(newVertex)) {
triangleSoup.remove(triangle);
triangleSoup.remove(neighbourTriangle);
final Vector2D noneEdgeVertex = neighbourTriangle.getNoneEdgeVertex(edge);
final Triangle2D firstTriangle = new Triangle2D(noneEdgeVertex, edge.a, newVertex);
final Triangle2D secondTriangle = new Triangle2D(noneEdgeVertex, edge.b, newVertex);
triangleSoup.add(firstTriangle);
triangleSoup.add(secondTriangle);
legalizeEdge(firstTriangle, new Edge2D(noneEdgeVertex, edge.a), newVertex);
legalizeEdge(secondTriangle, new Edge2D(noneEdgeVertex, edge.b), newVertex);
}
}
}
/**
* Creates a random permutation of the specified point set. Based on the
* implementation of the Delaunay algorithm this can speed up the
* computation.
*/
public void shuffle() {
Collections.shuffle(pointSet);
}
/**
* Shuffles the point set using a custom permutation sequence.
*
* @param permutation
* The permutation used to shuffle the point set
*/
public void shuffle(int[] permutation) {
List<Vector2D> temp = new ArrayList<Vector2D>();
for (int i = 0; i < permutation.length; i++) {
temp.add(pointSet.get(permutation[i]));
}
pointSet = temp;
}
/**
* Returns the point set in form of a vector of 2D vectors.
*
* @return Returns the points set.
*/
public List<Vector2D> getPointSet() {
return pointSet;
}
/**
* Returns the trianges of the triangulation in form of a vector of 2D
* triangles.
*
* @return Returns the triangles of the triangulation.
*/
public List<Triangle2D> getTriangles() {
return triangleSoup.getTriangles();
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Edge2D.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
/**
* 2D edge class implementation.
*
* @author Johannes Diemke
*/
public class Edge2D {
public Vector2D a;
public Vector2D b;
/**
* Constructor of the 2D edge class used to create a new edge instance from
* two 2D vectors describing the edge's vertices.
*
* @param a
* The first vertex of the edge
* @param b
* The second vertex of the edge
*/
public Edge2D(Vector2D a, Vector2D b) {
this.a = a;
this.b = b;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/EdgeDistancePack.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
/**
* Edge distance pack class implementation used to describe the distance to a
* given edge.
*
* @author Johannes Diemke
*/
public class EdgeDistancePack implements Comparable<EdgeDistancePack> {
public Edge2D edge;
public double distance;
/**
* Constructor of the edge distance pack class used to create a new edge
* distance pack instance from a 2D edge and a scalar value describing a
* distance.
*
* @param edge
* The edge
* @param distance
* The distance of the edge to some point
*/
public EdgeDistancePack(Edge2D edge, double distance) {
this.edge = edge;
this.distance = distance;
}
@Override
public int compareTo(EdgeDistancePack o) {
return Double.compare(this.distance, o.distance);
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/NotEnoughPointsException.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
/**
* Exception thrown by the Delaunay triangulator when it is initialized with
* less than three points.
*
* @author Johannes Diemke
*/
public class NotEnoughPointsException extends Exception {
private static final long serialVersionUID = 7061712854155625067L;
public NotEnoughPointsException() {
}
public NotEnoughPointsException(String s) {
super(s);
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Triangle2D.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
import java.util.Arrays;
/**
* 2D triangle class implementation.
*
* @author Johannes Diemke
*/
public class Triangle2D {
public Vector2D a;
public Vector2D b;
public Vector2D c;
private int color;
/**
* Constructor of the 2D triangle class used to create a new triangle
* instance from three 2D vectors describing the triangle's vertices.
*
* @param a
* The first vertex of the triangle
* @param b
* The second vertex of the triangle
* @param c
* The third vertex of the triangle
*/
public Triangle2D(Vector2D a, Vector2D b, Vector2D c) {
this.a = a;
this.b = b;
this.c = c;
}
/**
* Tests if a 2D point lies inside this 2D triangle. See Real-Time Collision
* Detection, chap. 5, p. 206.
*
* @param point
* The point to be tested
* @return Returns true iff the point lies inside this 2D triangle
*/
public boolean contains(Vector2D point) {
final double pab = point.sub(a).cross(b.sub(a));
final double pbc = point.sub(b).cross(c.sub(b));
if (!hasSameSign(pab, pbc)) {
return false;
}
double pca = point.sub(c).cross(a.sub(c));
if (!hasSameSign(pab, pca)) {
return false;
}
return true;
}
/**
* Tests if a given point lies in the circumcircle of this triangle. Let the
* triangle ABC appear in counterclockwise (CCW) order. Then when det >
* 0, the point lies inside the circumcircle through the three points a, b
* and c. If instead det < 0, the point lies outside the circumcircle.
* When det = 0, the four points are cocircular. If the triangle is oriented
* clockwise (CW) the result is reversed. See Real-Time Collision Detection,
* chap. 3, p. 34.
*
* @param point
* The point to be tested
* @return Returns true iff the point lies inside the circumcircle through
* the three points a, b, and c of the triangle
*/
public boolean isPointInCircumcircle(Vector2D point) {
final double a11 = a.x - point.x;
final double a21 = b.x - point.x;
final double a31 = c.x - point.x;
final double a12 = a.y - point.y;
final double a22 = b.y - point.y;
final double a32 = c.y - point.y;
final double a13 = (a.x - point.x) * (a.x - point.x) + (a.y - point.y) * (a.y - point.y);
final double a23 = (b.x - point.x) * (b.x - point.x) + (b.y - point.y) * (b.y - point.y);
final double a33 = (c.x - point.x) * (c.x - point.x) + (c.y - point.y) * (c.y - point.y);
final double det = a11 * a22 * a33 + a12 * a23 * a31 + a13 * a21 * a32 - a13 * a22 * a31 - a12 * a21 * a33
- a11 * a23 * a32;
if (isOrientedCCW()) {
return det > 0.0d;
}
return det < 0.0d;
}
/**
* Test if this triangle is oriented counterclockwise (CCW). Let A, B and C
* be three 2D points. If det > 0, C lies to the left of the directed
* line AB. Equivalently the triangle ABC is oriented counterclockwise. When
* det < 0, C lies to the right of the directed line AB, and the triangle
* ABC is oriented clockwise. When det = 0, the three points are colinear.
* See Real-Time Collision Detection, chap. 3, p. 32
*
* @return Returns true iff the triangle ABC is oriented counterclockwise
* (CCW)
*/
public boolean isOrientedCCW() {
final double a11 = a.x - c.x;
final double a21 = b.x - c.x;
final double a12 = a.y - c.y;
final double a22 = b.y - c.y;
final double det = a11 * a22 - a12 * a21;
return det > 0.0d;
}
/**
* Returns true if this triangle contains the given edge.
*
* @param edge
* The edge to be tested
* @return Returns true if this triangle contains the edge
*/
public boolean isNeighbour(Edge2D edge) {
return (a == edge.a || b == edge.a || c == edge.a) && (a == edge.b || b == edge.b || c == edge.b);
}
/**
* Returns the vertex of this triangle that is not part of the given edge.
*
* @param edge
* The edge
* @return The vertex of this triangle that is not part of the edge
*/
public Vector2D getNoneEdgeVertex(Edge2D edge) {
if (a != edge.a && a != edge.b) {
return a;
} else if (b != edge.a && b != edge.b) {
return b;
} else if (c != edge.a && c != edge.b) {
return c;
}
return null;
}
/**
* Returns true if the given vertex is one of the vertices describing this
* triangle.
*
* @param vertex
* The vertex to be tested
* @return Returns true if the Vertex is one of the vertices describing this
* triangle
*/
public boolean hasVertex(Vector2D vertex) {
if (a == vertex || b == vertex || c == vertex) {
return true;
}
return false;
}
/**
* Returns an EdgeDistancePack containing the edge and its distance nearest
* to the specified point.
*
* @param point
* The point the nearest edge is queried for
* @return The edge of this triangle that is nearest to the specified point
*/
public EdgeDistancePack findNearestEdge(Vector2D point) {
EdgeDistancePack[] edges = new EdgeDistancePack[3];
edges[0] = new EdgeDistancePack(new Edge2D(a, b),
computeClosestPoint(new Edge2D(a, b), point).sub(point).mag());
edges[1] = new EdgeDistancePack(new Edge2D(b, c),
computeClosestPoint(new Edge2D(b, c), point).sub(point).mag());
edges[2] = new EdgeDistancePack(new Edge2D(c, a),
computeClosestPoint(new Edge2D(c, a), point).sub(point).mag());
Arrays.sort(edges);
return edges[0];
}
/**
* Computes the closest point on the given edge to the specified point.
*
* @param edge
* The edge on which we search the closest point to the specified
* point
* @param point
* The point to which we search the closest point on the edge
* @return The closest point on the given edge to the specified point
*/
private Vector2D computeClosestPoint(Edge2D edge, Vector2D point) {
final Vector2D ab = edge.b.sub(edge.a);
float t = point.sub(edge.a).dot(ab) / ab.dot(ab);
if (t < 0.0f) {
t = 0.0f;
} else if (t > 1.0f) {
t = 1.0f;
}
return edge.a.add(ab.mult(t));
}
/**
* Tests if the two arguments have the same sign.
*
* @param a
* The first floating point argument
* @param b
* The second floating point argument
* @return Returns true iff both arguments have the same sign
*/
private boolean hasSameSign(double a, double b) {
return Math.signum(a) == Math.signum(b);
}
public void setColor(int color) {
this.color = color;
}
public int getColor() {
return color;
}
@Override
public String toString() {
return "Triangle2D[" + a + ", " + b + ", " + c + "]";
}
public Vector2D getCentroid() {
Vector2D centroid = new Vector2D(0,0);
centroid.x = ((a.x) + (b.x) + (c.x))/3;
centroid.y = ((a.y) + (b.y) + (c.y))/3;
return centroid;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/TriangleSoup.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
* Triangle soup class implementation.
*
* @author Johannes Diemke
*/
class TriangleSoup {
private HashSet<Triangle2D> triangleSoup;
/**
* Constructor of the triangle soup class used to create a new triangle soup
* instance.
*/
public TriangleSoup() {
this.triangleSoup = new HashSet<>();
}
/**
* Adds a triangle to this triangle soup.
*
* @param triangle
* The triangle to be added to this triangle soup
*/
public void add(Triangle2D triangle) {
this.triangleSoup.add(triangle);
}
/**
* Removes a triangle from this triangle soup.
*
* @param triangle
* The triangle to be removed from this triangle soup
*/
public void remove(Triangle2D triangle) {
this.triangleSoup.remove(triangle);
}
/**
* Returns the triangles from this triangle soup.
*
* @return The triangles from this triangle soup
*/
public List<Triangle2D> getTriangles() {
return new ArrayList<>(this.triangleSoup);
}
/**
* Returns the triangle from this triangle soup that contains the specified
* point or null if no triangle from the triangle soup contains the point.
*
* @param point
* The point
* @return Returns the triangle from this triangle soup that contains the
* specified point or null
*/
public Triangle2D findContainingTriangle(Vector2D point) {
for (Triangle2D triangle : triangleSoup) {
if (triangle.contains(point)) {
return triangle;
}
}
return null;
}
/**
* Returns the neighbor triangle of the specified triangle sharing the same
* edge as specified. If no neighbor sharing the same edge exists null is
* returned.
*
* @param triangle
* The triangle
* @param edge
* The edge
* @return The triangles neighbor triangle sharing the same edge or null if
* no triangle exists
*/
public Triangle2D findNeighbour(Triangle2D triangle, Edge2D edge) {
for (Triangle2D triangleFromSoup : triangleSoup) {
if (triangleFromSoup.isNeighbour(edge) && triangleFromSoup != triangle) {
return triangleFromSoup;
}
}
return null;
}
/**
* Returns one of the possible triangles sharing the specified edge. Based
* on the ordering of the triangles in this triangle soup the returned
* triangle may differ. To find the other triangle that shares this edge use
* the {@link findNeighbour(Triangle2D triangle, Edge2D edge)} method.
*
* @param edge
* The edge
* @return Returns one triangle that shares the specified edge
*/
public Triangle2D findOneTriangleSharing(Edge2D edge) {
for (Triangle2D triangle : triangleSoup) {
if (triangle.isNeighbour(edge)) {
return triangle;
}
}
return null;
}
/**
* Returns the edge from the triangle soup nearest to the specified point.
*
* @param point
* The point
* @return The edge from the triangle soup nearest to the specified point
*/
public Edge2D findNearestEdge(Vector2D point) {
List<EdgeDistancePack> edgeList = new ArrayList<EdgeDistancePack>();
for (Triangle2D triangle : triangleSoup) {
edgeList.add(triangle.findNearestEdge(point));
}
EdgeDistancePack[] edgeDistancePacks = new EdgeDistancePack[edgeList.size()];
edgeList.toArray(edgeDistancePacks);
Arrays.sort(edgeDistancePacks);
return edgeDistancePacks[0].edge;
}
/**
* Removes all triangles from this triangle soup that contain the specified
* vertex.
*
* @param vertex
* The vertex
*/
public void removeTrianglesUsing(Vector2D vertex) {
List<Triangle2D> trianglesToBeRemoved = new ArrayList<Triangle2D>();
for (Triangle2D triangle : triangleSoup) {
if (triangle.hasVertex(vertex)) {
trianglesToBeRemoved.add(triangle);
}
}
triangleSoup.removeAll(trianglesToBeRemoved);
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Vector2D.java
================================================
package com.sdsmdg.kd.trianglify.utilities.triangulator;
/**
* 2D vector class implementation.
*
* @author Johannes Diemke
*/
public class Vector2D {
public float x;
public float y;
/**
* Constructor of the 2D vector class used to create new vector instances.
*
* @param x
* The x coordinate of the new vector
* @param y
* The y coordinate of the new vector
*/
public Vector2D(float x, float y) {
this.x = x;
this.y = y;
}
/**
* Subtracts the given vector from this.
*
* @param vector
* The vector to be subtracted from this
* @return A new instance holding the result of the vector subtraction
*/
public Vector2D sub(Vector2D vector) {
return new Vector2D(this.x - vector.x, this.y - vector.y);
}
/**
* Adds the given vector to this.
*
* @param vector
* The vector to be added to this
* @return A new instance holding the result of the vector addition
*/
public Vector2D add(Vector2D vector) {
return new Vector2D(this.x + vector.x, this.y + vector.y);
}
/**
* Multiplies this by the given scalar.
*
* @param scalar
* The scalar to be multiplied by this
* @return A new instance holding the result of the multiplication
*/
public Vector2D mult(float scalar) {
return new Vector2D(this.x * scalar, this.y * scalar);
}
/**
* Computes the magnitude or length of this.
*
* @return The magnitude of this
*/
public float mag() {
return (float)Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
* Computes the dot product of this and the given vector.
*
* @param vector
* The vector to be multiplied by this
* @return A new instance holding the result of the multiplication
*/
public float dot(Vector2D vector) {
return this.x * vector.x + this.y * vector.y;
}
/**
* Computes the 2D pseudo cross product Dot(Perp(this), vector) of this and
* the given vector.
*
* @param vector
* The vector to be multiplied to the perpendicular vector of
* this
* @return A new instance holding the result of the pseudo cross product
*/
public float cross(Vector2D vector) {
return this.y * vector.x - this.x * vector.y;
}
@Override
public String toString() {
return "Vector2D[" + x + ", " + y + "]";
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/views/TrianglifyView.java
================================================
package com.sdsmdg.kd.trianglify.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import com.sdsmdg.kd.trianglify.presenters.Presenter;
import com.sdsmdg.kd.trianglify.R;
import com.sdsmdg.kd.trianglify.models.Palette;
import com.sdsmdg.kd.trianglify.models.Triangulation;
import com.sdsmdg.kd.trianglify.utilities.triangulator.Triangle2D;
public class TrianglifyView extends View implements TrianglifyViewInterface{
private int bleedX;
private int bleedY;
private int gridHeight;
private int gridWidth;
private int typeGrid;
private int variance;
private int cellSize;
private int paletteNumber;
private boolean fillTriangle;
private boolean drawStroke;
private boolean randomColoring;
private Palette palette;
private Triangulation triangulation;
private Presenter presenter;
private int bitmapQuality;
/**
*This variable is used to know whether the user wants the view to completely fill the passed gridHeight
* and gridWidth. If it is TRUE, then it will throw an exception whenever either bleedX or bleedY are not
* greater than the cellSize. If it is FALSE, then it will not check for the above condition, and hence will
* not throw an exception.
*/
private boolean fillViewCompletely;
public TrianglifyView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TrianglifyView, 0, 0);
attributeSetter(a);
this.presenter = new Presenter(this);
this.setDrawingCacheEnabled(true);
this.setDrawingCacheQuality(DRAWING_CACHE_QUALITY_AUTO);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setGridWidth(w);
setGridHeight(h);
smartUpdate();
}
private void attributeSetter(TypedArray typedArray) {
bleedX = (int) typedArray.getDimension(R.styleable.TrianglifyView_bleedX, 0);
bleedY = (int) typedArray.getDimension(R.styleable.TrianglifyView_bleedY, 0);
variance = (int) typedArray.getDimension(R.styleable.TrianglifyView_variance, 10);
cellSize = (int) typedArray.getDimension(R.styleable.TrianglifyView_cellSize, 40);
typeGrid = typedArray.getInt(R.styleable.TrianglifyView_gridType, 0);
fillTriangle = typedArray.getBoolean(R.styleable.TrianglifyView_fillTriangle, true);
drawStroke = typedArray.getBoolean(R.styleable.TrianglifyView_fillStrokes, false);
paletteNumber = typedArray.getInt(R.styleable.TrianglifyView_palette, 0);
palette = Palette.getPalette(paletteNumber);
typeGrid = GRID_RECTANGLE;
randomColoring = typedArray.getBoolean(R.styleable.TrianglifyView_randomColoring, false);
fillViewCompletely = typedArray.getBoolean(R.styleable.TrianglifyView_fillViewCompletely, false);
typedArray.recycle();
if (fillViewCompletely) {
checkViewFilledCompletely();
}
}
@Override
public int getBleedX() {
return bleedX;
}
public TrianglifyView setBleedX(int bleedX) {
this.bleedX = bleedX;
presenter.viewState = Presenter.ViewState.GRID_PARAMETERS_CHANGED;
if (fillViewCompletely) {
checkViewFilledCompletely();
}
return this;
}
@Override
public int getBleedY() {
return bleedY;
}
public TrianglifyView setBleedY(int bleedY) {
this.bleedY = bleedY;
presenter.viewState = Presenter.ViewState.GRID_PARAMETERS_CHANGED;
if (fillViewCompletely) {
checkViewFilledCompletely();
}
return this;
}
@Override
public int getGridHeight() {
return gridHeight;
}
public TrianglifyView setGridHeight(int gridHeight) {
this.gridHeight = gridHeight;
presenter.viewState = Presenter.ViewState.GRID_PARAMETERS_CHANGED;
return this;
}
@Override
public int getGridWidth() {
return gridWidth;
}
public TrianglifyView setGridWidth(int gridWidth) {
this.gridWidth = gridWidth;
presenter.viewState = Presenter.ViewState.GRID_PARAMETERS_CHANGED;
return this;
}
@Override
public int getBitmapQuality() {
return bitmapQuality;
}
public void setBitmapQuality(int bitmapQuality) {
this.bitmapQuality = bitmapQuality;
setDrawingCacheQuality(bitmapQuality);
}
@Override
public int getTypeGrid() {
return typeGrid;
}
public TrianglifyView setTypeGrid(int typeGrid) {
this.typeGrid = typeGrid;
presenter.viewState = Presenter.ViewState.GRID_PARAMETERS_CHANGED;
return this;
}
@Override
public int getVariance() {
return variance;
}
public TrianglifyView setVariance(int variance) {
this.variance = variance;
presenter.viewState = Presenter.ViewState.GRID_PARAMETERS_CHANGED;
return this;
}
@Override
public int getCellSize() {
return cellSize;
}
public TrianglifyView setCellSize(int cellSize) {
this.cellSize = cellSize;
presenter.viewState = Presenter.ViewState.GRID_PARAMETERS_CHANGED;
if (fillViewCompletely) {
checkViewFilledCompletely();
}
return this;
}
public TrianglifyView setFillViewCompletely(boolean fillViewCompletely) {
this.fillViewCompletely = fillViewCompletely;
if (fillViewCompletely) {
checkViewFilledCompletely();
}
return this;
}
@Override
public boolean isFillViewCompletely() {
return fillViewCompletely;
}
@Override
public boolean isFillTriangle() {
return fillTriangle;
}
public TrianglifyView setFillTriangle(boolean fillTriangle) {
this.fillTriangle = fillTriangle;
if (presenter.viewState != Presenter.ViewState.GRID_PARAMETERS_CHANGED && presenter.viewState != Presenter.ViewState.COLOR_SCHEME_CHANGED) {
presenter.viewState = Presenter.ViewState.PAINT_STYLE_CHANGED;
}
return this;
}
@Override
public boolean isDrawStrokeEnabled() {
return drawStroke;
}
public TrianglifyView setDrawStrokeEnabled(boolean drawStroke) {
this.drawStroke = drawStroke;
if (presenter.viewState != Presenter.ViewState.GRID_PARAMETERS_CHANGED && presenter.viewState != Presenter.ViewState.COLOR_SCHEME_CHANGED) {
presenter.viewState = Presenter.ViewState.PAINT_STYLE_CHANGED;
}
return this;
}
@Override
public boolean isRandomColoringEnabled() {
return randomColoring;
}
public TrianglifyView setRandomColoring(boolean randomColoring) {
this.randomColoring = randomColoring;
if (presenter.viewState != Presenter.ViewState.GRID_PARAMETERS_CHANGED) {
presenter.viewState = Presenter.ViewState.COLOR_SCHEME_CHANGED;
}
return this;
}
@Override
public Palette getPalette() {
return palette;
}
public TrianglifyView setPalette(Palette palette) {
this.palette = palette;
if (presenter.viewState != Presenter.ViewState.GRID_PARAMETERS_CHANGED) {
presenter.viewState = Presenter.ViewState.COLOR_SCHEME_CHANGED;
}
return this;
}
@Override
public Presenter.ViewState getViewState() {
return presenter.viewState;
}
private TrianglifyView setTriangulation(Triangulation triangulation) {
this.triangulation = triangulation;
return this;
}
/**
* This method clears the triangulation and sets the view state to NULL_TRIANGULATION.
*/
public void clearView() {
presenter.clearSoup();
}
/**
* invalidateView method invalidates the view by setting
* @param triangulation to the view instance triangulation and calling invalidate method.
* Once invalidated, the viewState is changed to UNCHANGED_TRIANGULATION to denote no change in the triangulation
* parameters after rendering the view.
*/
@Override
public void invalidateView(Triangulation triangulation) {
this.setTriangulation(triangulation);
invalidate();
presenter.viewState = Presenter.ViewState.UNCHANGED_TRIANGULATION;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
gridHeight = getHeight();
gridWidth = getWidth();
if (triangulation != null) {
plotOnCanvas(canvas);
} else {
generateAndInvalidate();
}
}
/**
* smartUpdate method ensures the increase in performance by generating only the necessary changes in triangulation.
* According to the value of viewState, it makes the necessary method call.
*/
public void smartUpdate() {
presenter.updateView();
}
/**
* generateAndInvalidate method is called when the triangulation is to be generated from scratch. It sets the
* GenerateOnlyColor boolean of presenter to false so that when generateSoupAndInvalidateView is
* called, the grid and delaunay triangulation is regenerated according to the new parameters, followed by
* colorization and plotting of the triangulation onto the view.
*/
public void generateAndInvalidate() {
presenter.setGenerateOnlyColor(false);
presenter.generateSoupAndInvalidateView();
}
private void plotOnCanvas(Canvas canvas) {
for (int i = 0; i < triangulation.getTriangleList().size(); i++) {
drawTriangle(canvas, triangulation.getTriangleList().get(i));
}
}
/**
* Draws triangle on the canvas object passed using the parameters of current view instance
* @param canvas Canvas to paint on
* @param triangle2D Triangle to draw on canvas
*/
private void drawTriangle(Canvas canvas, Triangle2D triangle2D) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
int color = triangle2D.getColor();
/*
* Add 0xff000000 for alpha channel required by android.graphics.Color
*/
color += 0xff000000;
paint.setColor(color);
paint.setStrokeWidth(4);
if (isFillTriangle() && isDrawStrokeEnabled()) {
paint.setStyle(Paint.Style.FILL_AND_STROKE);
} else if (isFillTriangle()) {
paint.setStyle(Paint.Style.FILL);
} else if (isDrawStrokeEnabled()) {
paint.setStyle(Paint.Style.STROKE);
} else {
paint.setStyle(Paint.Style.FILL_AND_STROKE);
}
paint.setAntiAlias(false);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(triangle2D.a.x - bleedX, triangle2D.a.y - bleedY);
path.lineTo(triangle2D.b.x - bleedX, triangle2D.b.y - bleedY);
path.lineTo(triangle2D.c.x - bleedX, triangle2D.c.y - bleedY);
path.lineTo(triangle2D.a.x - bleedX, triangle2D.a.y - bleedY);
path.close();
canvas.drawPath(path, paint);
}
/**
* This method checks whether the view will be filled completely by testing if both bleedY and bleedX are
* greater than cellSize. If not, then it throws an illegal argument exception.
*
* Explaination for Condition:
* Bleed defines the dimensions of extra size that TrianglifyView view generates so that triangles
* on the edge don't appear to be chopped off. In most of the cases min{bleedX, bleedY} > cellSize
* would ensure that the view is completely filled.
*/
private void checkViewFilledCompletely() {
if (bleedY <= cellSize || bleedX <= cellSize) {
throw new IllegalArgumentException("bleedY and bleedX should be larger than cellSize for view to be completely filled.");
}
}
public Bitmap getBitmap() {
Bitmap resultBitmap = getDrawingCache().copy(Bitmap.Config.ARGB_8888, true);
this.destroyDrawingCache();
return resultBitmap;
}
}
================================================
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/views/TrianglifyViewInterface.java
======
gitextract_a4up19b2/
├── .gitignore
├── .project
├── .settings/
│ └── org.eclipse.buildship.core.prefs
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DOCUMENTATION.md
├── LICENSE.md
├── README.md
├── app/
│ ├── .classpath
│ ├── .gitignore
│ ├── .project
│ ├── .settings/
│ │ └── org.eclipse.buildship.core.prefs
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── sdsmdg/
│ │ └── kd/
│ │ └── trianglifyexample/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── sdsmdg/
│ │ │ └── kd/
│ │ │ └── trianglifyexample/
│ │ │ ├── AboutActivity.java
│ │ │ ├── CustomPalettePickerActivity.java
│ │ │ └── MainActivity.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── color_picked_imageview_border.xml
│ │ │ ├── ok_icon.xml
│ │ │ └── palette_icon.xml
│ │ ├── layout/
│ │ │ ├── activity_about.xml
│ │ │ ├── activity_custom_palette_picker.xml
│ │ │ └── activity_main.xml
│ │ ├── menu/
│ │ │ ├── menu.xml
│ │ │ └── menu_custom_palette_picker.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ └── test/
│ └── java/
│ └── com/
│ └── sdsmdg/
│ └── kd/
│ └── trianglifyexample/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── resources/
│ └── tables/
│ ├── palette-methods-table.tgn
│ └── trianglify-view-attributes-table.tgn
├── settings.gradle
└── trianglify/
├── .classpath
├── .gitignore
├── .project
├── .settings/
│ └── org.eclipse.buildship.core.prefs
├── build.gradle
├── proguard-rules.pro
└── src/
├── androidTest/
│ └── java/
│ └── com/
│ └── sdsmdg/
│ └── kd/
│ └── trianglify/
│ └── ExampleInstrumentedTest.java
├── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── com/
│ │ └── sdsmdg/
│ │ └── kd/
│ │ └── trianglify/
│ │ ├── models/
│ │ │ ├── Grid.java
│ │ │ ├── Palette.java
│ │ │ └── Triangulation.java
│ │ ├── presenters/
│ │ │ └── Presenter.java
│ │ ├── utilities/
│ │ │ ├── ExtendedColor.java
│ │ │ ├── Point.java
│ │ │ ├── ThreadLocalRandom.java
│ │ │ ├── Utilities.java
│ │ │ ├── colorizers/
│ │ │ │ ├── Colorizer.java
│ │ │ │ └── FixedPointsColorizer.java
│ │ │ ├── patterns/
│ │ │ │ ├── Circle.java
│ │ │ │ ├── Patterns.java
│ │ │ │ └── Rectangle.java
│ │ │ └── triangulator/
│ │ │ ├── DelaunayTriangulation.java
│ │ │ ├── DelaunayTriangulator.java
│ │ │ ├── Edge2D.java
│ │ │ ├── EdgeDistancePack.java
│ │ │ ├── NotEnoughPointsException.java
│ │ │ ├── Triangle2D.java
│ │ │ ├── TriangleSoup.java
│ │ │ └── Vector2D.java
│ │ └── views/
│ │ ├── TrianglifyView.java
│ │ └── TrianglifyViewInterface.java
│ └── res/
│ └── values/
│ ├── attrs.xml
│ └── strings.xml
└── test/
└── java/
└── com/
└── sdsmdg/
└── kd/
└── trianglify/
└── ExampleUnitTest.java
SYMBOL INDEX (222 symbols across 30 files)
FILE: app/src/androidTest/java/com/sdsmdg/kd/trianglifyexample/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: app/src/main/java/com/sdsmdg/kd/trianglifyexample/AboutActivity.java
class AboutActivity (line 22) | public class AboutActivity extends AppCompatActivity {
method onCreate (line 32) | @Override
method displayOpenSourceLicenses (line 126) | public void displayOpenSourceLicenses() {
method onOptionsItemSelected (line 147) | public boolean onOptionsItemSelected(MenuItem item) {
FILE: app/src/main/java/com/sdsmdg/kd/trianglifyexample/CustomPalettePickerActivity.java
class CustomPalettePickerActivity (line 25) | public class CustomPalettePickerActivity extends AppCompatActivity {
method onCreate (line 35) | @Override
method onCreateOptionsMenu (line 116) | @Override
method onOptionsItemSelected (line 123) | public boolean onOptionsItemSelected(MenuItem item) {
FILE: app/src/main/java/com/sdsmdg/kd/trianglifyexample/MainActivity.java
class MainActivity (line 41) | public class MainActivity extends AppCompatActivity {
method onCreate (line 53) | @Override
method onCreateOptionsMenu (line 188) | @Override
method updateUIElements (line 195) | public void updateUIElements(TrianglifyView trianglifyView) {
method randomizeTrianglifyParameters (line 205) | public void randomizeTrianglifyParameters(TrianglifyView trianglifyVie...
method dpToPx (line 222) | public int dpToPx(int dp) {
method pxToDp (line 227) | public int pxToDp(int px) {
method onOptionsItemSelected (line 233) | @Override
method showColoringError (line 269) | public void showColoringError() {
method onActivityResult (line 274) | public void onActivityResult(int requestCode, int resultCode, Intent d...
method exportImage (line 285) | private void exportImage() throws IOException {
method addImageToGallery (line 305) | public static void addImageToGallery(Bitmap bitmap, Context context) t...
method setWallpaper (line 315) | public void setWallpaper(final TrianglifyView view) {
method onRequestPermissionsResult (line 342) | @Override
FILE: app/src/test/java/com/sdsmdg/kd/trianglifyexample/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
FILE: trianglify/src/androidTest/java/com/sdsmdg/kd/trianglify/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Grid.java
class Grid (line 11) | public class Grid {
method Grid (line 14) | public Grid(List<Vector2D> gridPoints) {
method getGridPoints (line 18) | public List<Vector2D> getGridPoints() {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Palette.java
class Palette (line 13) | public class Palette {
method getColors (line 47) | public int[] getColors() {
method setColors (line 51) | public void setColors(int[] colors) {
method getPalette (line 64) | public static Palette getPalette(int paletteIndex) {
method indexOf (line 132) | public static int indexOf(Palette palette) {
method Palette (line 152) | public Palette(int c0, int c1, int c2, int c3, int c4, int c5, int c6,...
method Palette (line 165) | public Palette(int[] colors) {
method getColor (line 177) | public int getColor(int index) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Triangulation.java
class Triangulation (line 11) | public class Triangulation {
method Triangulation (line 14) | public Triangulation(List<Triangle2D> triangleList) {
method getTriangleList (line 18) | public List<Triangle2D> getTriangleList() {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/presenters/Presenter.java
class Presenter (line 30) | public class Presenter {
type ViewState (line 46) | public enum ViewState {
method Presenter (line 59) | public Presenter(TrianglifyViewInterface view) {
method setGenerateOnlyColor (line 63) | public void setGenerateOnlyColor(boolean generateOnlyColor) {
method updateView (line 67) | public void updateView() {
method generateNewColoredSoupAndInvalidate (line 85) | private void generateNewColoredSoupAndInvalidate() {
method generateGrid (line 94) | private List<Vector2D> generateGrid() {
method getSoup (line 122) | private Triangulation getSoup() {
method generateSoup (line 134) | private void generateSoup() {
method generateTriangulation (line 144) | private Triangulation generateTriangulation(List<Vector2D> inputGrid) {
method generateColoredSoup (line 159) | private Triangulation generateColoredSoup(Triangulation inputTriangula...
method clearSoup (line 166) | public void clearSoup() {
method generateSoupAndInvalidateView (line 175) | public void generateSoupAndInvalidateView() {
class TriangleGeneratorTask (line 189) | class TriangleGeneratorTask extends AsyncTask<Void, Void, Triangulatio...
method doInBackground (line 191) | @Override
method onPostExecute (line 196) | @Override
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/ExtendedColor.java
class ExtendedColor (line 12) | public class ExtendedColor extends android.graphics.Color {
method ExtendedColor (line 18) | public ExtendedColor(int palleteColor) {
method ExtendedColor (line 25) | public ExtendedColor(int r, int g, int b) {
method ExtendedColor (line 29) | private ExtendedColor(int a, int r, int g, int b) {
method avg (line 36) | public static ExtendedColor avg(ExtendedColor c0, ExtendedColor c1) {
method toInt (line 44) | public int toInt() {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/Point.java
class Point (line 12) | public class Point{
method Point (line 16) | public Point() {
method Point (line 20) | public Point(int x, int y) {
method subtract (line 25) | public static Point subtract(Point a, Point b) {
method add (line 29) | public static Point add(Point a, Point b) {
method midPoint (line 39) | public static Point midPoint(Point a, Point b) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/ThreadLocalRandom.java
class ThreadLocalRandom (line 12) | public class ThreadLocalRandom {
method ThreadLocalRandom (line 15) | public ThreadLocalRandom() {
method ThreadLocalRandom (line 19) | public ThreadLocalRandom(long seed) {
method nextInt (line 29) | public int nextInt(int mod) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/Utilities.java
class Utilities (line 15) | public class Utilities {
method dpToPx (line 16) | public int dpToPx(int dp, Context context) {
method pxToDp (line 21) | public int pxToDp(int px, Context context) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/colorizers/Colorizer.java
type Colorizer (line 14) | public interface Colorizer {
method getColororedTriangulation (line 15) | Triangulation getColororedTriangulation();
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/colorizers/FixedPointsColorizer.java
class FixedPointsColorizer (line 26) | public class FixedPointsColorizer implements Colorizer {
method getColorPalette (line 36) | public Palette getColorPalette() {
method setColorPalette (line 40) | public void setColorPalette(Palette colorPalette) {
method getTriangulation (line 44) | public Triangulation getTriangulation() {
method setTriangulation (line 48) | public void setTriangulation(Triangulation triangulation) {
method FixedPointsColorizer (line 52) | public FixedPointsColorizer(Triangulation triangulation, Palette color...
method FixedPointsColorizer (line 57) | public FixedPointsColorizer(Triangulation triangulation, Palette color...
method getColororedTriangulation (line 67) | @Override
method getColorForPoint (line 124) | private int getColorForPoint(Vector2D point) {
method avg (line 249) | private int avg(int...args) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Circle.java
class Circle (line 13) | public class Circle implements Patterns {
method getRandom (line 27) | public Random getRandom() {
method getBleedX (line 31) | public int getBleedX() {
method setBleedX (line 35) | public void setBleedX(int bleedX) {
method getBleedY (line 39) | public int getBleedY() {
method setBleedY (line 43) | public void setBleedY(int bleedY) {
method getPointsPerCircle (line 47) | public int getPointsPerCircle() {
method setPointsPerCircle (line 51) | public void setPointsPerCircle(int pointsPerCircle) {
method getHeight (line 55) | public int getHeight() {
method setHeight (line 59) | public void setHeight(int height) {
method getWidth (line 63) | public int getWidth() {
method setWidth (line 67) | public void setWidth(int width) {
method getCellSize (line 71) | public int getCellSize() {
method setCellSize (line 75) | public void setCellSize(int cellSize) {
method getVariance (line 79) | public int getVariance() {
method setVariance (line 83) | public void setVariance(int variance) {
method Circle (line 87) | public Circle(int bleedX, int bleedY, int pointsPerCircle, int height,...
method generate (line 100) | public List<Vector2D> generate() {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Patterns.java
type Patterns (line 14) | public interface Patterns {
method generate (line 15) | public List<Vector2D> generate();
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Rectangle.java
class Rectangle (line 14) | public class Rectangle implements Patterns {
method Rectangle (line 27) | public Rectangle(int bleedX, int bleedY, int height, int width, int ce...
method generate (line 47) | @Override
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/DelaunayTriangulation.java
class DelaunayTriangulation (line 14) | public class DelaunayTriangulation {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/DelaunayTriangulator.java
class DelaunayTriangulator (line 12) | public class DelaunayTriangulator {
method DelaunayTriangulator (line 26) | public DelaunayTriangulator(List<Vector2D> pointSet) {
method triangulate (line 37) | public void triangulate() throws NotEnoughPointsException {
method legalizeEdge (line 146) | private void legalizeEdge(Triangle2D triangle, Edge2D edge, Vector2D n...
method shuffle (line 176) | public void shuffle() {
method shuffle (line 186) | public void shuffle(int[] permutation) {
method getPointSet (line 199) | public List<Vector2D> getPointSet() {
method getTriangles (line 209) | public List<Triangle2D> getTriangles() {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Edge2D.java
class Edge2D (line 8) | public class Edge2D {
method Edge2D (line 22) | public Edge2D(Vector2D a, Vector2D b) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/EdgeDistancePack.java
class EdgeDistancePack (line 9) | public class EdgeDistancePack implements Comparable<EdgeDistancePack> {
method EdgeDistancePack (line 24) | public EdgeDistancePack(Edge2D edge, double distance) {
method compareTo (line 29) | @Override
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/NotEnoughPointsException.java
class NotEnoughPointsException (line 9) | public class NotEnoughPointsException extends Exception {
method NotEnoughPointsException (line 13) | public NotEnoughPointsException() {
method NotEnoughPointsException (line 16) | public NotEnoughPointsException(String s) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Triangle2D.java
class Triangle2D (line 10) | public class Triangle2D {
method Triangle2D (line 28) | public Triangle2D(Vector2D a, Vector2D b, Vector2D c) {
method contains (line 42) | public boolean contains(Vector2D point) {
method isPointInCircumcircle (line 73) | public boolean isPointInCircumcircle(Vector2D point) {
method isOrientedCCW (line 107) | public boolean isOrientedCCW() {
method isNeighbour (line 126) | public boolean isNeighbour(Edge2D edge) {
method getNoneEdgeVertex (line 137) | public Vector2D getNoneEdgeVertex(Edge2D edge) {
method hasVertex (line 158) | public boolean hasVertex(Vector2D vertex) {
method findNearestEdge (line 174) | public EdgeDistancePack findNearestEdge(Vector2D point) {
method computeClosestPoint (line 198) | private Vector2D computeClosestPoint(Edge2D edge, Vector2D point) {
method hasSameSign (line 220) | private boolean hasSameSign(double a, double b) {
method setColor (line 224) | public void setColor(int color) {
method getColor (line 228) | public int getColor() {
method toString (line 232) | @Override
method getCentroid (line 239) | public Vector2D getCentroid() {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/TriangleSoup.java
class TriangleSoup (line 12) | class TriangleSoup {
method TriangleSoup (line 20) | public TriangleSoup() {
method add (line 30) | public void add(Triangle2D triangle) {
method remove (line 40) | public void remove(Triangle2D triangle) {
method getTriangles (line 49) | public List<Triangle2D> getTriangles() {
method findContainingTriangle (line 62) | public Triangle2D findContainingTriangle(Vector2D point) {
method findNeighbour (line 83) | public Triangle2D findNeighbour(Triangle2D triangle, Edge2D edge) {
method findOneTriangleSharing (line 102) | public Triangle2D findOneTriangleSharing(Edge2D edge) {
method findNearestEdge (line 118) | public Edge2D findNearestEdge(Vector2D point) {
method removeTrianglesUsing (line 139) | public void removeTrianglesUsing(Vector2D vertex) {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Vector2D.java
class Vector2D (line 8) | public class Vector2D {
method Vector2D (line 21) | public Vector2D(float x, float y) {
method sub (line 33) | public Vector2D sub(Vector2D vector) {
method add (line 44) | public Vector2D add(Vector2D vector) {
method mult (line 55) | public Vector2D mult(float scalar) {
method mag (line 64) | public float mag() {
method dot (line 75) | public float dot(Vector2D vector) {
method cross (line 88) | public float cross(Vector2D vector) {
method toString (line 92) | @Override
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/views/TrianglifyView.java
class TrianglifyView (line 18) | public class TrianglifyView extends View implements TrianglifyViewInterf...
method TrianglifyView (line 43) | public TrianglifyView(Context context, AttributeSet attrs) {
method onSizeChanged (line 52) | @Override
method attributeSetter (line 60) | private void attributeSetter(TypedArray typedArray) {
method getBleedX (line 83) | @Override
method setBleedX (line 88) | public TrianglifyView setBleedX(int bleedX) {
method getBleedY (line 97) | @Override
method setBleedY (line 102) | public TrianglifyView setBleedY(int bleedY) {
method getGridHeight (line 111) | @Override
method setGridHeight (line 116) | public TrianglifyView setGridHeight(int gridHeight) {
method getGridWidth (line 122) | @Override
method setGridWidth (line 127) | public TrianglifyView setGridWidth(int gridWidth) {
method getBitmapQuality (line 133) | @Override
method setBitmapQuality (line 138) | public void setBitmapQuality(int bitmapQuality) {
method getTypeGrid (line 143) | @Override
method setTypeGrid (line 148) | public TrianglifyView setTypeGrid(int typeGrid) {
method getVariance (line 154) | @Override
method setVariance (line 159) | public TrianglifyView setVariance(int variance) {
method getCellSize (line 165) | @Override
method setCellSize (line 170) | public TrianglifyView setCellSize(int cellSize) {
method setFillViewCompletely (line 179) | public TrianglifyView setFillViewCompletely(boolean fillViewCompletely) {
method isFillViewCompletely (line 187) | @Override
method isFillTriangle (line 192) | @Override
method setFillTriangle (line 197) | public TrianglifyView setFillTriangle(boolean fillTriangle) {
method isDrawStrokeEnabled (line 205) | @Override
method setDrawStrokeEnabled (line 210) | public TrianglifyView setDrawStrokeEnabled(boolean drawStroke) {
method isRandomColoringEnabled (line 218) | @Override
method setRandomColoring (line 223) | public TrianglifyView setRandomColoring(boolean randomColoring) {
method getPalette (line 231) | @Override
method setPalette (line 236) | public TrianglifyView setPalette(Palette palette) {
method getViewState (line 244) | @Override
method setTriangulation (line 249) | private TrianglifyView setTriangulation(Triangulation triangulation) {
method clearView (line 258) | public void clearView() {
method invalidateView (line 268) | @Override
method onDraw (line 275) | @Override
method smartUpdate (line 291) | public void smartUpdate() {
method generateAndInvalidate (line 301) | public void generateAndInvalidate() {
method plotOnCanvas (line 306) | private void plotOnCanvas(Canvas canvas) {
method drawTriangle (line 317) | private void drawTriangle(Canvas canvas, Triangle2D triangle2D) {
method checkViewFilledCompletely (line 361) | private void checkViewFilledCompletely() {
method getBitmap (line 367) | public Bitmap getBitmap() {
FILE: trianglify/src/main/java/com/sdsmdg/kd/trianglify/views/TrianglifyViewInterface.java
type TrianglifyViewInterface (line 11) | public interface TrianglifyViewInterface {
method getBleedX (line 15) | int getBleedX();
method getBleedY (line 16) | int getBleedY();
method getTypeGrid (line 17) | int getTypeGrid();
method getGridWidth (line 18) | int getGridWidth();
method getGridHeight (line 19) | int getGridHeight();
method getVariance (line 20) | int getVariance();
method getCellSize (line 21) | int getCellSize();
method getBitmapQuality (line 22) | int getBitmapQuality();
method getViewState (line 23) | Presenter.ViewState getViewState();
method isFillViewCompletely (line 24) | boolean isFillViewCompletely();
method isFillTriangle (line 25) | boolean isFillTriangle();
method isDrawStrokeEnabled (line 26) | boolean isDrawStrokeEnabled();
method isRandomColoringEnabled (line 27) | boolean isRandomColoringEnabled();
method getPalette (line 28) | Palette getPalette();
method invalidateView (line 29) | void invalidateView(Triangulation triangulation);
FILE: trianglify/src/test/java/com/sdsmdg/kd/trianglify/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
Condensed preview — 77 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (208K chars).
[
{
"path": ".gitignore",
"chars": 371,
"preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbi"
},
{
"path": ".project",
"chars": 439,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>trianglify</name>\n\t<comment>Project trianglify create"
},
{
"path": ".settings/org.eclipse.buildship.core.prefs",
"chars": 114,
"preview": "connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)\nconnection.project.dir=\neclipse.preferences.version=1\n"
},
{
"path": ".travis.yml",
"chars": 1152,
"preview": "language: android\njdk: oraclejdk8\nsudo: required\n\nandroid:\n components:\n - tools\n - platform-tools\n - tools\n "
},
{
"path": "CHANGELOG.md",
"chars": 1701,
"preview": "# Trianglify Releases\n\n## Latest\n* [Version 1.0.0](https://bintray.com/suyashmahar/trianglify/trianglify/1.0.0)\n | [Goog"
},
{
"path": "CONTRIBUTING.md",
"chars": 4411,
"preview": "Contributing to Trianglify\n==========================\n:+1::tada: First off, thanks for taking the time to contribute! :t"
},
{
"path": "DOCUMENTATION.md",
"chars": 13620,
"preview": "Welcome to the Trianglify documentation! Here's the ultimate guide to using Trianglify in your app.\n\n# Documentation\n## "
},
{
"path": "LICENSE.md",
"chars": 1048,
"preview": "Copyright 2016-17 SDSMDG\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software "
},
{
"path": "README.md",
"chars": 2752,
"preview": "<!-- \n\n<br> \n<br> \n<div align=\"center\"><img src=\"resources/trianglify-logo-with-text-close-fit.png\" data-canonical-src"
},
{
"path": "app/.classpath",
"chars": 344,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTA"
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/.project",
"chars": 591,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>app</name>\n\t<comment>Project app created by Buildship"
},
{
"path": "app/.settings/org.eclipse.buildship.core.prefs",
"chars": 116,
"preview": "connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)\nconnection.project.dir=..\neclipse.preferences.version=1\n"
},
{
"path": "app/build.gradle",
"chars": 1193,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion 27\n buildToolsVersion '26.0.2'\n defaultCo"
},
{
"path": "app/proguard-rules.pro",
"chars": 648,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /r"
},
{
"path": "app/src/androidTest/java/com/sdsmdg/kd/trianglifyexample/ExampleInstrumentedTest.java",
"chars": 766,
"preview": "package com.sdsmdg.kd.trianglifyexample;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationReg"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 940,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "app/src/main/java/com/sdsmdg/kd/trianglifyexample/AboutActivity.java",
"chars": 6106,
"preview": "package com.sdsmdg.kd.trianglifyexample;\n\nimport android.content.ActivityNotFoundException;\nimport android.content.Dialo"
},
{
"path": "app/src/main/java/com/sdsmdg/kd/trianglifyexample/CustomPalettePickerActivity.java",
"chars": 5707,
"preview": "package com.sdsmdg.kd.trianglifyexample;\n\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport"
},
{
"path": "app/src/main/java/com/sdsmdg/kd/trianglifyexample/MainActivity.java",
"chars": 14725,
"preview": "package com.sdsmdg.kd.trianglifyexample;\n\nimport android.Manifest;\nimport android.app.WallpaperManager;\nimport android.c"
},
{
"path": "app/src/main/res/drawable/color_picked_imageview_border.xml",
"chars": 266,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <stroke an"
},
{
"path": "app/src/main/res/drawable/ok_icon.xml",
"chars": 344,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:he"
},
{
"path": "app/src/main/res/drawable/palette_icon.xml",
"chars": 850,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:he"
},
{
"path": "app/src/main/res/layout/activity_about.xml",
"chars": 6490,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xm"
},
{
"path": "app/src/main/res/layout/activity_custom_palette_picker.xml",
"chars": 5043,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "app/src/main/res/layout/activity_main.xml",
"chars": 5175,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xm"
},
{
"path": "app/src/main/res/menu/menu.xml",
"chars": 1164,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "app/src/main/res/menu/menu_custom_palette_picker.xml",
"chars": 469,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:ap"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#009688</color>\n <color name=\"color"
},
{
"path": "app/src/main/res/values/dimens.xml",
"chars": 211,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 1336,
"preview": "<resources>\n <string name=\"app_name\">Trianglify Demo</string>\n\n\n <!-- About Fragment strings -->\n <string name="
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 756,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
},
{
"path": "app/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "app/src/test/java/com/sdsmdg/kd/trianglifyexample/ExampleUnitTest.java",
"chars": 409,
"preview": "package com.sdsmdg.kd.trianglifyexample;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example loca"
},
{
"path": "build.gradle",
"chars": 791,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 230,
"preview": "#Wed Feb 07 13:07:53 IST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 730,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "gradlew",
"chars": 4971,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "resources/tables/palette-methods-table.tgn",
"chars": 6475,
"preview": "{\"rows_views\":[[{\"style\":{\"borders\":\"\",\"font_style\":{},\"text_color\":\"\",\"bg_color\":\"\",\"halign\":\"left\",\"valign\":\"middle\",\""
},
{
"path": "resources/tables/trianglify-view-attributes-table.tgn",
"chars": 13850,
"preview": "{\"rows_views\":[[{\"style\":{\"borders\":\"lrtb\",\"font_style\":{},\"text_color\":\"\",\"bg_color\":\"\",\"halign\":\"left\",\"valign\":\"top\","
},
{
"path": "settings.gradle",
"chars": 30,
"preview": "include ':app', ':trianglify'\n"
},
{
"path": "trianglify/.classpath",
"chars": 344,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTA"
},
{
"path": "trianglify/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "trianglify/.project",
"chars": 627,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>trianglify-trianglify</name>\n\t<comment>Project triang"
},
{
"path": "trianglify/.settings/org.eclipse.buildship.core.prefs",
"chars": 116,
"preview": "connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)\nconnection.project.dir=..\neclipse.preferences.version=1\n"
},
{
"path": "trianglify/build.gradle",
"chars": 1965,
"preview": "apply plugin: 'com.android.library'\n\next {\n\n bintrayRepo = 'trianglify'\n bintrayName = 'trianglify' // Has to be"
},
{
"path": "trianglify/proguard-rules.pro",
"chars": 648,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /r"
},
{
"path": "trianglify/src/androidTest/java/com/sdsmdg/kd/trianglify/ExampleInstrumentedTest.java",
"chars": 757,
"preview": "package com.sdsmdg.kd.trianglify;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\n"
},
{
"path": "trianglify/src/main/AndroidManifest.xml",
"chars": 193,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.sdsmdg.kd.trianglify\">\n\n <appli"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Grid.java",
"chars": 404,
"preview": "package com.sdsmdg.kd.trianglify.models;\n\nimport com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;\n\nimport java."
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Palette.java",
"chars": 8813,
"preview": "package com.sdsmdg.kd.trianglify.models;\n\n/**\n * <h1>Palette</h1>\n * <b>Description : </b>\n * Set of 9 colors that are u"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/models/Triangulation.java",
"chars": 442,
"preview": "package com.sdsmdg.kd.trianglify.models;\n\nimport com.sdsmdg.kd.trianglify.utilities.triangulator.Triangle2D;\n\nimport jav"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/presenters/Presenter.java",
"chars": 7718,
"preview": "package com.sdsmdg.kd.trianglify.presenters;\n\n\nimport android.os.AsyncTask;\n\nimport com.sdsmdg.kd.trianglify.models.Tria"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/ExtendedColor.java",
"chars": 1081,
"preview": "package com.sdsmdg.kd.trianglify.utilities;\n\n/**\n * <h1>Title</h1>\n * <b>Description : Extends android.graphics.Color to"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/Point.java",
"chars": 831,
"preview": "package com.sdsmdg.kd.trianglify.utilities;\n\n/**\n * <h1>Title</h1>\n * <b>Description :</b>\n * <p>\n *\n * @author suyash\n "
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/ThreadLocalRandom.java",
"chars": 960,
"preview": "package com.sdsmdg.kd.trianglify.utilities;\n\n/**\n * <h1>Thread Local Random</h1>\n * <b>Description : Generates Random nu"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/Utilities.java",
"chars": 694,
"preview": "package com.sdsmdg.kd.trianglify.utilities;\n\nimport android.content.Context;\nimport android.util.DisplayMetrics;\n\n/**\n *"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/colorizers/Colorizer.java",
"chars": 287,
"preview": "package com.sdsmdg.kd.trianglify.utilities.colorizers;\n\nimport com.sdsmdg.kd.trianglify.models.Triangulation;\n\n/**\n * <h"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/colorizers/FixedPointsColorizer.java",
"chars": 11296,
"preview": "package com.sdsmdg.kd.trianglify.utilities.colorizers;\n\nimport android.util.Log;\n\nimport com.sdsmdg.kd.trianglify.models"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Circle.java",
"chars": 2775,
"preview": "package com.sdsmdg.kd.trianglify.utilities.patterns;\n\n\nimport com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;\n"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Patterns.java",
"chars": 257,
"preview": "package com.sdsmdg.kd.trianglify.utilities.patterns;\n\n\n\nimport com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/patterns/Rectangle.java",
"chars": 1624,
"preview": "package com.sdsmdg.kd.trianglify.utilities.patterns;\n\nimport com.sdsmdg.kd.trianglify.utilities.triangulator.Vector2D;\n\n"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/DelaunayTriangulation.java",
"chars": 234,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\n\n//import Triangulation.Triagulation;\n\n/**\n * <h1>Title</h1>\n *"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/DelaunayTriangulator.java",
"chars": 8148,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimpo"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Edge2D.java",
"chars": 577,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\n\n/**\n * 2D edge class implementation.\n * \n * @author Johannes D"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/EdgeDistancePack.java",
"chars": 891,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\n\n/**\n * Edge distance pack class implementation used to describ"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/NotEnoughPointsException.java",
"chars": 453,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\n\n/**\n * Exception thrown by the Delaunay triangulator when it i"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Triangle2D.java",
"chars": 7706,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\n\nimport java.util.Arrays;\n\n/**\n * 2D triangle class implementat"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/TriangleSoup.java",
"chars": 4491,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport jav"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/utilities/triangulator/Vector2D.java",
"chars": 2585,
"preview": "package com.sdsmdg.kd.trianglify.utilities.triangulator;\n\n/**\n * 2D vector class implementation.\n * \n * @author Johannes"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/views/TrianglifyView.java",
"chars": 12397,
"preview": "package com.sdsmdg.kd.trianglify.views;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport a"
},
{
"path": "trianglify/src/main/java/com/sdsmdg/kd/trianglify/views/TrianglifyViewInterface.java",
"chars": 787,
"preview": "package com.sdsmdg.kd.trianglify.views;\n\n/**\n * Created by suyash on 18/3/17.\n */\n\nimport com.sdsmdg.kd.trianglify.model"
},
{
"path": "trianglify/src/main/res/values/attrs.xml",
"chars": 1984,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <declare-styleable name=\"TrianglifyView\">\n <attr name=\"ble"
},
{
"path": "trianglify/src/main/res/values/strings.xml",
"chars": 73,
"preview": "<resources>\n <string name=\"app_name\">trianglify</string>\n</resources>\n"
},
{
"path": "trianglify/src/test/java/com/sdsmdg/kd/trianglify/ExampleUnitTest.java",
"chars": 402,
"preview": "package com.sdsmdg.kd.trianglify;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit "
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the sdsmdg/trianglify GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 77 files (187.4 KB), approximately 50.7k tokens, and a symbol index with 222 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.