Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// THIS FILE HAS BEEN GENERATED BY A PREPROCESSOR.
/* +=======================================================================
* |
* | PlantUML : a free UML diagram generator
* |
* +=======================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/liberapay (only 1€ per month!)
* https://plantuml.com/paypal
*
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the Eclipse Public License.
*
* THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
* LICENSE ("AGREEMENT"). [Eclipse Public License - v 1.0]
*
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
*
* You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* PlantUML can occasionally display sponsored or advertising messages. Those
* messages are usually generated on welcome or error images and never on
* functional diagrams.
* See https://plantuml.com/professional if you want to remove them
*
* Images (whatever their format : PNG, SVG, EPS...) generated by running PlantUML
* are owned by the author of their corresponding sources code (that is, their
* textual description in PlantUML language). Those images are not covered by
* this EPL license.
*
* The generated images can then be used without any reference to the EPL license.
* It is not even necessary to stipulate that they have been generated with PlantUML,
* although this will be appreciated by the PlantUML team.
*
* There is an exception : if the textual description in PlantUML language is also covered
* by any license, then the generated images are logically covered
* by the very same license.
*
* This is the IGY distribution (Install GraphViz by Yourself).
* You have to install GraphViz and to setup the GRAPHVIZ_DOT environment variable
* (see https://plantuml.com/graphviz-dot )
*
* Icons provided by OpenIconic : https://useiconic.com/open
* Archimate sprites provided by Archi : http://www.archimatetool.com
* Stdlib AWS provided by https://github.com/milo-minderbinder/AWS-PlantUML
* Stdlib Icons provided https://github.com/tupadr3/plantuml-icon-font-sprites
* ASCIIMathML (c) Peter Jipsen http://www.chapman.edu/~jipsen
* ASCIIMathML (c) David Lippman http://www.pierce.ctc.edu/dlippman
* CafeUndZopfli ported by Eugene Klyuchnikov https://github.com/eustas/CafeUndZopfli
* Brotli (c) by the Brotli Authors https://github.com/google/brotli
* Themes (c) by Brett Schwarz https://github.com/bschwarz/puml-themes
* Twemoji (c) by Twitter at https://twemoji.twitter.com/
*
*/
package org.stathissideris.ascii2image.text;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
*
* @author Efstathios Sideris
*/
public class CellSet implements Iterable {
private static final boolean DEBUG = false;
private static final boolean VERBOSE_DEBUG = false;
public static final int TYPE_CLOSED = 0;
public static final int TYPE_OPEN = 1;
public static final int TYPE_MIXED = 2;
public static final int TYPE_HAS_CLOSED_AREA = 3;
public static final int TYPE_UNDETERMINED = 4;
Set internalSet = new HashSet();
private int type = TYPE_UNDETERMINED;
private boolean typeIsValid = false;
private static final Object FAKE = new Object();
public CellSet(){
}
public CellSet(CellSet other){
addAll(other);
}
public Iterator iterator(){
return internalSet.iterator();
}
public Object add(TextGrid.Cell cell){
return internalSet.add(cell);
}
public void addAll(CellSet set){
internalSet.addAll(set.internalSet);
}
void clear(){
internalSet.clear();
}
public int size() {
return internalSet.size();
}
public TextGrid.Cell getFirst(){
//return internalSet.get(0);
return (TextGrid.Cell) internalSet.iterator().next();
}
public void printAsGrid(){
TextGrid grid = new TextGrid(getMaxX()+2, getMaxY()+2);
grid.fillCellsWith(this, '*');
grid.printDebug();
}
public void printDebug(){
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = it.next();
System.out.print(cell);
if(it.hasNext()) System.out.print(" ");
}
System.out.println();
}
public String getCellsAsString(){
StringBuilder str = new StringBuilder();
Iterator it = iterator();
while(it.hasNext()){
str.append(it.next().toString());
if(it.hasNext()) str.append("/");
}
return str.toString();
}
public String toString(){
TextGrid grid = new TextGrid(getMaxX()+2, getMaxY()+2);
grid.fillCellsWith(this, '*');
return grid.getDebugString();
}
/**
* Deep copy
*
* @param set
* @return
*/
public static CellSet copyCellSet(CellSet set) {
TextGrid grid = new TextGrid();
CellSet newSet = new CellSet();
Iterator it = set.iterator();
while (it.hasNext()) {
TextGrid.Cell cell = (TextGrid.Cell) it.next();
TextGrid.Cell newCell = grid.new Cell(cell);
newSet.add(newCell);
}
return newSet;
}
/*public BoundarySet(BoundarySet set) {
Iterator it = set.iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
add(new TextGrid.Cell(cell));
}
}*/
public int getType(TextGrid grid) {
if(typeIsValid) return type;
typeIsValid = true;
if(size() == 1) {
type = TYPE_OPEN;
return TYPE_OPEN;
}
int typeTrace = getTypeAccordingToTraceMethod(grid);
if(DEBUG){
System.out.println("trace: "+typeTrace);
}
if(typeTrace == TYPE_OPEN) {
type = TYPE_OPEN;
return TYPE_OPEN;
}
if(typeTrace == TYPE_CLOSED) {
type = TYPE_CLOSED;
return TYPE_CLOSED;
}
if(typeTrace == TYPE_UNDETERMINED) {
int typeFill = getTypeAccordingToFillMethod(grid);
if(typeFill == TYPE_HAS_CLOSED_AREA){
type = TYPE_MIXED;
return TYPE_MIXED;
} else if(typeFill == TYPE_OPEN){
type = TYPE_OPEN;
return TYPE_OPEN;
}
}
//in the case that both return undetermined:
type = TYPE_UNDETERMINED;
return TYPE_UNDETERMINED;
}
private int getTypeAccordingToTraceMethod(TextGrid grid) {
if(size() < 2) return TYPE_OPEN;
TextGrid workGrid = TextGrid.makeSameSizeAs(grid);
grid.copyCellsTo(this, workGrid);
//start with a line end if it exists or with a "random" cell if not
TextGrid.Cell start = null;
for(TextGrid.Cell cell : this)
if(workGrid.isLinesEnd(cell))
start = cell;
if(start == null) start = (TextGrid.Cell) getFirst();
if (DEBUG)
System.out.println("Tracing:\nStarting at "+start+" ("+grid.getCellTypeAsString(start)+")");
TextGrid.Cell previous = start;
TextGrid.Cell cell = null;
CellSet nextCells = workGrid.followCell(previous);
if(nextCells.size() == 0) return TYPE_OPEN;
cell = (TextGrid.Cell) nextCells.getFirst();
if (DEBUG)
System.out.println("\tat cell "+cell+" ("+grid.getCellTypeAsString(cell)+")");
while(!cell.equals(start)){
nextCells = workGrid.followCell(cell, previous);
if(nextCells.size() == 0) {
if (DEBUG)
System.out.println("-> Found dead-end, shape is open");
return TYPE_OPEN;
} if(nextCells.size() == 1) {
previous = cell;
cell = (TextGrid.Cell) nextCells.getFirst();
if (DEBUG)
System.out.println("\tat cell "+cell+" ("+grid.getCellTypeAsString(cell)+")");
} else if(nextCells.size() > 1) {
if (DEBUG)
System.out.println("-> Found intersection at cell "+cell);
return TYPE_UNDETERMINED;
}
}
if (DEBUG)
System.out.println("-> Arrived back to start, shape is closed");
return TYPE_CLOSED;
// boolean hasMoved = false;
//
// CellSet workSet;
// workSet = new CellSet(this);
//
// TextGrid.Cell start = (TextGrid.Cell) get(0);
//
// workSet.remove(start);
// TextGrid.Cell cell = workSet.findCellNextTo(start);
//
// while(true && cell != null){
//
// hasMoved = true;
// workSet.remove(cell);
//
// CellSet setOfNeighbours = workSet.findCellsNextTo(cell);
//
// if(setOfNeighbours.isEmpty()) break;
//
// TextGrid.Cell c = null;
// if(setOfNeighbours.size() == 1) c = (TextGrid.Cell) setOfNeighbours.get(0);
// if(setOfNeighbours.size() > 1) return TYPE_UNDETERMINED;
// if(c == null) break;
// else cell = c;
// }
// if(cell != null && start.isNextTo(cell) && hasMoved) return TYPE_CLOSED;
// else return TYPE_OPEN;
}
private int getTypeAccordingToFillMethod(TextGrid grid){
if(size() == 0) return TYPE_OPEN;
CellSet tempSet = copyCellSet(this);
tempSet.translate( -this.getMinX() + 1, -this.getMinY() + 1);
TextGrid subGrid = grid.getSubGrid(getMinX() - 1, getMinY() - 1, getWidth() + 3, getHeight() + 3);
AbstractionGrid abstraction = new AbstractionGrid(subGrid, tempSet);
TextGrid temp = abstraction.getCopyOfInternalBuffer();
TextGrid.Cell cell1 = null;
TextGrid.Cell cell2 = null;
int width = temp.getWidth();
int height = temp.getHeight();
TextGrid.Cell fillCell = null;
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
TextGrid.Cell cCell = temp.new Cell(x, y);
if(temp.isBlank(cCell)){
fillCell = cCell;
break;
}
}
}
if(fillCell == null){
System.err.println("Unexpected error: fill method cannot fill anywhere");
return TYPE_UNDETERMINED;
}
temp.fillContinuousArea(fillCell, '*');
if(VERBOSE_DEBUG) {System.out.println("Buffer after filling:"); temp.printDebug();}
if(temp.hasBlankCells()) return TYPE_HAS_CLOSED_AREA;
else return TYPE_OPEN;
}
public void translate(int dx, int dy){
typeIsValid = false;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cCell = (TextGrid.Cell) it.next();
cCell.x += dx;
cCell.y += dy;
}
}
public TextGrid.Cell find(TextGrid.Cell cell){
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cCell = it.next();
if(cCell.equals(cell)) return cCell;
}
return null;
}
public boolean contains(TextGrid.Cell cell){
if(cell == null) return false;
return internalSet.contains(cell);
}
// public boolean contains(TextGrid.Cell cell){
// Iterator it = iterator();
// while(it.hasNext()){
// TextGrid.Cell cCell = it.next();
// if(cCell.equals(cell)) return true;
// }
// return false;
// }
public void addSet(CellSet set){
typeIsValid = false;
this.addAll(set);
}
public boolean hasCommonCells(CellSet otherSet){
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = it.next();
if(otherSet.contains(cell)) return true;
}
return false;
}
public TextGrid.Cell find(int x, int y){
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cCell = (TextGrid.Cell) it.next();
if(cCell.x == x && cCell.y == y) return cCell;
}
return null;
}
public CellSet getFilledEquivalent(TextGrid textGrid){
if(this.getType(textGrid) == CellSet.TYPE_OPEN) return new CellSet(this);
TextGrid grid = new TextGrid(getMaxX()+2, getMaxY()+2);
grid.fillCellsWith(this, '*');
//find a cell that has a blank both on the east and the west
TextGrid.Cell cell = null;
boolean finished = false;
for(int y = 0; y < grid.getHeight() && !finished; y++){
for(int x = 0; x < grid.getWidth() && !finished; x++){
cell = grid.new Cell(x, y);
if(!grid.isBlank(cell)
&& grid.isBlank(cell.getEast())
&& grid.isBlank(cell.getWest())){
finished = true;
}
}
}
if(cell != null){
cell = cell.getEast();
if(grid.isOutOfBounds(cell)) return new CellSet(this);
grid.fillContinuousArea(cell, '*');
return grid.getAllNonBlank();
}
System.err.println("Unexpected error, cannot find the filled equivalent of CellSet");
return null;
}
/**
* Returns the first cell that is found to be next to cell.
*
* @param cell
* @return
*/
public TextGrid.Cell findCellNextTo(TextGrid.Cell cell){
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cCell = (TextGrid.Cell) it.next();
if(cCell.isNextTo(cell)) return cCell;
}
return null;
}
/**
* Returns all the cells that are found to be next to cell.
*
* @param cell
* @return
*/
public CellSet findCellsNextTo(TextGrid.Cell cell){
if(cell == null) throw new IllegalArgumentException("cell cannot be null");
CellSet set = new CellSet();
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cCell = (TextGrid.Cell) it.next();
if(cCell.isNextTo(cell)) set.add(cCell);
}
return set;
}
public void appendSet(CellSet set){
typeIsValid = false;
Iterator it = set.iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(find(cell) == null) add(cell);
}
}
public void subtractSet(CellSet set){
typeIsValid = false;
Iterator it = set.iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
TextGrid.Cell thisCell = find(cell);
if(thisCell != null) remove(thisCell);
}
}
public int getWidth(){
return getMaxX() - getMinX();
}
public int getHeight(){
return getMaxY() - getMinY();
}
public int getMaxX(){
int result = 0;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.x > result) result = cell.x;
}
return result;
}
public int getMinX(){
int result = Integer.MAX_VALUE;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.x < result) result = cell.x;
}
return result;
}
public int getMaxY(){
int result = 0;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.y > result) result = cell.y;
}
return result;
}
public int getMinY(){
int result = Integer.MAX_VALUE;
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(cell.y < result) result = cell.y;
}
return result;
}
public Object remove(TextGrid.Cell cell){
typeIsValid = false;
cell = find(cell);
if(cell != null) return internalSet.remove(cell);
else return null;
}
public boolean equals(Object o){
CellSet otherSet = (CellSet) o;
return internalSet.equals(otherSet.internalSet);
}
public static ArrayList removeDuplicateSets(ArrayList list) {
ArrayList uniqueSets = new ArrayList();
Iterator it = list.iterator();
while(it.hasNext()){
CellSet set = (CellSet) it.next();
boolean isOriginal = true;
Iterator uniquesIt = uniqueSets.iterator();
while(uniquesIt.hasNext()){
CellSet uniqueSet = (CellSet) uniquesIt.next();
if(set.equals(uniqueSet)){
isOriginal = false;
}
}
if(isOriginal) uniqueSets.add(set);
}
return uniqueSets;
}
/**
* Takes into account character info from the grid
*
* @return ArrayList of distinct BoundarySetS
*/
public ArrayList breakIntoDistinctBoundaries(TextGrid grid){
ArrayList result;
AbstractionGrid temp = new AbstractionGrid(grid, this);
result = temp.getDistinctShapes();
return result;
}
/**
*
* @return ArrayList of distinct BoundarySetS
*/
public ArrayList breakIntoDistinctBoundaries(){
ArrayList result = new ArrayList();
//CellSet tempSet = copyCellSet(this);
//tempSet.translate( - this.getMinX() + 1, - this.getMinY() + 1);
// TextGrid boundaryGrid = new TextGrid(tempSet.getMaxX()+2, tempSet.getMaxY()+2);
// boundaryGrid.fillCellsWith(tempSet, '*');
TextGrid boundaryGrid = new TextGrid(getMaxX()+2, getMaxY()+2);
boundaryGrid.fillCellsWith(this, '*');
Iterator it = iterator();
while(it.hasNext()){
TextGrid.Cell cell = (TextGrid.Cell) it.next();
if(boundaryGrid.isBlank(cell.x, cell.y)) continue;
CellSet boundarySet = boundaryGrid.fillContinuousArea(cell.x, cell.y, ' ');
//boundarySet.translate( this.getMinX() - 1, this.getMinY() - 1);
result.add(boundarySet);
}
return result;
}
/**
*
* Breaks that:
*