The area keeps coming out to zero. What am i doing wrong? - area

Trying to determine the area of a triangle. Prompted the user for 3 numbers(doubles) and calculated the area of a triangle within the program. The area must be a number of at least 3 decimal places. Yet, the area keeps coming out to 0. What am I doing wrong?
public static void main (String [] args) {
double sideA = 0.0;
double sideB = 0.0;
double sideC = 0.0;
int s = 1/2;
double area = 0.000;
Scanner scnr = new Scanner(System.in);
System.out.println("Enter Side A: ");
sideA = scnr.nextInt();
System.out.println("Enter Side B: ");
sideB = scnr.nextInt();
System.out.println("Enter Side C: ");
sideC = scnr.nextInt();
DecimalFormat fmt = new DecimalFormat("0.###");
area = Math.sqrt((s * (s - sideA) * (s - sideB) * (s - sideC)));
System.out.println("The area of the triangle is: " + fmt.format(area));
return;

This may help, I have taken your code and worked on it and this is what mine looks like:
public static void main (String [] args) {
double base;
double height;
double s = 2;
double area;
Scanner scnr = new Scanner(System.in);
System.out.print("Enter length for the Base: ");
base = scnr.nextInt();
System.out.println("Enter Height of the triangle: ");
height = scnr.nextInt();
DecimalFormat fmt = new DecimalFormat("0.###");
area = (height*base) / s;
System.out.println("The area of the triangle is: " + fmt.format(area));
}
This will printout 157.5 as your area. You were close to it but you are combining the formula for the perimeter and the formula for the area together and thats why it didn't work.

Related

Random() happening only once

I have this for() loop where I am randomizing the selection of slices of a picture, to display 16 slices of an image in a random order.
I'm picking those slices from an array and I have a variable that picks up what slice is going to be selected in the array.
The problem being that I'd think that the random function would be triggered for every frame, but it's triggered only once.
Here's the code :
void setup() {
size(720,720);
slices = new PImage[16];
slices[0] = loadImage("1.png");
slices[1] = loadImage("2.png");
slices[2] = loadImage("3.png");
slices[3] = loadImage("4.png");
slices[4] = loadImage("5.png");
slices[5] = loadImage("6.png");
slices[6] = loadImage("7.png");
slices[7] = loadImage("8.png");
slices[8] = loadImage("9.png");
slices[9] = loadImage("10.png");
slices[10] = loadImage("11.png");
slices[11] = loadImage("12.png");
slices[12] = loadImage("13.png");
slices[13] = loadImage("14.png");
slices[14] = loadImage("15.png");
slices[15] = loadImage("16.png");
frameRate(1);
}
void draw() {
for (int a = 0; a < 16; a++){
int rand = int(random(slices.length));
image(slices[rand],x,y,size,size);
x += size;
if (a % 4 == 3){
y += size;
x = 0;
}
}
It's dispalying the randomized slices only once and then I end up with a fix image. What I'd like to have is random slices appearing at every frame.
Thanks for your help !
You have 2 problems in your code.
First, you may not want to choose a random index.
This is because the same image could be chosen twice.
Instead, you could shuffle the array before drawing the images, like this:
for (int i = slices.length; i > 1; i--) {
//choose a random index for the i-th element to be swapped with
int j = (int)random(i);
//swap them
PImage temp = slices[j];
slices[j] = slices[i-1];
slices[i-1] = temp;
}
Second, the index is chosen on every frame, and the images are drawn, too, but you can't see it, because your code never resets y back to 0, meaning that they are below the screen.
You can fix this by adding
y = 0;
to the top or bottom of your draw().
Could it be because you've forgot to clear the screen (e.g. calling background()) (meaning once you've drawn an image it will stay rendered) ?
You could also make use of the for loop in setup to avoid repeating yourself:
int numSlices = 16;
PImage[] slices = new PImage[numSlices];
float x, y;
float size = 180;
void setup() {
size(720, 720);
for(int i = 0 ; i < numSlices; i++){
slices[i] = loadImage((i+1) + ".png");
}
frameRate(1);
}
void draw() {
background(255);
for (int a = 0; a < numSlices; a++) {
int rand = int(random(numSlices));
image(slices[rand], x, y, size, size);
x += size;
if (a % 4 == 3) {
y += size;
x = 0;
}
}
y = 0;
}
Additionally you could easily format your code (via CMD+T on OSX or Ctrl+T on Windows/Linux)
Update Kamakura (+1) correctly pointing out y not being reset to 0.
As a distraction I though't point you to IntList's shuffle() method:
int numSlices = 16;
PImage[] slices = new PImage[numSlices];
float x, y;
float size = 180;
IntList indices = new IntList();
void setup() {
size(720, 720);
for(int i = 0 ; i < numSlices; i++){
slices[i] = loadImage((i+1) + ".png");
indices.append(i);
}
frameRate(1);
}
void draw() {
background(255);
// shuffle list
indices.shuffle();
// reset y
y = 0;
for (int a = 0; a < numSlices; a++) {
int rand = indices.get(a);
image(slices[rand], x, y, size, size);
x += size;
if (a % 4 == 3) {
y += size;
x = 0;
}
}
}
Extra reason to play with it, other than a learning experience is that fact that it will be unlikely to get the same random index repeated.
Regarding splicing/shuffling, here's a modified version of the Load and Display example:
/**
* Load and Display
*
* Images can be loaded and displayed to the screen at their actual size
* or any other size.
*/
PImage img; // Declare variable "a" of type PImage
// shuffled image
PImage imgShuffled;
// list of indices to shuffle
IntList shuffleIndices = new IntList();
// configure image slicing rows/columns
int rows = 4;
int cols = 4;
// total sections
int numSections = rows * cols;
// image section dimensions
int sectionWidth;
int sectionHeight;
void setup() {
size(640, 360);
frameRate(1);
// The image file must be in the data folder of the current sketch
// to load successfully
img = loadImage("https://processing.org/examples/moonwalk.jpg"); // Load the image into the program
// calculate section dimensions
sectionWidth = img.width / cols;
sectionHeight = img.height / rows;
// allocate a separate image to copy shuffled pixels into
imgShuffled = createImage(img.width, img.height, RGB);
// populate image section indices
for(int i = 0 ; i < numSections; i++){
shuffleIndices.append(i);
}
}
void shuffleImage(){
// shuffle the list
shuffleIndices.shuffle();
// Ta-da!
println(shuffleIndices);
// loop through each section
for(int i = 0 ; i < numSections; i++){
// index to row, col conversion
int srcCol = i % cols;
int srcRow = i / cols;
// convert to pixel coordinates to copy from
int srcX = srcCol * sectionWidth;
int srcY = srcRow * sectionHeight;
// get random / shuffled index
int index = shuffleIndices.get(i);
// same row, col, to pixel conversion to copy to
int dstCol = index % cols;
int dstRow = index / cols;
int dstX = dstCol * sectionWidth;
int dstY = dstRow * sectionHeight;
// copy from original image to shuffled pixel coordinates
imgShuffled.copy(img,srcX,srcY,sectionWidth,sectionHeight,dstX,dstY,sectionWidth,sectionHeight);
}
}
void draw() {
shuffleImage();
// Displays the image at its actual size at point (0,0)
image(imgShuffled, 0, 0);
}

Attempting for loop with if-thn statement so that my desired value is surpassed by the value in the for loop

I'm working with a program so that it will be able to take a two values, and multiply the difference by the first power of ten above the sum and then add the sum. So for 5 and 3, it would be 2 * 10 + 8 = 28. This only works when the sum < 10. I am wondering if anybody can help to make the else portion of the if-then-else statement to work so than one where 9 and 1 and other values can be input so then the other half of the program will work.
import java.util.Scanner;
public class StrangeCalculation {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("What is the first number?");
int num1 = input.nextInt();
System.out.println("What is the second number?");
int num2 = input.nextInt();
int min = Math.min(num1, num2);
int max = Math.max(num1, num2);
int sum = min + max;
int diff = max - min;
int a = 1;
if (sum < Math.pow(10, a + 1)) {
int strangeValue = (int) (Math.pow(10, a) * diff + sum);
System.out.println("The value is: " + strangeValue);
}
else {
for(int i = 0; i < 3; i = 10 * i) {
//Loop until the sum value can be exceeded
}
}
}
}
Here is a very simple implementation with the main logic statement as,
double strangeValue = (Math.pow(10, (sum + "").length()) * diff + sum);
So, your program is,
public class StrangeCalculation {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("What is the first number?");
int num1 = input.nextInt();
System.out.println("What is the second number?");
int num2 = input.nextInt();
int min = Math.min(num1, num2);
int max = Math.max(num1, num2);
int sum = min + max;
int diff = max - min;
// Main logic
double strangeValue = (Math.pow(10, (sum + "").length()) * diff + sum);
}
}

How to use only one time bfs to solve this algorithm?

The problem is uva1599, Visit https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4474
The problem is roughly described as below:
The labyrinth consists of n rooms connected by m path. Each path is colored into some color ci. Find the ideal path from the room number 1 to the
room number n. The path is the ideal path if its color sequence is the lexicographically smallest among shortest paths.(2<=n<=100000, 1<=m<=200000, 1<=c<=10^9)
I could use bfs from the end room to get the shortest path for each room, and use bfs again to search from the beginning if there is multi paths with the same length of path and different colors.
How to solve this problem with only one bfs?
I try to start from the end room using bfs get the shortest path and color sequence for each room. The idael path is stored in the room 1's color sequence.
Is that right?
Thanks.
This is my code. The error is runtime error
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
public class IdealPath {
//store the path between two rooms, if there is a path between room i and j, then graph[i][j] = 1
public static int [][]graph;
//store the color between two rooms
public static int [][]color;
//store the shortest path to the end room for each room
public static int []distance;
//store the ideal color sequence for each room
public static String []color_seq;
//use for bfs
public static Queue<Integer> queue = new LinkedBlockingQueue<Integer>();
/**
* Initialize parameters
* #param n
*/
public static void init(int n){
graph = new int[n][n];
color = new int[n][n];
distance = new int[n];
color_seq = new String[n];
queue.clear();
}
/**
* use bfs to find the ideal path
* #param n
*/
public static void bfs(int n){
//init the end room
distance[n-1] = 0;
color_seq[n-1] = "";
queue.add(n-1);
//loop until the queue is empty
while(!queue.isEmpty()){
int node = queue.poll();
for (int i = 0; i < n; i++) {
//there is a path
if (graph[node][i] == 1){
//the room is not visited or is visited by the last floor
if (distance[i] == 0 || distance[i] == distance[node] + 1) {
distance[i] = distance[node] + 1; //add the distance
String str = color[i][node] + " " + color_seq[node]; //generate the color sequence
if (color_seq[i] == null)
color_seq[i] = str.trim();
//choose the ideal color sequence for the room
else
color_seq[i] = compare(color_seq[i], str) ? str.trim() : color_seq[i].trim();
queue.add(i);
}
}
}
}
}
/**
* return true if str2 < str1
* #param str1
* #param str2
* #return
*/
public static boolean compare(String str1, String str2){
String []arr2 = str2.trim().split(" ");
String []arr1 = str1.trim().split(" ");
//assume the lengths of arr1 and arr2 are same
for (int i = 0; i < arr1.length; i++) {
if (arr2[i].compareTo(arr1[i]) < 0)
return true;
}
return false;
}
public static void main(String []args){
Scanner input = new Scanner(System.in);
while(input.hasNext()){
//input
int n = input.nextInt();
int m = input.nextInt();
init(n);
for (int i = 0; i < m; i++) {
int node1 = input.nextInt() - 1;
int node2 = input.nextInt() - 1;
//ignore the path to itself
if (node1 != node2) {
graph[node1][node2] = graph[node2][node1] = 1;
int c = input.nextInt();
//choose the smallest path if it has multi path
color[node1][node2] = color[node2][node1] = (color[node1][node2] == 0) ? c : Math.min(c, color[node1][node2]);
}
}
//use bfs to find the ideal path
bfs(n);
//output
//the ideal path is stored in the color_seq[0]
String res = color_seq[0].trim();
System.out.println((res.length() + 1) / 2);
System.out.println(res);
}
}
}

How to get the nearest point outside a polygon from a point inside a polygon?

I have a map with a lot of polygons and a point inside in one of them, like this:
The x and y coordinates of the edges of the polygons are save in a database like this(for example):
Polygon(Point(11824, 10756), Point(11822, 10618), Point(11912, 10517), Point(12060, 10529), Point(12158, 10604), Point(12133, 10713), Point(12027, 10812), Point(11902, 10902)),
Polygon(Point(11077, 13610), Point(10949, 13642), Point(10828, 13584), Point(10772, 13480), Point(10756, 13353), Point(10849, 13256), Point(10976, 13224), Point(11103, 13294), Point(11171, 13414), Point(11135, 13558)),
Polygon(Point(11051.801757813, 11373.985351563), Point(11165.717773438, 11275.469726563), Point(11281.733398438, 11255.646484375), Point(11381.07421875, 11333.15625), Point(11440.202148438, 11467.706054688), Point(11404.73046875, 11584.534179688), Point(11301.662109375, 11643.852539063), Point(11169.486328125, 11644.079101563), Point(11067.555664063, 11579.676757813), Point(11018.21484375, 11454.750976563)),
Polygon(Point(12145, 13013), Point(12069.065429688, 13014.67578125), Point(12012.672851563, 12953.833984375), Point(11973.942382813, 12910.14453125), Point(11958.610351563, 12853.736328125), Point(11988.58203125, 12780.668945313), Point(12046.806640625, 12735.046875), Point(12117.080078125, 12729.838867188), Point(12185.567382813, 12743.389648438), Point(12225.575195313, 12803.530273438), Point(12255.934570313, 12859.2109375), Point(12263.861328125, 12914.166992188), Point(12221.2578125, 12978.983398438)),
They are drawn later, I don't have access to that, only to this coordinates.
So I have the x/y of the edges of the polygons and the x/y of the red dot. Now i have to know in which polygon the red dot is.
Then the most important I need is this:
I have the x and y coordinates of the red point and the x y coordinates of the edges.
I need the x and y coordinates of the green dot.(The nearest location outside the polygon)
I need it in lua, but feel free to answer in any language, I can translate it.
To know in which polygon the point is in you can use the Ray Casting algorithm.
For finding the closest edge you could use a naive approach computing the distance to each edge and then take the minimum. Just remember to check if the intersection with edge is outside the edge (check this). If it is outside take the distance to the closest extreme of the edge.
Ok better explaining the intuition with some pseudo-code:
dot(u,v) --> ((u).x * (v).x + (u).y * (v).y)
norm(v) --> sqrt(dot(v,v)) // norm = length of vector
dist(u,v)--> norm(u-v) // distance = norm of difference
// Vector contains x and y
// Point contains x and y
// Segment contains P0 and P1 of type Point
// Point = Point ± Vector
// Vector = Point - Point
// Vector = Scalar * Vector
Point closest_Point_in_Segment_to(Point P, Segment S)
{
Vector v = S.P1 - S.P0;
Vector w = P - S.P0;
double c1 = dot(w,v);
if ( c1 <= 0 ) // the closest point is outside the segment and nearer to P0
return S.P0;
double c2 = dot(v,v);
if ( c2 <= c1 ) // the closest point is outside the segment and nearer to P1
return S.P1;
double b = c1 / c2;
Point Pb = S.P0 + b * v;
return Pb;
}
[Point, Segment] get_closest_border_point_to(Point point, Polygon poly) {
double bestDistance = MAX_DOUBLE;
Segment bestSegment;
Point bestPoint;
foreach s in poly.segments {
Point closestInS = closest_Point_in_Segment_to(point, s);
double d = dist(point, closestInS);
if (d < bestDistance) {
bestDistance = d;
bestSegment = s;
bestPoint = closestInS;
}
}
return [bestPoint, bestSegment];
}
I think this pseudo-code should get you going, of course once you have the polygon your point is in!.
My PolyCollisions class:
public class PolyCollisions {
// Call this function...
public static Vector2 doCollisions (Vector2[] polygon, Vector2 point) {
if(!pointIsInPoly(polygon, point)) {
// The point is not colliding with the polygon, so it does not need to change location
return point;
}
// Get the closest point of the polygon
return closestPointOutsidePolygon(polygon, point);
}
// Check if the given point is within the given polygon (Vertexes)
//
// If so, call on collision if required, and move the point to the
// closest point outside of the polygon
public static boolean pointIsInPoly(Vector2[] verts, Vector2 p) {
int nvert = verts.length;
double[] vertx = new double[nvert];
double[] verty = new double[nvert];
for(int i = 0; i < nvert; i++) {
Vector2 vert = verts[i];
vertx[i] = vert.x;
verty[i] = vert.y;
}
double testx = p.x;
double testy = p.y;
int i, j;
boolean c = false;
for (i = 0, j = nvert-1; i < nvert; j = i++) {
if ( ((verty[i]>testy) != (verty[j]>testy)) &&
(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
c = !c;
}
return c;
}
// Gets the closed point that isn't inside the polygon...
public static Vector2 closestPointOutsidePolygon (Vector2[] poly, Vector2 point) {
return getClosestPointInSegment(closestSegment(poly, point), point);
}
public static Vector2 getClosestPointInSegment (Vector2[] segment, Vector2 point) {
return newPointFromCollision(segment[0], segment[1], point);
}
public static Vector2 newPointFromCollision (Vector2 aLine, Vector2 bLine, Vector2 p) {
return nearestPointOnLine(aLine.x, aLine.y, bLine.x, bLine.y, p.x, p.y);
}
public static Vector2 nearestPointOnLine(double ax, double ay, double bx, double by, double px, double py) {
// https://stackoverflow.com/questions/1459368/snap-point-to-a-line-java
double apx = px - ax;
double apy = py - ay;
double abx = bx - ax;
double aby = by - ay;
double ab2 = abx * abx + aby * aby;
double ap_ab = apx * abx + apy * aby;
double t = ap_ab / ab2;
if (t < 0) {
t = 0;
} else if (t > 1) {
t = 1;
}
return new Vector2(ax + abx * t, ay + aby * t);
}
public static Vector2[] closestSegment (Vector2[] points, Vector2 point) {
Vector2[] returns = new Vector2[2];
int index = closestPointIndex(points, point);
returns[0] = points[index];
Vector2[] neighbors = new Vector2[] {
points[(index+1+points.length)%points.length],
points[(index-1+points.length)%points.length]
};
double[] neighborAngles = new double[] {
getAngle(new Vector2[] {point, returns[0], neighbors[0]}),
getAngle(new Vector2[] {point, returns[0], neighbors[1]})
};
// The neighbor with the lower angle is the one to use
if(neighborAngles[0] < neighborAngles[1]) {
returns[1] = neighbors[0];
} else {
returns[1] = neighbors[1];
}
return returns;
}
public static double getAngle (Vector2[] abc) {
// https://stackoverflow.com/questions/1211212/how-to-calculate-an-angle-from-three-points
// atan2(P2.y - P1.y, P2.x - P1.x) - atan2(P3.y - P1.y, P3.x - P1.x)
return Math.atan2(abc[2].y - abc[0].y, abc[2].x - abc[0].x) - Math.atan2(abc[1].y - abc[0].y, abc[1].x - abc[0].x);
}
public static int closestPointIndex (Vector2[] points, Vector2 point) {
int leastDistanceIndex = 0;
double leastDistance = Double.MAX_VALUE;
for(int i = 0; i < points.length; i++) {
double dist = distance(points[i], point);
if(dist < leastDistance) {
leastDistanceIndex = i;
leastDistance = dist;
}
}
return leastDistanceIndex;
}
public static double distance (Vector2 a, Vector2 b) {
return Math.sqrt(Math.pow(Math.abs(a.x-b.x), 2)+Math.pow(Math.abs(a.y-b.y), 2));
}
}
Here's a small explanation (Fun Fact: This is the first image I posted to stack overflow!)
Sorry that it's so messy...
Step-by-Step of the class:
Check if the given point is within a polygon
If it isn't, return the current point as no changes are needed.
Find the closest VERTEX of the polygon
This is not the closest POINT, as a point can be between vertexes
Grab the two neighbors of the vertex, keeping the one with a lower angle.
The lower angle has lower distance than the higher angle because the higher angle "goes away" faster
Get the closest point of the line segment, using the answer to this question on StackOverflow.
Congrats! You survived the bad tutorial! Hopefully it helped :)
+ Thanks to all of the commented links to answers that helped me help you!
Snap Point to Line
How to calculate an angle from 3 points
Here is C# version of the answer #nathanfranke
using System;
using Windows.Foundation;
using Windows.UI.Xaml.Shapes;
using System.Numerics;
public class PolyCollisions
{
// Call this function...
public static Vector2 DoCollisions(Vector2[] polygon, Vector2 point)
{
if (!PointIsInPoly(polygon, point))
{
// The point is not colliding with the polygon, so it does not need to change location
return point;
}
// Get the closest point of the polygon
return ClosestPointOutsidePolygon(polygon, point);
}
// Check if the given point is within the given polygon (Vertexes)
//
// If so, call on collision if required, and move the point to the
// closest point outside of the polygon
public static bool PointIsInPoly(Vector2[] verts, Vector2 p)
{
int nvert = verts.Length;
double[] vertx = new double[nvert];
double[] verty = new double[nvert];
for (int d = 0; d < nvert; d++)
{
Vector2 vert = verts[d];
vertx[d] = vert.X;
verty[d] = vert.Y;
}
double testx = p.X;
double testy = p.Y;
int i, j;
bool c = false;
for (i = 0, j = nvert - 1; i < nvert; j = i++)
{
if (((verty[i] > testy) != (verty[j] > testy)) && (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
c = !c;
}
return c;
}
// Gets the closed point that isn't inside the polygon...
public static Vector2 ClosestPointOutsidePolygon(Vector2[] poly, Vector2 point)
{
return GetClosestPointInSegment(ClosestSegment(poly, point), point);
}
public static Vector2 GetClosestPointInSegment(Vector2[] segment, Vector2 point)
{
return NewPointFromCollision(segment[0], segment[1], point);
}
public static Vector2 NewPointFromCollision(Vector2 aLine, Vector2 bLine, Vector2 p)
{
return NearestPointOnLine(aLine.X, aLine.Y, bLine.X, bLine.Y, p.X, p.Y);
}
public static Vector2 NearestPointOnLine(double ax, double ay, double bx, double by, double px, double py)
{
// https://stackoverflow.com/questions/1459368/snap-point-to-a-line-java
double apx = px - ax;
double apy = py - ay;
double abx = bx - ax;
double aby = by - ay;
double ab2 = abx * abx + aby * aby;
double ap_ab = apx * abx + apy * aby;
double t = ap_ab / ab2;
if (t < 0)
{
t = 0;
}
else if (t > 1)
{
t = 1;
}
return new Vector2((float)(ax + (abx * t)), (float)(ay + aby * t));
}
public static Vector2[] ClosestSegment(Vector2[] points, Vector2 point)
{
Vector2[] returns = new Vector2[2];
int index = ClosestPointIndex(points, point);
returns[0] = points[index];
Vector2[] neighbors = new Vector2[] {
points[(index+1+points.Length)%points.Length],
points[(index-1+points.Length)%points.Length]
};
double[] neighborAngles = new double[] {
GetAngle(new Vector2[] {point, returns[0], neighbors[0]}),
GetAngle(new Vector2[] {point, returns[0], neighbors[1]})
};
// The neighbor with the lower angle is the one to use
if (neighborAngles[0] < neighborAngles[1])
{
returns[1] = neighbors[0];
}
else
{
returns[1] = neighbors[1];
}
return returns;
}
public static double GetAngle(Vector2[] abc)
{
// https://stackoverflow.com/questions/1211212/how-to-calculate-an-angle-from-three-points
// atan2(P2.y - P1.y, P2.x - P1.x) - atan2(P3.y - P1.y, P3.x - P1.x)
return Math.Atan2(abc[2].X - abc[0].Y, abc[2].X - abc[0].X) - Math.Atan2(abc[1].Y - abc[0].Y, abc[1].X - abc[0].X);
}
public static int ClosestPointIndex(Vector2[] points, Vector2 point)
{
int leastDistanceIndex = 0;
double leastDistance = Double.MaxValue;
for (int i = 0; i < points.Length; i++)
{
double dist = Distance(points[i], point);
if (dist < leastDistance)
{
leastDistanceIndex = i;
leastDistance = dist;
}
}
return leastDistanceIndex;
}
public static double Distance(Vector2 a, Vector2 b)
{
return Math.Sqrt(Math.Pow(Math.Abs(a.X - b.X), 2) + Math.Pow(Math.Abs(a.Y - b.Y), 2));
}
}

reading and writing an image simultaneously Processing

I'm generating probability tables for one color appearing to the right of another. I have accomplished all of this. I store the tables in objects which are created for each color value. My problem is, that when I generate a new image, I'd like to create pixel 0, then make a weighted random decision for the color that will appear to the right. I think my problem is that I'm trying to read data from image I'm constructing, and write to it in the same loop. I'm not sure how processing deals with this, and I seem to be getting strange errors, often, many of my pixels are black. I believe all of my problems are occurring the third time I loop through all of the pixels (lines 60-78), and try to write pixels to the new image.
you can see in the output of println statement the colors that should be written to the new image.
Is there something I'm missing?
This is the first time I've used classes and objects to code, so please forgive any clunkiness.
Thanks in advance for any help anyone can offer.
PImage src;
PImage dstn;
HashMap library;
int counter;
color d = (0);
color seed = (0);
color ds = (0);
void setup() {
library = new HashMap<Integer, Object>();
size(200, 200);
src = loadImage("sunflower.jpg");
dstn = createImage(src.width, src.height, RGB);
src.loadPixels();
int acc = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int loc = x + y*width;
color d = src.get(x,y); // get pixel color at desired location
if (library.containsKey(d)) {
// Get the AColor object and increase the count
// We access objects from the library via its key, the String
AColor c = (AColor) library.get(d);
c.count(); // touch the counter everytime the a color is read
c.the_color(d); // add the color to the object
//c.output();
} else {
// Otherwise make a new entry in library
AColor c = new AColor(d);
// And add to the library
// put() takes two arguments, "key" and "value"
// The key for us is the String and the value is the AColor object
library.put(d, c);
} // all colors are in library now
AColor c = (AColor) library.get(d);
if (x < width - 1 ) { //If statement to ensure null pixles are not added to transition matrix
color z = src.get(x+1,y);
c.access_matrix_right(z);
} else { // this is a nasty shortcut that wraps the probability of the rightmost pixel to the leftmost pixel
color z = src.get(x,y);
c.access_matrix_right(z);
}
}
}
}
void draw() {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
color d = src.get(x,y);
AColor c = (AColor) library.get(d);
c.sort_matrix(); // add and construct all of the ArrayLists for each object
println("first loop");
}
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int loc1 = ((x + y*width));
color seed = src.get(x,y);
dstn.pixels[0] = seed;
color ds = src.get(x,y); // copy pixel 0 from src to dstn image
AColor c = (AColor) library.get(ds);
float chance;
int acc = 0;
chance = random(1);
float probAccum = (c.probs.get(acc));
while (chance > probAccum) {
acc++;
probAccum = probAccum + (c.probs.get(acc));
int colorToTheRight = c.colors.get(acc);
dstn.pixels[loc1] = colorToTheRight; // <-If I put this outside of the while lopp, the image is more or less normal looking.
}
println(acc + " " + c.colors.get(acc) + " , " + c.colors + " - " + c.probs + " Chance = " + chance +" -color should be" + (c.colors.get(acc)));
dstn.updatePixels();
}
}
dstn.updatePixels();
image(dstn,0,0);
noLoop();
}
class AColor {
float count;
int theColor;
int colorRight;
int acc = 0;
int z;
HashMap<Object, Integer> matrix = new HashMap<Object, Integer>();
ArrayList<Float> probs;
ArrayList<Integer> colors = new ArrayList<Integer>(); //an ArrayList is used here. Perhaps it would be better to use an Array and iterate over the hashmap to set the length
AColor(int theColorTemp) {
theColor = theColorTemp;
count = 1;
}
void the_color(int theColorTemp) {
theColor = theColorTemp;
}
void count() {
count++;
}
void access_matrix_right(int colorRightTemp) {
colorRight = colorRightTemp;
if (matrix.containsKey(colorRight)) { // if library has entry for current pixel
int val = ((Integer) matrix.get(colorRight)).intValue(); //accumulator
matrix.put(colorRight, new Integer(val + 1)); // add 1 to
}
else {
matrix.put(colorRight,1); //adds entry & a value of 1 if entry does not exist
colors.add(colorRight);
}
}
void sort_matrix() {
probs = new ArrayList<Float>();
for (int i = 0; i <= colors.size()-1; i++) { //for number elements in list
probs.add((matrix.get(colors.get(i))) / count); // add element in array probs (number of occurrances of a color on the right/ total pixels on right )
}
}
}
Why not read all your pixels into a second image write to that, then write that back to the original one?
wouldn't something like this work? (untested)
int numPixelsX = 500;
int numPixelsY = 500;
PImage captureImage = createImage (numPixelsX,numPixelsY, ARGB);
void setup(){
size(500,500);
}
void draw(){
captureImage.loadPixels();
captureImage = pushPixels(captureImage);
captureImage.updatePixels();
image(captureImage, 0, 0);
}
PImage pushPixels(PImage readImage){
PImage writeImage = createImage(numPixelsX,numPixelsY,ARGB);
writeImage.loadPixels();
writeImage = readImage();
//do your stuff here from the read image to the write image
writeImage.updatePixels();
return writeImage;
}

Resources