How to correct loop counters for maze algorithm? - algorithm

I have figured out how to move my character around the maze using the algorithm I have written, but the count is not figuring correctly. At the end of each row my character moves up and down several times until the count reaches the specified number to exit the loop, then the character moves along the next row down until it reaches the other side and repeats the moving up and down until the count reaches the specified number again. Can anyone help me find why my count keeps getting off? The algorithm and the maze class I am calling from is listed below.
public class P4 {
public static void main(String[] args) {
// Create maze
String fileName = args[3];
Maze maze = new Maze(fileName);
System.out.println("Maze name: " + fileName);
// Get dimensions
int mazeWidth = maze.getWidth();
int mazeHeight = maze.getHeight();
// Print maze size
System.out.println("Maze width: " + mazeWidth);
System.out.println("Maze height: " + mazeHeight);
int r = 0;
int c = 0;
// Move commands
while (true){
for (c = 0; c <= mazeWidth; c++){
if (maze.moveRight()){
maze.isDone();
c++;
}
if (maze.isDone() == true){
System.exit(1);
}
if (maze.moveRight() == false && c != mazeWidth){
maze.moveDown();
maze.moveRight();
maze.moveRight();
maze.moveUp();
c++;
}
}
for (r = 0; r % 2 == 0; r++){
maze.moveDown();
maze.isDone();
if (maze.isDone() == true){
System.exit(1);
}
}
for (c = mazeWidth; c >= 0; c--){
if (maze.moveLeft()){
c--;
maze.isDone();
System.out.println(c);
}
if (maze.isDone() == true){
System.exit(1);
}
if (maze.moveLeft() == false && c != 0){
maze.moveDown();
maze.moveLeft();
maze.moveLeft();
maze.moveUp();
c--;
}
}
for (r = 1; r % 2 != 0; r++){
maze.moveDown();
maze.isDone();
if (maze.isDone() == true){
System.exit(1);
}
}
}
}
}
public class Maze {
// Maze variables
private char mazeData[][];
private int mazeHeight, mazeWidth;
private int finalRow, finalCol;
int currRow;
private int currCol;
private int prevRow = -1;
private int prevCol = -1;
// User interface
private JFrame frame;
private JPanel panel;
private Image java, student, success, donotpass;
private ArrayList<JButton> buttons;
// Maze constructor
public Maze(String fileName) {
// Read maze
readMaze(fileName);
// Graphics setup
setupGraphics();
}
// Get height
public int getHeight() {
return mazeHeight;
}
// Get width
public int getWidth() {
return mazeWidth;
}
// Move right
public boolean moveRight() {
// Legal move?
if (currCol + 1 < mazeWidth) {
// Do not pass?
if (mazeData[currRow][currCol + 1] != 'D')
{
currCol++;
redraw(true);
return true;
}
}
return false;
}
// Move left
public boolean moveLeft() {
// Legal move?
if (currCol - 1 >= 0) {
// Do not pass?
if (mazeData[currRow][currCol - 1] != 'D')
{
currCol--;
redraw(true);
return true;
}
}
return false;
}
// Move up
public boolean moveUp() {
// Legal move?
if (currRow - 1 >= 0) {
// Do not pass?
if (mazeData[currRow - 1][currCol] != 'D')
{
currRow--;
redraw(true);
return true;
}
}
return false;
}
// Move down
public boolean moveDown() {
// Legal move?
if (currRow + 1 < mazeHeight) {
// Do not pass?
if (mazeData[currRow + 1][currCol] != 'D')
{
currRow++;
redraw(true);
return true;
}
}
return false;
}
public boolean isDone() {
// Maze solved?
if ((currRow == finalRow) && (currCol == finalCol))
return true;
else
return false;
}
private void redraw(boolean print) {
// Wait for awhile
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
if (print)
System.out.println("Moved to row " + currRow + ", column " + currCol);
// Compute index and remove icon
int index = (prevRow * mazeWidth) + prevCol;
if ((prevRow >= 0) && (prevCol >= 0)) {
buttons.get(index).setIcon(null);
}
// Compute index and add icon
index = (currRow * mazeWidth) + currCol;
if ((currRow == finalRow) && (currCol == finalCol))
buttons.get(index).setIcon(new ImageIcon(success));
else
buttons.get(index).setIcon(new ImageIcon(student));
// Store previous location
prevRow = currRow;
prevCol = currCol;
}
// Set button
private void setButton(JButton button, int row, int col) {
if (mazeData[row][col] == 'S') {
button.setIcon(new ImageIcon(student));
currRow = row;
currCol = col;
} else if (mazeData[row][col] == 'J') {
button.setIcon(new ImageIcon(java));
finalRow = row;
finalCol = col;
} else if (mazeData[row][col] == 'D') {
button.setIcon(new ImageIcon(donotpass));
}
}
// Read maze
private void readMaze(String filename) {
try {
// Open file
Scanner scan = new Scanner(new File(filename));
// Read numbers
mazeHeight = scan.nextInt();
mazeWidth = scan.nextInt();
// Allocate maze
mazeData = new char[mazeHeight][mazeWidth];
// Read maze
for (int row = 0; row < mazeHeight; row++) {
// Read line
String line = scan.next();
for (int col = 0; col < mazeWidth; col++) {
mazeData[row][col] = line.charAt(col);
}
}
// Close file
scan.close();
} catch (IOException e) {
System.out.println("Cannot read maze: " + filename);
System.exit(0);
}
}
// Setup graphics
private void setupGraphics() {
// Create grid
frame = new JFrame();
panel = new JPanel();
panel.setLayout(new GridLayout(mazeHeight, mazeWidth, 0, 0));
frame.add(Box.createRigidArea(new Dimension(0, 5)), BorderLayout.NORTH);
frame.add(panel, BorderLayout.CENTER);
// Look and feel
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
// Configure window
frame.setSize(mazeWidth * 100, mazeHeight * 100);
frame.setTitle("Maze");
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
// Load and scale images
ImageIcon icon0 = new ImageIcon("Java.jpg");
Image image0 = icon0.getImage();
java = image0.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon1 = new ImageIcon("Student.jpg");
Image image1 = icon1.getImage();
student = image1.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon2 = new ImageIcon("Success.jpg");
Image image2 = icon2.getImage();
success = image2.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon3 = new ImageIcon("DoNotPass.jpg");
Image image3 = icon3.getImage();
donotpass = image3.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
// Build panel of buttons
buttons = new ArrayList<JButton>();
for (int row = 0; row < mazeHeight; row++) {
for (int col = 0; col < mazeWidth; col++) {
// Initialize and add button
JButton button = new JButton();
Border border = new LineBorder(Color.darkGray, 4);
button.setOpaque(true);
button.setBackground(Color.gray);
button.setBorder(border);
setButton(button, row, col);
panel.add(button);
buttons.add(button);
}
}
// Show window
redraw(false);
frame.setVisible(true);
}
}

One error I can see in your code is that you're incrementing your c counter more often than you should. You start with it managed by your for loop, which means that it will be incremented (or decremented, for the leftward moving version) at the end of each pass through the loop. However, you also increment it an additional time in two of your if statements. That means that c might increase by two or three on a single pass through the loop, which is probably not what you intend.
Furthermore, the count doesn't necessarily have anything obvious to do with the number of moves you make. The loop code will always increase it by one, even if you're repeatedly trying to move through an impassible wall.
I don't really understand what your algorithm is supposed to be, so I don't have any detailed advice for how to fix your code.
One suggestion I have though is that you probably don't ever want to be calling methods on your Maze class without paying attention to their return values. You have a bunch of places where you call isDone but ignore the return value, which doesn't make any sense. Similarly, you should always be checking the return values from your moveX calls, to see if the move was successful or not. Otherwise you may just blunder around a bunch, without your code having any clue where you are in the maze.

Related

How to find a path in a matrix which must pass through some cells

Given a 2d matrix, I have a start cell, end cell, cells that must be visited and cells that cannot be visited.
What would be the optimal way to find a path that:
starts at the start cell
ends at the end cell
passes through all must visit cell
does not pass through any cell that cannot be visited
does not pass any cell twice
we can only move left, right, up and down
The matrix size can be at most 10x10.
For example:
S - start
E - end
0 - can visit
X - can not visit
M - must visit
S 0 0 M 0
0 0 0 X 0
0 M 0 0 0
0 X 0 0 0
0 0 0 0 E
One solution would be:
* 0 * * *
* 0 * X *
* * * 0 *
0 X 0 0 *
0 0 0 0 *
The path doesn't necessarily should be the shortest one, but it would be nice if it can be, and it can be calculated quiet fast.
You can model the grid with a class Grid that would have a width and a height, and a set of must locations a set of mustNot locations:
public class Grid {
private final int width;
private final int height;
private final Set<Location> must = new HashSet<>();
private final Set<Location> mustNot = new HashSet<>();
public Grid(int width, int height,
Collection<Location> must, Collection<Location> mustNot) {
this.width = width;
this.height = height;
this.must.addAll(must);
this.mustNot.addAll(mustNot);
}
In that class, you would have a method solve that would take a start location and an end location, and would return the best path:
public PathNode solve(Location start, Location end) {
...
}
class Location looks like this:
public class Location {
public final int row;
public final int col;
public Location(int row, int col) {
this.row = row;
this.col = col;
}
#Override
public int hashCode() {
int hash = 7;
hash = 41 * hash + this.row;
hash = 41 * hash + this.col;
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Location other = (Location) obj;
if (this.row != other.row) {
return false;
}
return this.col == other.col;
}
#Override
public String toString() {
return "(" + row + ", " + col + ')';
}
}
Basically, it's a row and a col.
A path is a linked list of PathNodes:
public class PathNode {
public final Location loc;
public final PathNode link;
public PathNode(Location loc, PathNode link) {
this.loc = loc;
this.link = link;
}
public boolean contains(Location loc) {
PathNode n = this;
while (n != null) {
if (n.loc.equals(loc)) {
return true;
}
n = n.link;
}
return false;
}
}
I've added a contains method because of the condition that a path must not go through the same location twice.
Now, the algorithm is a breadth-first search:
public PathNode solve(Location start, Location end) {
List<PathNode> paths = new ArrayList<>();
if (validLoc(start.row, start.col) == null) {
return null;
}
paths.add(new PathNode(start, null));
for (int i = 0; i < paths.size(); ++i) {
PathNode path = paths.get(i);
Location loc = path.loc;
if (loc.equals(end)) {
// at the end point, we must still check the path goes through
// all the 'must' cells
if (allMustInPath(path)) {
// found a path
return path;
}
} else {
addToPaths(path, left(loc), paths);
addToPaths(path, right(loc), paths);
addToPaths(path, up(loc), paths);
addToPaths(path, down(loc), paths);
}
}
return null;
}
We still need a few more methods:
private Location left(Location loc) {
return validLoc(loc.row, loc.col-1);
}
private Location right(Location loc) {
return validLoc(loc.row, loc.col+1);
}
private Location up(Location loc) {
return validLoc(loc.row-1, loc.col);
}
private Location down(Location loc) {
return validLoc(loc.row+1, loc.col);
}
private Location validLoc(int row, int col) {
if (row >= 0 && row < height && col >= 0 && col < width) {
Location loc = new Location(row, col);
return mustNot.contains(loc) ? null : loc;
}
return null;
}
private boolean allMustInPath(PathNode path) {
for (Location loc: must) {
if (!path.contains(loc)) {
return false;
}
}
return true;
}
private void addToPaths(PathNode path, Location loc, List<PathNode> paths) {
if (loc == null) {
return;
}
loc = validLoc(loc.row, loc.col);
if (loc != null && !path.contains(loc)) {
paths.add(new PathNode(loc, path));
}
}
The path returned by the solve method, is actually in backward order. For your example above, it finds the path that you mentionned:
Grid grid = new Grid(5,5,
Arrays.asList(
new Location(0,3),
new Location(2,1)),
Arrays.asList(
new Location(1,3),
new Location(3,1)));
PathNode path = grid.solve(
new Location(0,0),
new Location(4,4));
if (path == null) {
System.out.println("No solution found");
}
while (path != null) {
System.out.println(path.loc);
path = path.link;
}
(4, 4)
(3, 4)
(2, 4)
(1, 4)
(0, 4)
(0, 3)
(0, 2)
(1, 2)
(2, 2)
(2, 1)
(1, 1)
(0, 1)
(0, 0)
Essentially, you need to calculate the minimum spanning tree ( MST, google it ).
Start with the cells that must be visited. These will be the nodes in the graph you apply the MST algorithm to. Find the lengths of the shortest paths between each pair of nodes ( in such a small problem you can easily do that manually ) These will be the links, and link costs you input to the MST.
Input the constructed graph to the MST method in your favorite graph-theory library.
For a more complicated version of this problem, which is solved using the same technique, see How to find a shortest path in a graph that while travelling it, you can "see" all the nodes within a radius

How to sort List in dart based on value returned by a function

I have to show a list of stores in a sorted order by nearest location
and I have a unsorted list of stores and a function to calculate
distance of each store from my current location but I don't know how
to sort List in dart based on value returned by a function.
I am getting the unsorted List of stores data from an api.
I need logic for this question for sorting the _kikkleStores List
class KikkleStoresBloc extends BlocBase {
List<KikkleStoreInfo> _kikkleStores = [];
//for distance sorting
List<KikkleStoreInfo> _kikkleStoresSorted = [];
List<double> distanceFromCurrentLocation;//already got
value in it
bool hasReachedEndOfList = false;
Coordinate _currentLocation;
KikkleStoresBloc();
final _kikkleStoreSubject =
BehaviorSubject<List<KikkleStoreInfo>>
();
// Getter Stream
Stream<List<KikkleStoreInfo>> get kikkleStores =>
_kikkleStoreSubject.stream;`enter code here`
// Getter Sink
Function(List<KikkleStoreInfo>) get _fetchedkikkleStores =>
_kikkleStoreSubject.sink.add;
getKikkleStores() async {
try {
if (_currentPage <= _totalPages) {
final response = await
ApiController.getKikkleStores(_currentPage);
_kikkleStores.addAll(response.item1);
//here how to sort _kikkleStores by using
getStoreDistance function
_totalPages = response.item3;
_fetchedkikkleStores(_kikkleStores);
if (_currentPage == _totalPages) {
hasReachedEndOfList = true;
} else if (_currentPage < _totalPages &&
_kikkleStores.length
< 10) {
}
}
}
}
// this function returns distance
getStoreDistance(Coordinate currentLocation, KikkleStoreInfo
store)
async {
if (currentLocation == null) return 0.0;
try {
double distanceInMeter = await
LocationUtils.getDistanceInMeters(
currentLocation, Coordinate(store.latitude,
store.longitude));
// final miles = (distanceInMeter / 1609.344).round();
return distanceInMeter;
} catch (e) {
return 0.0;
}
}
void getCurrentLocation() async {
try {
final isAllowed = await
PermissionsUtils.isLocationAccessAllowed();
if (isAllowed) {
final coordinates = await
LocationUtils.getCurrentLocation();
if (coordinates != null) {
_currentLocation = coordinates;
}
}
}
catch (e) {
print(e);
}
}
}
Take the reference of below code
void main(){
List<POJO> pojo = [POJO(5), POJO(3),POJO(7),POJO(1)];
// fill list
pojo..sort((a, b) => a.id.compareTo(b.id));
for(var i in pojo){
print(i.id); // prints list in sorted order i.e 1 3 5 7
}
}
class POJO {
int id;
POJO(this.id);
}
void sortfun() async {
for (int c = 0; c < (_kikkleStores.length - 1); c++) {
for (int d = 0; d < _kikkleStores.length - c - 1; d++) {
if (await getStoreDistance(_currentLocation, _kikkleStores[d]) >
await getStoreDistance(_currentLocation,
_kikkleStores[d + 1])) /* For descending order use < */
{
swap = _kikkleStores[d];
_kikkleStores[d] = _kikkleStores[d + 1];
_kikkleStores[d + 1] = swap;
}
}
}
}

Algorithms find shortest path to all cells on grid

I have a grid [40 x 15] with 2 to 16 units on it, and unknown amount of obstacles.
How to find the shortest path to all the units from my unit location.
I have two helper methods that we can consider as O(1)
getMyLocation() - return the (x, y) coordinates of my location on the grid
investigateCell(x, y) - return information about cell at (x,y) coordinates
I implemented A* search algorithm, that search simultaneously to all the directions. At the end it output a grid where each cell have a number representing the distance from my location, and collection of all the units on the grid. It performs with O(N) where N is the number of cells - 600 in my case.
I implement this using AS3, unfortunately it takes my machine 30 - 50 milliseconds to calculate.
Here is my source code. Can you suggest me a better way?
package com.gazman.strategy_of_battle_package.map
{
import flash.geom.Point;
/**
* Implementing a path finding algorithm(Similar to A* search only there is no known target) to calculate the shortest path to each cell on the map.
* Once calculation is complete the information will be available at cellsMap. Each cell is a number representing the
* number of steps required to get to that location. Enemies and Allies will be represented with negative distance. Also the enemy and Allys
* coordinations collections are provided. Blocked cells will have the value 0.<br><br>
* Worth case and best case efficiency is O(N) where N is the number of cells.
*/
public class MapFilter
{
private static const PULL:Vector.<MapFilter> = new Vector.<MapFilter>();
public var cellsMap:Vector.<Vector.<int>>;
public var allys:Vector.<Point>;
public var enemies:Vector.<Point>;
private var stack:Vector.<MapFilter>;
private var map:Map;
private var x:int;
private var y:int;
private var count:int;
private var commander:String;
private var hash:Object;
private var filtered:Boolean;
public function filter(map:Map, myLocation:Point, commander:String):void{
filtered = true;
this.commander = commander;
this.map = map;
this.x = myLocation.x;
this.y = myLocation.y;
init();
cellsMap[x][y] = 1;
excecute();
while(stack.length > 0){
var length:int = stack.length;
for(var i:int = 0; i < length; i++){
var mapFilter:MapFilter = stack.shift();
mapFilter.excecute();
PULL.push(mapFilter);
}
}
}
public function navigateTo(location:Point):Point{
if(!filtered){
throw new Error("Must filter before navigating");
}
var position:int = Math.abs(cellsMap[location.x][location.y]);
if(position == 0){
throw new Error("Target unreachable");
}
while(position > 2){
if(canNavigateTo(position, location.x + 1, location.y)){
location.x++;
}
else if(canNavigateTo(position, location.x - 1, location.y)){
location.x--;
}
else if(canNavigateTo(position, location.x, location.y + 1)){
location.y++;
}
else if(canNavigateTo(position, location.x, location.y - 1)){
location.y--;
}
position = cellsMap[location.x][location.y];
}
return location;
throw new Error("Unexpected filtering error");
}
private function canNavigateTo(position:int, targetX:int, targetY:int):Boolean
{
return isInMapRange(targetX, targetY) && cellsMap[targetX][targetY] < position && cellsMap[targetX][targetY] > 0;
}
private function excecute():void
{
papulate(x + 1, y);
papulate(x - 1, y);
papulate(x, y + 1);
papulate(x, y - 1);
}
private function isInMapRange(x:int, y:int):Boolean{
return x < cellsMap.length &&
x >= 0 &&
y < cellsMap[0].length &&
y >= 0;
}
private function papulate(x:int, y:int):void
{
if(!isInMapRange(x,y) ||
cellsMap[x][y] != 0 ||
hash[x + "," + y] != null ||
map.isBlocked(x,y)){
return;
}
// we already checked that is not block
// checking if there units
if(map.isEmpty(x,y)){
cellsMap[x][y] = count;
addTask(x,y);
}
else{
cellsMap[x][y] = -count;
if(map.isAlly(x,y, commander)){
hash[x + "," + y] = true;
allys.push(new Point(x,y));
}
else {
hash[x + "," + y] = true;
enemies.push(new Point(x,y));
}
}
}
private function addTask(x:int, y:int):void
{
var mapFilter:MapFilter = PULL.pop();
if(mapFilter == null){
mapFilter = new MapFilter();
}
mapFilter.commander = commander;
mapFilter.hash = hash;
mapFilter.map = map;
mapFilter.cellsMap = cellsMap;
mapFilter.allys = allys;
mapFilter..enemies = enemies;
mapFilter.stack = stack;
mapFilter.count = count + 1;
mapFilter.x = x;
mapFilter.y = y;
stack.push(mapFilter);
}
private function init():void
{
hash = new Object();
cellsMap = new Vector.<Vector.<int>>();
for(var i:int = 0; i < map.width;i++){
cellsMap.push(new Vector.<int>);
for(var j:int = 0; j < map.height;j++){
cellsMap[i].push(0);
}
}
allys = new Vector.<Point>();
enemies = new Vector.<Point>();
stack = new Vector.<MapFilter>();
count = 2;
}
}
}
You can use Floyd Warshall to find the shortest path between every pair of points. This would be O(|V|^3) and you would not have to run it for each unit, just once on each turn. It's such a simple algorithm I suspect it might be faster in practice than running something like BFS / Bellman Ford for each unit.

How to run processing script on multiple frames in a folder

Using processing I am trying to run a script that will process a folder full of frames.
The script is a combination of PixelSortFrames and SortThroughSeamCarving.
I am new to processing and what I want does not seems to be working. I would like the script to run back through and choose the following file in the folder to be processed. At the moment it stops at the end and does not return to start on next file (there are three other modules also involved).
Any help would be much appreciated. :(
/* ASDFPixelSort for video frames v1.0
Original ASDFPixelSort by Kim Asendorf <http://kimasendorf.com>
https://github.com/kimasendorf/ASDFPixelSort
Fork by dx <http://dequis.org> and chinatsu <http://360nosco.pe>
// Main configuration
String basedir = ".../Images/Seq_002"; // Specify the directory in which the frames are located. Use forward slashes.
String fileext = ".jpg"; // Change to the format your images are in.
int resumeprocess = 0; // If you wish to resume a previously stopped process, change this value.
boolean reverseIt = true;
boolean saveIt = true;
int mode = 2; // MODE: 0 = black, 1 = bright, 2 = white
int blackValue = -10000000;
int brightnessValue = -1;
int whiteValue = -6000000;
// -------
PImage img, original;
float[][] sums;
int bottomIndex = 0;
String[] filenames;
int row = 0;
int column = 0;
int i = 0;
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(fileext);
}
};
void setup() {
if (resumeprocess > 0) {i = resumeprocess - 1;frameCount = i;}
size(1504, 1000); // Resolution of the frames. It's likely there's a better way of doing this..
filenames = folder.list(extfilter);
size(1504, 1000);
println(" " + width + " x " + height + " px");
println("Creating buffer images...");
PImage hImg = createImage(1504, 1000, RGB);
PImage vImg = createImage(1504, 1000, RGB);
// draw image and convert to grayscale
if (i +1 > filenames.length) {println("Uh.. Done!"); System.exit(0);}
img = loadImage(basedir+"/"+filenames[i]);
original = loadImage(basedir+"/"+filenames[i]);
image(img, 0, 0);
filter(GRAY);
img.loadPixels(); // updatePixels is in the 'runKernals'
// run kernels to create "energy map"
println("Running kernals on image...");
runKernels(hImg, vImg);
image(img, 0, 0);
// sum pathways through the image
println("Getting sums through image...");
sums = getSumsThroughImage();
image(img, 0, 0);
loadPixels();
// get start point (smallest value) - this is used to find the
// best seam (starting at the lowest energy)
bottomIndex = width/2;
// bottomIndex = findStartPoint(sums, 50);
println("Bottom index: " + bottomIndex);
// find the pathway with the lowest information
int[] path = new int[height];
path = findPath(bottomIndex, sums, path);
for (int bi=0; bi<width; bi++) {
// get the pixels of the path from the original image
original.loadPixels();
color[] c = new color[path.length]; // create array of the seam's color values
for (int i=0; i<c.length; i++) {
try {
c[i] = original.pixels[i*width + path[i] + bi]; // set color array to values from original image
}
catch (Exception e) {
// when we run out of pixels, just ignore
}
}
println(" " + bi);
c = sort(c); // sort (use better algorithm later)
if (reverseIt) {
c = reverse(c);
}
for (int i=0; i<c.length; i++) {
try {
original.pixels[i*width + path[i] + bi] = c[i]; // reverse! set the pixels of the original from sorted array
}
catch (Exception e) {
// when we run out of pixels, just ignore
}
}
original.updatePixels();
}
// when done, update pixels to display
updatePixels();
// display the result!
image(original, 0, 0);
if (saveIt) {
println("Saving file...");
//filenames = stripFileExtension(filenames);
save("results/SeamSort_" + filenames + ".tiff");
}
println("DONE!");
}
// strip file extension for saving and renaming
String stripFileExtension(String s) {
s = s.substring(s.lastIndexOf('/')+1, s.length());
s = s.substring(s.lastIndexOf('\\')+1, s.length());
s = s.substring(0, s.lastIndexOf('.'));
return s;
}
This code works by processing all images in the selected folder
String basedir = "D:/things/pixelsortframes"; // Specify the directory in which the frames are located. Use forward slashes.
String fileext = ".png"; // Change to the format your images are in.
int resumeprocess = 0; // If you wish to resume a previously stopped process, change this value.
int mode = 1; // MODE: 0 = black, 1 = bright, 2 = white
int blackValue = -10000000;
int brightnessValue = -1;
int whiteValue = -6000000;
PImage img;
String[] filenames;
int row = 0;
int column = 0;
int i = 0;
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(fileext);
}
};
void setup() {
if (resumeprocess > 0) {i = resumeprocess - 1;frameCount = i;}
size(1920, 1080); // Resolution of the frames. It's likely there's a better way of doing this..
filenames = folder.list(extfilter);
}
void draw() {
if (i +1 > filenames.length) {println("Uh.. Done!"); System.exit(0);}
row = 0;
column = 0;
img = loadImage(basedir+"/"+filenames[i]);
image(img,0,0);
while(column < width-1) {
img.loadPixels();
sortColumn();
column++;
img.updatePixels();
}
while(row < height-1) {
img.loadPixels();
sortRow();
row++;
img.updatePixels();
}
image(img,0,0);
saveFrame(basedir+"/out/"+filenames[i]);
println("Frames processed: "+frameCount+"/"+filenames.length);
i++;
}
essentially I want to do the same thing only with a different image process but my code is not doing this to all with in the folder... just one file.
You seem to be confused about what the setup() function does. It runs once, and only once, at the beginning of your code's execution. You don't have any looping structure for processing the other files, so it's no wonder that it only processes the first one. Perhaps wrap the entire thing in a for loop? It looks like you kind of thought about this, judging by the global variable i, but you never increment it to go to the next image and you overwrite its value in several for loops later anyway.

Wrap AutoCompleteField List Item

My apps has AutoCompleteField that hold long text more than 100 Characters, if I use regular AutoCompleteField I cant read the rest of data.
How can I make the text wrap into 2 or more lines in the autocompletefield options ?
I try using '\r'+'\n' and '\n', its not giving new line. setting it size and also set row height doesnt give me the result I wanted
AutoCompleteField autoCustomer = new AutoCompleteField(custList, style);
autoCustomer.getListField().setSize(20);
autoCustomer.getListField().setRowHeight(100);
If I was you I would override drawListRow and draw the text using drawText which will give me total control on how the row should look. Try adapting your code to behave like this
AutoCompleteField autoCompleteField = new AutoCompleteField(
filterList, AutoCompleteField.LIST_STATIC) {
public void drawListRow(ListField listField, Graphics g,
int index, int y, int width) {
BasicFilteredListResult result = (BasicFilteredListResult) (autoCompleteField
.get(listField, index));
if (result != null)
{
//Draw text here
}
}
public void onSelect(Object selection, int type) {
super.onSelect(selection, type);
if (selection != null) {
BasicFilteredListResult result = (BasicFilteredListResult) this
.getSelectedObject();
handleResult((String) result._object);
} else {
Dialog.alert(Resource
.getString(PLEASE_PICK_A_VALID_NAME));
return;
}
}
};
IF you want to wrap your text you can use the following method
// Handy method to wrap text drawn with the specified font into rows with
// the max width
// Found here:
// http://supportforums.blackberry.com/t5/Java-Development/Can-drawText-wrap-text-into-multiple-lines/m-p/499901
public static String[] wrapText(String text, Font f, int maxWidth) {
Vector result = new Vector();
if (text == null)
return new String[] {};
boolean hasMore = true;
// The current index of the cursor
int current = 0;
// The next line break index
int lineBreak = -1;
// The space after line break
int nextSpace = -1;
while (hasMore) {
// Find the line break
while (true) {
lineBreak = nextSpace;
if (lineBreak == text.length() - 1) {
// We have reached the last line
hasMore = false;
break;
}
nextSpace = text.indexOf(' ', lineBreak + 1);
if (nextSpace == -1)
nextSpace = text.length() - 1;
int linewidth = f
.getAdvance(text, current, nextSpace - current);
// If too long, break out of the find loop
if (linewidth > maxWidth)
break;
}
String line = text.substring(current, lineBreak + 1);
result.addElement(line);
current = lineBreak + 1;
}
String[] resultArray = new String[result.size()];
result.copyInto(resultArray);
return resultArray;
}

Resources