I have to make a pyramid that can have its parameters changed, but my code keeps not allowing the next row after to start at the proper point, I need help! I'm sorry if its messy, I'm very new. picture at bottom is result. I need it to be centered.
public class Pyramid2 {
public static void main(String[] args) {
Turtle t = new Turtle();
t.delay(100);
pyramid(t, 200, 5);
}
public static void square(Turtle t, double base, int levels) {
for (int i = 0; i < 4; i++) {
t.forward(base / ((levels * 2) - 1));
t.left(90);
}
}
public static void pyramid(Turtle t, double base, int levels) {
//for (int p = 1; (p-1)< levels; p++){
for (int j = 0; j < levels; j++) {
for (int i = 0; i < ((levels) * 2) - (j * 2) - 1; i++) {
square(t, base, levels);
t.forward(base / ((levels * 2) - 1));
}
t.penup();
t.left(90);
t.forward(base / ((levels * 2) - 1));
t.right(90);
t.backward(base - (base / (((levels * 2) - (j * 2)) - 1)));
t.pendown();
}
}
}
what I get
I couldn't figure out how to set up a turtle Java environment (link to a guide in the comments would be appreciated!), but the basic algorithm is pretty much language-agnostic. I'll use JavaScript with var so it should be compatible with Java 10+.
I'm not sure if your turtle has goto, but if it does, that makes rewinding to the left side of the canvas to prepare the next row easier. I'll assume you don't have this and only use forward, right, pendown and penup commands.
My approach is this:
Set size and levels constants which represent the box/grid size and number of levels, respectively. (If you want to use base, fine--compute size = base / (levels * 2 - 1) as you've already done, but save it in a variable).
Start from the top level
For each level i:
Compute the number of boxes for the level: boxes = i * 2 + 1
Compute the left x-offset to start drawing boxes from: offset = (levels - i - 1) * size
Move forward offset pixels
Draw the boxes for the level
Move to the beginning of the next line and point rightward (goto(0, turtle.y + size) would be handy here to avoid some maneuvering)
Here's the code:
var size = 20;
var levels = 5;
var t = new Turtle();
t.penup();
for (var i = 0; i < levels; i++) {
var boxes = i * 2 + 1;
var offset = (levels - i - 1) * size;
t.forward(offset);
t.pendown();
for (var j = 0; j < boxes; j++) {
for (var k = 0; k < 4; k++) {
t.forward(size);
t.right(90);
}
t.forward(size);
}
t.penup();
t.right(90);
t.forward(size);
t.right(90);
t.forward(offset + size * boxes);
t.right(180);
}
///////////////////////////////////////
// turtle library; ignore code below //
function Turtle() {
const rad = d => d * Math.PI / 180;
const canvas = document.querySelector("#turtle-pond");
canvas.width = innerWidth;
canvas.height = innerHeight;
const ctx = canvas.getContext("2d");
ctx.translate(0.5, 0.5);
let x = 0, y = 0, angle = 0;
let penDown = true;
return {
pendown() {
penDown = true;
},
penup() {
penDown = false;
},
forward(dist) {
if (penDown) {
ctx.beginPath();
ctx.moveTo(x, y);
}
x += Math.cos(rad(angle)) * dist;
y += Math.sin(rad(angle)) * dist;
if (penDown) {
ctx.lineTo(x, y);
ctx.stroke();
}
},
right(ang) {
angle += ang;
},
left(ang) {
angle -= ang;
},
};
}
<canvas id="turtle-pond"></canvas>
Related
I was beginning with coding in Processing when I encountered an error which I can't find a solution for.
**DISCLAIMER: I'm new to coding, so I'm having trouble understanding how it works lol
I was attempting to use processing to write a code for a kinect program that would create a ripple effect, but I can't figure out how to define two variables.
Code:
// A simple ripple effect. Click on the image to produce a ripple
// Author: radio79
// Code adapted from http://www.neilwallis.com/java/water.html
// Code adapted from https://forum.processing.org/two/discussion/25348/can-i-apply-ripple-effect-to-kinect
import org.openkinect.processing.*;
Kinect kinect;
PImage img;
Ripple ripple;
void setup() {
size(1920, 1080);
kinect = new Kinect(this);
kinect.initVideo();
img = new PImage(kinect.colorWidth, kinect.colorHeight);
ripple = new Ripple();
//frameRate(60);
}
void draw() {
image(kinect.getVideoImage(), 0, 0);
img.loadPixels();
for (int loc = 0; loc < Kinect.colorWidth * Kinect.colorHeight; loc++) {
img.pixels[loc] = ripple.col[loc];
}
img.updatePixels();
ripple.newframe();
}
class Ripple {
int i, a, b;
int oldind, newind, mapind;
short ripplemap[]; // the height map
int col[]; // the actual pixels
int riprad;
int rwidth, rheight;
int ttexture[];
int ssize;
Ripple() {
// constructor
riprad = 3;
rwidth = width >> 1;
rheight = height >> 1;
ssize = width * (height + 2) * 2;
ripplemap = new short[ssize];
col = new int[width * height];
ttexture = new int[width * height];
oldind = width;
newind = width * (height + 3);
}
void newframe() {
// update the height map and the image
i = oldind;
oldind = newind;
newind = i;
i = 0;
mapind = oldind;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
short data = (short)((ripplemap[mapind - width] + ripplemap[mapind + width] +
ripplemap[mapind - 1] + ripplemap[mapind + 1]) >> 1);
data -= ripplemap[newind + i];
data -= data >> 5;
if (x == 0 || y == 0) // avoid the wraparound effect
ripplemap[newind + i] = 0;
else
ripplemap[newind + i] = data;
// where data = 0 then still, where data > 0 then wave
data = (short)(1024 - data);
// offsets
a = ((x - rwidth) * data / 1024) + rwidth;
b = ((y - rheight) * data / 1024) + rheight;
//bounds check
if (a >= width)
a = width - 1;
if (a < 0)
a = 0;
if (b >= height)
b = height-1;
if (b < 0)
b=0;
col[i] = img.pixels[a + (b * width)];
mapind++;
i++;
}
}
}
}
void mouseDragged() {
for (int j = mouseY - ripple.riprad; j < mouseY + ripple.riprad; j++) {
for (int k = mouseX - ripple.riprad; k < mouseX + ripple.riprad; k++) {
if (j >= 0 && j < height && k>= 0 && k < width) {
ripple.ripplemap[ripple.oldind + (j * width) + k] += 512;
}
}
}
}
The error is: 'The global variable "x" does not exist', 'The global variable "y" does not exist' and so forth. Please help.
The variables I need help defining appear on line 18 for the first time, they are colorWidth and colorHeight
The line reads:
img = new PImage(kinect.colorWidth, kinect.colorHeight);
The colorWidth and colorHeight are underlined in red.
I have tried using this method:
public
float colorWidth;
float colorHeight;
But, only the second line appears to be defined properly. The first line emits the message "colorWidth cannot be resolved or is not a field" when the program runs, or "illegal modifier for parameter colorWidth; only final is permitted" when the underline is clicked.
Picture of what the program shows after the public code
PLEASE HELP!!! Thank you!
The keyword public here just means nothing, it must be said of a function or variable. And you just don't need it. So removing it should fix the problem!
I'm trying to get my code to recreate a random x and y value if there is already another object occupying the chosen value. But for some reason, the loop just keeps giving me the same float value causing it to loop forever instead of creating new value and then checking that one against previous x and y variables. Here's the code. Let me know if you need anymore.
static int numberOfDots = 5;
static int windowSize = 400;
float[] pos = new float[2];
float[] vel = new float[2];
float[] acc = new float[2];
float dotSize = 0;
float dotMass = 0;
float dotWidth = 0;
float dotRadius = 0;
float[] centrePos = new float[2];
float[][] dots = new float[numberOfDots][10];
//for making dots
boolean first = true;
boolean creationCollision = false;
boolean dotCollision = false;
// pos means x and y positions
// vel means x and y velocity
// centrePos means centre of the dot x and y
// dotMass isnt implemented yet
public boolean collisionOnCreate() {
//compare all dots
for (int i = 0; i < dots.length; i++) {
//against any dots later in the array
// since they will already have compared themselves to dots previous in the array
// - dont need to loop over them again
for (int a = i + 1; a < dots.length; a++) {
if (dots[a][0] != 0) {
creationCollision = dots[i][1] + dots[i][8] > dots[a][1] && dots[i][1] + dots[i][8] < dots[a][1] + dots[a][8] || dots[i][1] > dots[a][1] && dots[i][1] < dots[a][1] + dots[a][8] || dots[i][0] > dots[a][0] && dots[i][0] < dots[a][0] + dots[a][8] || dots[i][0] + dots[i][8] > dots[a][0] && dots[i][0] + dots[i][8] < dots[a][0] + dots[a][8];
System.out.println(dots[a][0] + " " + dots[a][1]);
}
//check if the left-most part of the dot is anywhere between the leftmost and right most part of another dot
//check if the rightmost part of the dot is anywhere between the left most and right most part of another dot
//check if the top part of the dot is anywhere between the top and bottom part of another dot
//check if the bottom of the dot is anywhere between the top and bottom part of another dot
// I know its long but its easier then running a bunch of if statements to do the same task
}
}
return creationCollision;
}
public void createDots(int i) {
pos[0] = r.nextFloat() * 300;
pos[1] = r.nextFloat() * 300;
dotWidth = r.nextFloat() * 30;
if (dotWidth < 5) {
dotWidth *= 10;
}
dotRadius = dotWidth / 2;
dotMass = r.nextFloat() / 10;
centrePos[0] = centrePos[0] + dotRadius;
centrePos[1] = pos[1] + dotRadius;
vel[0] = r.nextFloat() / 10;
vel[1] = r.nextFloat() / 10;
check(i);
}
public void check(int i) {
collisionOnCreate();
if (creationCollision) {
createDots(i);
System.out.println("collision on creation");
} else {
setValues(i);
System.out.println("dot number " + i + " is created");
}
}
public void setValues(int i) {
dots[i][0] = pos[0];
dots[i][1] = pos[1];
dots[i][2] = vel[0];
dots[i][3] = vel[1];
dots[i][4] = dotRadius;
dots[i][5] = centrePos[0];
dots[i][6] = centrePos[1];
dots[i][7] = dotMass;
dots[i][8] = dotWidth;
}
//create an array of dots and assign them values for x, y, radius, etc.
public float[][] Dots() {
if (first == true) {
for (int i = 0; i < numberOfDots; i++) {
createDots(i);
}
first = false;
} else {
for (int i = 0; i < numberOfDots; i++) {
// update values
dots[i][0] = dots[i][0] + dots[i][2];
dots[i][1] = dots[i][1] + dots[i][3];
centrePos[0] = dots[i][0] + dots[i][4];
centrePos[1] = dots[i][1] + dots[i][4];
dots[i][5] = centrePos[0];
dots[i][6] = centrePos[1];
collisionOnWall(i);
}
}
repaint();
return dots;
}
I don't think the problem is with random number generation. Instead there is something wrong with the logic of creation / checking.
It seems that first, inside of createDots(), you assign values to some variables that are meant to represent a new dot (why don't make a dedicated class for that?). Then you don't add that new dot to dots array but instead you go straight to checking if there are any collisions.
However, you only check the values that are already present in the dots array, without taking into account the newly created one.
Another thing, that creationCollision condition is really unreadable to me. You should use some parentheses just for the clarity. Plus make sure it is actually doing what you want it to.
You don't appear to ever set dots[i] to your new values here:
public void createDots(int i) {
pos[0] = r.nextFloat() * 300;
pos[1] = r.nextFloat() * 300;
dotWidth = r.nextFloat() * 30;
if (dotWidth < 5) {
dotWidth *= 10;
}
dotRadius = dotWidth / 2;
dotMass = r.nextFloat() / 10;
centrePos[0] = centrePos[0] + dotRadius;
centrePos[1] = pos[1] + dotRadius;
vel[0] = r.nextFloat() / 10;
vel[1] = r.nextFloat() / 10;
check(i);
}
Looks like you want to call setValues(i) at the end, just before check(i).
I am trying to make Space Invaders in Processing. I am currently working on getting the enemy to move correctly. I have got them to be drawn in the right spot but I haven't gotten them to be moved correctly. Here is my code:
PImage mainPlayer;
PImage enemyPlayer;
float Xspeed = 60;
float Yspeed = 60;
float X;
float Y;
Enemy EnemyPlayer = new Enemy("EnemyPlayerSpaceInvaders.png", 10, 10, 6);
void setup() {
size(1400, 800);
//enemyPlayer = loadImage("EnemyPlayerSpaceInvaders.png");
mainPlayer = loadImage("MainPlayerSpaceInvaders.png");
}
void draw() {
background(0);
Enemy[] enemyPlayer = new Enemy[60];
for (int i = 0; i < 5; i += 1) {
for (int j = 0; j < 11; j += 1) {
enemyPlayer[j *i] = new Enemy("EnemyPlayerSpaceInvaders.png", 50 + j * 100, 5 + 75 * i, 6);
}
}
for (int i = 0; i < 5; i += 1) {
for (int j = 0; j < 11; j += 1) {
if(enemyPlayer[j * i].alive){
enemyPlayer[j * i].Draw();
}
enemyPlayer[j *i].moveAndDraw(6);
}
}
}
class Enemy {
boolean alive = true;
float x;
float y;
float speed;
String playerTexFile;
PImage playerTex;
Enemy(String PlayerTexFile, float X, float Y, float Speed){
x = X;
y = Y;
speed = Speed;
playerTexFile = PlayerTexFile;
}
void Draw(){
playerTex = loadImage(playerTexFile);
image(playerTex, x, y);
}
void moveAndDraw(float Speed){
playerTex = loadImage(playerTexFile);
if(alive){
x += Speed;
if (x >= 1300) {
x = 100;
y += 50;
}
}
}
}
Here is my result:
The Draw function works but what you're seeing that is messing it up is the moveAndDraw() function.
And the enemy drawings aren't moving. I have made this before with c++ SFML but in that there is a very basic getPosition function. The reason I want to get position is that right now I'm having to use inaccurate numbers as the X and Y position and for the enemy to move correctly I need to know exactly what it's position is. I have checked multiple pages on processing.org but none of them helped. I haven't found any getPosition void and all the ones I've seen other people using a void to do this I just haven't been able to get it to work. If there is some code that could get me this to work or just some function I've looked over and even a website page I could look at I'd be open to it. Please tell me anything I can do to get this working.
The issue is that you recreate the enemies in every frame at it's initial position:
void draw() {
background(0);
Enemy[] enemyPlayer = new Enemy[60];
for (int i = 0; i < 5; i += 1) {
for (int j = 0; j < 11; j += 1) {
enemyPlayer[j *i] = new Enemy("EnemyPlayerSpaceInvaders.png", 50 + j * 100, 5 + 75 * i, 6);
}
}
// [...]
}
You've to:
Create a global array of enemies Enemy[] enemyPlayer (and delete PImage enemyPlayer).
Create and initialize the enemies in setup.
Use and move the existing enemies in draw:
Further note, that your loops doesn't do what you expect it to do. Create the enemies in 2 nested loops. If i runs from o to 6 and j from 0 to 10, the the index of an enemy is i*10 + j.
The enemies can be moved in a single loop from 0 to enemyPlayer.length.
//PImage enemyPlayer; <--- DELETE
// global array of enemies
Enemy[] enemyPlayer = new Enemy[60];
// [...]
void setup() {
size(1400, 800);
mainPlayer = loadImage("MainPlayerSpaceInvaders.png");
// create enemies
for (int i = 0; i < 6; i += 1) {
for (int j = 0; j < 10; j += 1) {
enemyPlayer[i*10 + j] = new Enemy("rocket64.png", 50 + j * 100, 5 + 75 * i, 6);
}
}
}
void draw() {
background(0);
// move enemies
for(int i = 0; i < enemyPlayer.length; ++i ) {
if(enemyPlayer[i].alive){
enemyPlayer[i].Draw();
}
enemyPlayer[i].moveAndDraw(6);
}
}
My perceptron doesn't find the right y-intercept even though I added a bias. The slope is correct. This is my second try coding a perceptron from scratch and I got the same error twice.
The perceptron evaluates if a point on a canvas is higher or lower than the interception line. The inputs are the x-coordinate, y-coordinate and 1 for the bias.
Perceptron class:
class Perceptron
{
float[] weights;
Perceptron(int layerSize)
{
weights = new float[layerSize];
for (int i = 0; i < layerSize; i++)
{
weights[i] = random(-1.0,1.0);
}
}
float Evaluate(float[] input)
{
float sum = 0;
for (int i = 0; i < weights.length; i++)
{
sum += weights[i] * input[i];
}
return sum;
}
float Learn(float[] input, int expected)
{
float guess = Evaluate(input);
float error = expected - guess;
for (int i = 0; i < weights.length; i++)
{
weights[i] += error * input[i] * 0.01;
}
return guess;
}
}
This is the testing code:
PVector[] points;
float m = 1; // y = mx+q (in canvas space)
float q = 0; //
Perceptron brain;
void setup()
{
size(600,600);
points = new PVector[100];
for (int i = 0; i < points.length; i++)
{
points[i] = new PVector(random(0,width),random(0,height));
}
brain = new Perceptron(3);
}
void draw()
{
background(255);
DrawGraph();
DrawPoints();
//noLoop();
}
void DrawPoints()
{
for (int i = 0; i < points.length; i++)
{
float[] input = new float[] {points[i].x / width, points[i].y / height, 1};
int expected = ((m * points[i].x + q) < points[i].y) ? 1 : 0; // is point above line
float output = brain.Learn(input, expected);
fill(sign(output) * 255);
stroke(expected*255,100,100);
strokeWeight(3);
ellipse(points[i].x, points[i].y, 20, 20);
}
}
int sign(float x)
{
return x >= 0 ? 1 : 0;
}
void DrawGraph()
{
float y1 = 0 * m + q;
float y2 = width * m + q;
stroke(255,100,100);
strokeWeight(3);
line(0,y1,width,y2);
}
I found the problem
float guess = Evaluate(input);
float error = expected - guess;
should be
float guess = sign(Evaluate(input));
float error = expected - guess;
The output was never exactly one ore zero even if the answer would be correct. Because of this even the correct points gave a small error that stopped the perceptron from finding the right answer. By calculating the sign of the answer first the error is 0 if the answer is correct.
I am making and auto clicker using java.awt.Robot. One of the concerns i have however is the movements aren't very humanlike. Can anyone suggest some changes to my code to make it more human like? Right now it just moves in a straight line.
/**
*
* #param robot The java.awt.Robot being utilized
* #param sx The start x position of the mouse
* #param sy The start y potition of the mouse
* #param ex The end x position of the mouse
* #param ey The end y position of the mouse
* #param speed The speed at which to travel
*/
public void moveMouse(Robot robot, int sx, int sy, int ex, int ey, int speed){
for (int i=0; i<100; i++){
int mov_x = ((ex * i)/100) + (sx*(100-i)/100);
int mov_y = ((ey * i)/100) + (sy*(100-i)/100);
robot.mouseMove(mov_x,mov_y);
robot.delay(speed);
}
}
Update:
I decided to go with an algorithm that makes use of Bézier Curves. It's been a very long time since I implemented the change, but I wanted to post it here just in case people would find it useful in the future. Here is what I ended up with:
public class MouseEvent{
public int getMouseX(){
return MouseInfo.getPointerInfo().getLocation().x;
}
public int getMouseY(){
return MouseInfo.getPointerInfo().getLocation().y;
}
public void moveMouse(int speed, int destX, int destY, int ranX, int ranY){
Mouse.moveMouse(new Robot(), new Point(getMouseX(),getMouseY()), new Point(destX, destY), speed, ranX, ranY);
}
}
public class Mouse {
public static void moveMouse(Robot robot, Point s, Point e, int speed, int ranX, int ranY){
if(Math.abs(e.x-s.x) <= ranX && Math.abs(e.y-s.y) <= ranY)
return;
Point[] cooardList;
double t; //the time interval
double k = .025;
cooardList = new Point[4];
//set the beginning and end points
cooardList[0] = s;
cooardList[3] = new Point(e.x+random(-ranX,ranX),e.y+(random(-ranY,ranY)));
int xout = (int)(Math.abs(e.x - s.x) /10);
int yout = (int)(Math.abs(e.y - s.y) /10);
int x=0,y=0;
x = s.x < e.x
? s.x + ((xout > 0) ? random(1,xout) : 1)
: s.x - ((xout > 0) ? random(1,xout) : 1);
y = s.y < e.y
? s.y + ((yout > 0) ? random(1,yout) : 1)
: s.y - ((yout > 0) ? random(1,yout) : 1);
cooardList[1] = new Point(x,y);
x = e.x < s.x
? e.x + ((xout > 0) ? random(1,xout) : 1)
: e.x - ((xout > 0) ? random(1,xout) : 1);
y = e.y < s.y
? e.y + ((yout > 0) ? random(1,yout) : 1)
: e.y - ((yout > 0) ? random(1,yout) : 1);
cooardList[2] = new Point(x,y);
double px = 0,py = 0;
for(t=k;t<=1+k;t+=k){
//use Berstein polynomials
px=(cooardList[0].x+t*(-cooardList[0].x*3+t*(3*cooardList[0].x-
cooardList[0].x*t)))+t*(3*cooardList[1].x+t*(-6*cooardList[1].x+
cooardList[1].x*3*t))+t*t*(cooardList[2].x*3-cooardList[2].x*3*t)+
cooardList[3].x*t*t*t;
py=(cooardList[0].y+t*(-cooardList[0].y*3+t*(3*cooardList[0].y-
cooardList[0].y*t)))+t*(3*cooardList[1].y+t*(-6*cooardList[1].y+
cooardList[1].y*3*t))+t*t*(cooardList[2].y*3-cooardList[2].y*3*t)+
cooardList[3].y*t*t*t;
robot.mouseMove((int)px, (int)py);
robot.delay(random(speed,speed*2));
}
}
}
public void moveMouse(int sx, int sy, int ex, int ey, int speed) throws AWTException {
Robot robot = new Robot();
int a = 10;
boolean flag = true;
for (int i = 0; i < 100; i++) {
int mov_x = ((ex * i) / 100) + (sx * (100 - i) / 100);
int mov_y = ((ey * i) / 100) + (sy * (100 - i) / 100);
if (flag == true) {
robot.mouseMove(mov_x + a, mov_y); // adds 10 to X-axis
flag = false;
} else {
robot.mouseMove(mov_x - 2 * a, mov_y); // subtracts 20 to X-axis
flag = true;
}
robot.delay(speed);
}
}
Just manipulated your code. This moves the mouse in straight path in X-direction. You can achieve what you want from here. Just get the ideas. You can move any way you want if you can manipulate mov_x and mov_y .
You could use Catmull-Rom method. Generate random controlpoints somewhere around the endpoints and maybe where the straight line would be, asking for coordinates on every step moving from start to end (parameter t, from zero to one).
See demo applets and source: http://www.cse.unsw.edu.au/~lambert/splines/