I am trying to make a circle with the following code. I just cant figure out what values I need to change in order to create it. Appreciate any help.
void setup() {
size(400, 400);
background(255,255,255);
}
void draw() {
float step=(2*PI)/120;
float theta_start=0;
float old_sx=map(theta_start,0,2*PI,4,width-4);
float old_sy1=map(sin(theta_start),-1,1,height-4,4);
float old_sy2=map(cos(theta_start),0,1*PI,1,width-2);
for(float theta=step;theta<=(2*PI)+step;theta+=step)
{
float screen_x=map(theta,0,2*PI,4,width-4);
float screen_y1=map(sin(theta),-1,1,height-4,4);
float screen_y2=map(cos(theta),0,1*PI,1,width-2);
//stroke(255,0,0);
//line(old_sx,old_sy1,screen_x,screen_y1);
//stroke(0,255,0);
// line(old_sx,old_sy2,screen_x,screen_y2);
stroke(0,0,255);
line(old_sy1,old_sy2,screen_y1,screen_y2);
old_sx=screen_x;
old_sy1=screen_y1;
old_sy2=screen_y2;
}
}
A circle with radius 1 can be defined as all points (x,y), that are located at
(sin(theta), cos(theta))
for all 0<=theta<2*PI.
In order to change the radius, simply alter it to
(radius * sin(theta), radius * cos(theta)).
Finally, if you want to change the center of the radius to a position (posX, posY), just add these:
(radius * sin(theta) + posX, radius * cos(theta) + posY)
void setup()
{
size(400, 400);
background(255,255,255);
}
void draw()
{
float step=(2*PI)/120;
int posX = width/2;
int posY = height/2;
float radius = 100;
int xOld=0, yOld=0;
for(float theta=0;theta<=(2*PI)+step;theta+=step)
{
stroke(0,0,255);
int x = int(radius*sin(theta) + posX);
int y = int(radius*cos(theta) + posY);
if(theta>0)
{
line(x,y,xOld,yOld);
}
xOld = x;
yOld = y;
}
}
Related
I have several buttons that I created like this:
In the setup()
PImage[] imgs1 = {loadImage("AREA1_1.png"),loadImage("AREA1_2.png"),loadImage("AREA1_3.png")};
cp5.addButton("AREA_1") // The button
.setValue(128)
.setPosition(-60,7) // x and y relative to the group
.setImages(imgs1)
.updateSize()
.moveTo(AreaRingGroup); // add it to the group
;
After draw()
void AREA_1(){
println("AREA_1");
if (port != null){
port.write("a\n");
}
Now, I have to add about 24 small buttons from images that are going to be seen as 1 circle. But instead of adding them using cp5.addButton like above, I thought I should create a class.
I want to extend the existing CP5 button class because I want to be able to reach the cp5 parameters; like using .setImages() for 3 mouseClick conditions in the button images.
My problem is, I couldn't figure out
How to extend the CP5 button class, so that I can use angles (since I want to place buttons in a circular way) instead of giving x,y positions.
How to use serial port writings using this class, like the above void (AREA_1) example.
Here is my silly attempt:
class myButton extends Button
{
myButton(ControlP5 cp5, String theName)
{
super(cp5, cp5.getTab("default"), theName, 0,0,0, autoWidth, autoHeight);
}
PVector pos = new PVector (0,0);
PVector center = new PVector(500,500);
PImage[] img = new PImage[3];
String lable;
int sizeX = 10, sizeY=10;
color imgColor;
Boolean pressed = false;
Boolean clicked = false;
//Constructor
myButton(float a, String theName)
{
//Angle between the center I determined and the position of the
button.
a = degrees (PVector.angleBetween(center, pos));
//Every button will have 3 images for the 3 mouseClick conditions.
for (int i = 0; i < 2; ++i)
(img[i] = loadImage(lable + i + ".png")).resize(sizeX, sizeY);
}
}
Laancelot's idea isn't bad, however, due to controlP5's OOP architecture it might not be possible, or at least trivial, to extend the controlP5's Button class to achieve your goal from a controlP5 sketch.
I'm making the assumption this is connected to other LED ring related questions you posted around this time (such as this one).
It might be wrong (and I'd be interested in seeing a solution), but without forking/modifying the controlP5 library itself, the inheritance chain gets a bit tricky.
Ideally you'd just need to extend Button and be done with it, however the method used to tell states (if a button over/pressed/etc.) is the Controller superclass's inside() method. To work with your image you'd need override this method to and swap the logic so it takes into account the alpha transparency of your png button skin (e.g. if the pixel under the cursor is opaque then it's inside otherwise it's not)
Here's a rough illustration you were constrained to using a Processing sketch:
public abstract class CustomController< T > extends Controller< T> {
public CustomController( ControlP5 theControlP5 , String theName ) {
super( theControlP5 , theControlP5.getDefaultTab( ) , theName , 0 , 0 , autoWidth , autoHeight );
theControlP5.register( theControlP5.papplet , theName , this );
}
protected CustomController( final ControlP5 theControlP5 , final ControllerGroup< ? > theParent , final String theName , final float theX , final float theY , final int theWidth , final int theHeight ) {
super(theControlP5, theParent, theName, theX, theY, theWidth, theHeight);
}
boolean inside( ) {
/* constrain the bounds of the controller to the dimensions of the cp5 area, required since PGraphics as render
* area has been introduced. */
//float x0 = PApplet.max( 0 , x( position ) + x( _myParent.getAbsolutePosition( ) ) );
//float x1 = PApplet.min( cp5.pgw , x( position ) + x( _myParent.getAbsolutePosition( ) ) + getWidth( ) );
//float y0 = PApplet.max( 0 , y( position ) + y( _myParent.getAbsolutePosition( ) ) );
//float y1 = PApplet.min( cp5.pgh , y( position ) + y( _myParent.getAbsolutePosition( ) ) + getHeight( ) );
//return ( _myControlWindow.mouseX > x0 && _myControlWindow.mouseX < x1 && _myControlWindow.mouseY > y0 && _myControlWindow.mouseY < y1 );
// FIXME: add alpha pixel logic here
return true;
}
}
public class CustomButton<Button> extends CustomController< Button > {
protected CustomButton( ControlP5 theControlP5 , ControllerGroup< ? > theParent , String theName , float theDefaultValue , int theX , int theY , int theWidth , int theHeight ) {
super( theControlP5 , theParent , theName , theX , theY , theWidth , theHeight );
_myValue = theDefaultValue;
_myCaptionLabel.align( CENTER , CENTER );
}
// isn't this fun ?
//public CustomButton setImage( PImage theImage ) {
// return super.setImage( theImage , DEFAULT );
//}
}
I would suggest a simpler workaround: simply add smaller buttons in a ring layout (using polar to cartesian coordinate conversion):
import controlP5.*;
ControlP5 cp5;
void setup(){
size(600, 600);
background(0);
cp5 = new ControlP5(this);
int numLEDs = 24;
float radius = 240;
for(int i = 0; i < numLEDs; i++){
float angle = (TWO_PI / numLEDs * i) - HALF_PI;
cp5.addButton(nf(i, 2))
.setPosition(width * 0.5 + cos(angle) * radius, height * 0.5 + sin(angle) * radius)
.setSize(30, 30);
}
}
void draw(){}
Sure, not as pretty, but much much simpler.
Hopefully rendering the ring image drawn behind as a background and changing the button colour might be enough to get the point across.
It might be simpler to skip ControlP5 altogether and make your own button class for such a custom behaviour.
Let's say you want to have a square button in a ring layout that also rotates along the ring. This rotation will make checking the bounds tricker, but not impossible. You could hold track of the button's 2D transformation matrix using PMatrix2D) to render the button, but use the inverse of this transformation matrix to convert between Processing's global coordinate system to the button's local coordinate system. This would make checking if the button hovered trivial again (as the mouse converted to local coordinates would be within the button's bounding box). Here's an example:
TButton btn;
void setup(){
size(600, 600);
btn = new TButton(0, 300, 300, 90, 90, radians(45));
}
void draw(){
background(0);
btn.update(mouseX, mouseY, mousePressed);
btn.draw();
}
class TButton{
PMatrix2D transform = new PMatrix2D();
PMatrix2D inverseTransform;
int index;
int x, y, w, h;
float angle;
boolean isOver;
boolean isPressed;
PVector cursorGlobal = new PVector();
PVector cursorLocal = new PVector();
color fillOver = color(192);
color fillOut = color(255);
color fillOn = color(127);
TButton(int index, int x, int y, int w, int h, float angle){
this.index = index;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.angle = angle;
transform.translate(x, y);
transform.rotate(angle);
inverseTransform = transform.get();
inverseTransform.invert();
}
void update(int mx, int my, boolean mPressed){
cursorGlobal.set(mx, my);
inverseTransform.mult(cursorGlobal, cursorLocal);
isOver = ((cursorLocal.x >= 0 && cursorLocal.x <= w) &&
(cursorLocal.y >= 0 && cursorLocal.y <= h));
isPressed = mPressed && isOver;
}
void draw(){
pushMatrix();
applyMatrix(transform);
pushStyle();
if(isOver) fill(fillOver);
if(isPressed) fill(fillOn);
rect(0, 0, w, h);
popStyle();
popMatrix();
}
}
If you can draw one button, you can draw many buttons, in a ring layout:
int numLEDs = 24;
TButton[] ring = new TButton[numLEDs];
TButton selectedLED;
void setup(){
size(600, 600);
float radius = 240;
float ledSize= 30;
float offsetX = width * 0.5;
float offsetY = height * 0.5;
for(int i = 0 ; i < numLEDs; i++){
float angle = (TWO_PI / numLEDs * i) - HALF_PI;
float x = offsetX + (cos(angle) * radius);
float y = offsetY + (sin(angle) * radius);
ring[i] = new TButton(i, x, y, ledSize, ledSize, angle);
}
println("click to select");
println("click and drag to change colour");
}
void draw(){
background(0);
for(int i = 0 ; i < numLEDs; i++){
ring[i].update(mouseX, mouseY);
ring[i].draw();
}
}
void onButtonClicked(TButton button){
selectedLED = button;
println("selected", selectedLED);
}
void mouseReleased(){
for(int i = 0 ; i < numLEDs; i++){
ring[i].mouseReleased();
}
}
void mouseDragged(){
if(selectedLED != null){
float r = map(mouseX, 0, width, 0, 255);
float g = map(mouseY, 0, height, 0, 255);
float b = 255 - r;
selectedLED.fillColor = color(r, g, b);
}
}
class TButton{
PMatrix2D transform = new PMatrix2D();
PMatrix2D inverseTransform;
int index;
float x, y, w, h;
float angle;
boolean isOver;
PVector cursorGlobal = new PVector();
PVector cursorLocal = new PVector();
color fillColor = color(255);
TButton(int index, float x, float y, float w, float h, float angle){
this.index = index;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.angle = angle;
transform.translate(x, y);
transform.rotate(angle);
inverseTransform = transform.get();
inverseTransform.invert();
}
void update(int mx, int my){
cursorGlobal.set(mx, my);
inverseTransform.mult(cursorGlobal, cursorLocal);
isOver = ((cursorLocal.x >= 0 && cursorLocal.x <= w) &&
(cursorLocal.y >= 0 && cursorLocal.y <= h));
}
void mouseReleased(){
if(isOver) onButtonClicked(this);
}
void draw(){
pushMatrix();
applyMatrix(transform);
pushStyle();
if(isOver) {
fill(red(fillColor) * .5, green(fillColor) * .5, blue(fillColor) * .5);
}else{
fill(fillColor);
}
rect(0, 0, w, h);
popStyle();
popMatrix();
}
String toString(){
return "[TButton index=" + index + "]";
}
}
This isn't bad, but it easily gets complicated, right ?
What is you apply a global transformation in draw(): that may need to be handled by the button ? What if the button is nested in a bunch of pushMatrix()/popMatrix() calls when .draw() is called ? etc...
Could this be simpler ? Sure, the LEDs appear as rotated squares on a ring layout, however the important part that lights up is circular in shape. A rotated circle looks the same regardless of the angle. Checking if the mouse is over is trivial, as you can see in the Processing RollOver example : simply check if the distance between a circle's position and the cursor is smaller than the circle's radius.
Here's an example using circular buttons (removing the need for handling coordinate space transformations):
int numLEDs = 24;
CButton[] ring = new CButton[numLEDs];
CButton selectedLED;
void setup(){
size(600, 600);
float radius = 240;
float ledSize= 30;
float offsetX = width * 0.5;
float offsetY = height * 0.5;
for(int i = 0 ; i < numLEDs; i++){
float angle = (TWO_PI / numLEDs * i) - HALF_PI;
float x = offsetX + (cos(angle) * radius);
float y = offsetY + (sin(angle) * radius);
ring[i] = new CButton(i, x, y, ledSize);
}
println("click to select");
println("click and drag to change colour");
}
void draw(){
background(0);
for(int i = 0 ; i < numLEDs; i++){
ring[i].update(mouseX, mouseY);
ring[i].draw();
}
}
void onButtonClicked(CButton button){
selectedLED = button;
println("selected", selectedLED);
}
void mouseReleased(){
for(int i = 0 ; i < numLEDs; i++){
ring[i].mouseReleased();
}
}
void mouseDragged(){
if(selectedLED != null){
float r = map(mouseX, 0, width, 0, 255);
float g = map(mouseY, 0, height, 0, 255);
float b = 255 - r;
selectedLED.fillColor = color(r, g, b);
}
}
class CButton{
int index;
float x, y, radius, diameter;
boolean isOver;
color fillColor = color(255);
CButton(int index, float x, float y, float radius){
this.index = index;
this.x = x;
this.y = y;
this.radius= radius;
diameter = radius * 2;
}
void update(int mx, int my){
isOver = dist(x, y, mx, my) < radius;
}
void mouseReleased(){
if(isOver) onButtonClicked(this);
}
void draw(){
pushMatrix();
pushStyle();
if(isOver) {
fill(red(fillColor) * .5, green(fillColor) * .5, blue(fillColor) * .5);
}else{
fill(fillColor);
}
ellipse(x, y, diameter, diameter);
popStyle();
popMatrix();
}
String toString(){
return "[CButton index=" + index + "]";
}
}
Using these circular buttons on top of your NeoPixel ring image and perhaps with a bit of glow might look pretty good and simpler to achieve in a Processing sketch than taking the ControlP5 route. Don't get me wrong, it's a great library, but for custom behaviours it sometimes makes more sense to use your own custom code.
One other aspect to think is the overall interaction.
If this interface would be used to set the colors of an LED ring once, then it might ok, although it would take numLEDs * 3 interactions to set all the LEDs with a custom colour. If this was for a custom frame by frame LED animation tool then the interaction would get exhausting after a few frames.
My problem is as in the title. I am trying to write a simple game in processing with a car that you can drive on a 2D plane. I wanted to create a rotation of the car since it seems crucial so I did it as described here:Rotating points in 2D
But my implementation seems to fail a bit. You see, when I hit left of right arrow the car actually rotates but shrinks in size as it is rotating and after few turns it completely dissapears. Can you show me what am I missing here? Thanks in advance! Code of my functions:
class Point
{
float x, y;
Point(float xx, float yy)
{
x = xx;
y = yy;
}
Point()
{
x = y = 0.0;
}
void Rotate(Point center, float angle)
{
float s = sin(angle);
float c = cos(angle);
y = center.y + ((y-center.y) * c + (x-center.x) * s);
x = center.x + ((x-center.x) * c - (y-center.y) * s);
}
}
class Car
{
Point LT;
Point RT;
Point LB;
Point RB;
Point center;
float r;
float acceleration;
Car()
{
LT = new Point(10, 10);
RT = new Point (30, 10);
LB = new Point(10, 50);
RB = new Point(30, 50);
r = sqrt(pow(15-30, 2) + pow(25-10, 2));
}
Car(Point lt, Point rt, Point lb, Point rb)
{
LT = lt;
RT = rt;
LB = lb;
RB = rb;
center = new Point(abs((LT.x - RT.x)/2), abs((LT.y - LB.y)/2));
r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
}
Car(Point Center, float w, float h)
{
center = Center;
LT = new Point(center.x - w/2, center.y - h/2);
RT = new Point (center.x + w/2, center.y - h/2);
LB = new Point(center.x - w/2, center.y + h/2);
RB = new Point(center.x + w/2, center.y + h/2);
r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
}
void Show()
{
fill(45, 128, 156);
beginShape();
vertex(LT.x, LT.y);
vertex(RT.x, RT.y);
vertex(RB.x, RB.y);
vertex(LB.x, LB.y);
endShape();
}
void Update()
{
}
void Turn(float angle)
{
LT.Rotate(center, angle);
RT.Rotate(center, angle);
RB.Rotate(center, angle);
LB.Rotate(center, angle);
}
void Accelerate(float accel)
{
}
}
In main I only use car.Show() and I turn by -0.1 per left cliock and 0.1 per right click
EDIT
If you want to see whole code visit my github repo
Unfortunately I can't explain more at the moment, but here's a simpler option using one of the formulas you've pointed to:
Car car = new Car();
void setup(){
size(300,300);
// this helps draw rectangles from centre (as opposed to corner (default))
rectMode(CENTER);
car.position.set(150,150);
}
void draw(){
background(255);
if(keyPressed){
if(keyCode == UP){
car.speed = 1;
}
}
car.draw();
}
void keyPressed(){
if(keyCode == LEFT){
car.steer -= radians(10);
}
if(keyCode == RIGHT){
car.steer += radians(10);
}
}
void keyReleased(){
if(keyCode == UP){
car.speed = 0;
}
}
class Car{
PVector position = new PVector();
PVector velocity = new PVector();
float speed;
float steer;
void update(){
// use the same polar to cartesian coordinates formulate for quick'n'dirty steering
velocity.set(cos(steer) * speed,sin(steer) * speed);
// update position based on velocity
position.add(velocity);
}
void draw(){
update();
// use a nested coordinate system to handle translation and rotation for us
// order of operations is important
pushMatrix();
translate(position.x,position.y);
rotate(steer);
rect(0,0,30,15);
popMatrix();
}
}
Update
The main issue with points shrinking is you're cumulatively transforming the points when you rotate them. After each transformation there is no history of what the x,y were. Instead you should return a new point that is transformed, thus "remembering" the old x,y position.
Bellow is a tweaked version of your code, minus the two constructor variants.
Hopefully the comments will help:
Car car = new Car();
void setup(){
size(300,300);
}
void draw(){
if(keyCode == UP){
if(keyPressed){
car.Accelerate(1);
}else{
car.Accelerate(0);
}
}
car.Update();
background(255);
car.Show();
}
void keyPressed(){
if(keyCode == LEFT){
car.Turn(radians(-3));
}
if(keyCode == RIGHT){
car.Turn(radians(+3));
}
}
class Point
{
float x, y;
Point(float xx, float yy)
{
x = xx;
y = yy;
}
Point()
{
x = y = 0.0;
}
Point Rotate(Point center, float angle)
{
float s = sin(angle);
float c = cos(angle);
// return a new point (a rotated copy), rather than overwriting this one
return new Point(center.x + ((x-center.x) * c - (y-center.y) * s),
center.y + ((y-center.y) * c + (x-center.x) * s));
}
// translate by another point
void AddToSelf(Point point){
this.x += point.x;
this.y += point.y;
}
// pretty print info when using println()
String toString(){
return "[Point x=" + x + " y="+ y +"]";
}
}
class Car
{
Point LT;
Point RT;
Point LB;
Point RB;
Point center;
float r;
float acceleration;
// car angle: used to compute velocity and update vertices
float angle;
// car position: used to offset rendering position of the corners
Point position;
// car velocity: amount by which position translates
Point velocity = new Point();
Car()
{
float x = 10;
float y = 10;
float w = 40;
float h = 20;
// setup corners with no translation
LT = new Point(0 , 0 );
RT = new Point(0 + w, 0 );
LB = new Point(0 , 0 + h);
RB = new Point(0 + w, 0 + h);
// setup initial position
position = new Point(x,y);
center = new Point(w / 2, h / 2);
r = sqrt(pow(15-30, 2) + pow(25-10, 2));
}
//Car(Point lt, Point rt, Point lb, Point rb)
//{
// LT = lt;
// RT = rt;
// LB = lb;
// RB = rb;
// center = new Point(abs((LT.x - RT.x)/2), abs((LT.y - LB.y)/2));
// r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
//}
//Car(Point Center, float w, float h)
//{
// center = Center;
// LT = new Point(center.x - w/2, center.y - h/2);
// RT = new Point (center.x + w/2, center.y - h/2);
// LB = new Point(center.x - w/2, center.y + h/2);
// RB = new Point(center.x + w/2, center.y + h/2);
// r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
//}
void Show()
{
fill(45, 128, 156);
beginShape();
// render corners offset by the car position
vertex(position.x + LT.x, position.y + LT.y);
vertex(position.x + RT.x, position.y + RT.y);
vertex(position.x + RB.x, position.y + RB.y);
vertex(position.x + LB.x, position.y + LB.y);
endShape(CLOSE);
}
void Update()
{
// update velocity based on car angle and acceleration
velocity.x = cos(angle) * acceleration;
velocity.y = sin(angle) * acceleration;
// update position based on velocity
position.AddToSelf(velocity);
}
void Turn(float angle)
{
this.angle += angle;
// replace the old point with the transformed points
// (rather than continuosly transforming the same point)
LT = LT.Rotate(center, angle);
RT = RT.Rotate(center, angle);
RB = RB.Rotate(center, angle);
LB = LB.Rotate(center, angle);
}
void Accelerate(float accel)
{
acceleration = accel;
}
}
I'm learning Processing and am making modified version of pong game in processing 3. I have 2 balls simultaneously instead of just 1.
Also, one ball accelerates while the other ball slows down as the program runs.
My accelerating ball is working fine, it bounces around and increases speed. But, my slowing down ball is not working correct. The slowing ball moves in a very small area and does not even go close to the borders to bounce off. Help would be appreciated. Thanks.`
float ballXPosition;
float ballYPosition;
float ballTwoXPos;
float ballTwoYPos;
float xDirection;
float ballTwoXDir;
float yDirection;
float ballTwoYDir;
float radius = 12;
float xSpeed;
float ySpeed;
float ballTwoXSpeed;
float ballTwoYSpeed;
float MAX_SPEED = 15;
float MIN_SPEED = 0.2;
void setup()
{
size(600,600);
stroke(3);
background(255,255,255);
ballXPosition = width/2 + random(60);
ballTwoXPos= width/2 + random(60);
ballYPosition = height/2 + random(60);
ballTwoYPos = height/2 + random(60);
xDirection = random(1,3);
ballTwoXDir = random(1,3);
yDirection = random(1,3);
ballTwoYDir = random(1,3);
xSpeed = MIN_SPEED;
ySpeed = MIN_SPEED;
ballTwoXSpeed = MAX_SPEED;
ballTwoYSpeed = MAX_SPEED;
}
void createAcceleratingBall(float xpos, float ypos, float xstretch, float ystretch)
{
fill(255,0,0);
ellipse(xpos, ypos, xstretch, ystretch);
}
void createSlowingBall(float xpos, float ypos, float xstretch, float ystretch)
{
fill(0,0,255);
ellipse(xpos, ypos, xstretch, ystretch);
}
boolean isSpeedMax(float speed)
{
return speed > MAX_SPEED;
}
boolean isSpeedMin(float speed)
{
return speed < MIN_SPEED;
}
boolean isBallAtXBorder(float xpos)
{
if(xpos < radius || xpos > width - radius)
return true;
else
return false;
}
boolean isBallAtYBorder(float ypos)
{
if(ypos < radius || ypos > height - radius)
return true;
else
return false;
}
void draw()
{
background(255);
ballXPosition = ballXPosition + (xDirection * xSpeed);
ballTwoXPos = ballTwoXPos + (ballTwoXDir * ballTwoXSpeed);
ballYPosition = ballYPosition + (yDirection * ySpeed);
ballTwoYPos = ballTwoYPos + (ballTwoYDir * ballTwoYSpeed);
if(!isSpeedMax(xSpeed))
xSpeed *= 1.005;
if(!isSpeedMax(ySpeed))
ySpeed *= 1.003;
if(!isSpeedMin(ballTwoXSpeed))
ballTwoXSpeed = ballTwoXSpeed / 1.005;
if(!isSpeedMin(ballTwoYSpeed))
ballTwoYSpeed = ballTwoYSpeed / 1.003;
if(isBallAtXBorder(ballXPosition))
xDirection *= -1;
if(isBallAtYBorder(ballYPosition))
yDirection *= -1;
if(isBallAtXBorder(ballTwoXDir))
ballTwoXDir *= -1;
if(isBallAtYBorder(ballTwoYDir))
ballTwoYDir *= -1;
createAcceleratingBall(ballXPosition, ballYPosition, 2*radius, 2*radius);
createSlowingBall(ballTwoXPos, ballTwoYPos, 2.5*radius, 2.5*radius);
}
I think you have the wrong variables being tested for the slowing ball in the isBallAtXBorder and isBallAtYBorder functions. You're testing ballTwoXDir and ballTwoYDir - should you not be testing ballTwoXPos and ballTwoYPos?
I need to create a loop which will space circles equally around a circle in Processing.
I know I can somehow implement a FOR loop.
I need to be able to increase or decrease the number of circles around this circle (with button presses) but keep them equally spaced.
I know the formula's I need to include in the FOR loop to get the X and Y axis. The formulas:
being
X = R*cos(angle-90)+Y0
Y = R*sin(angle-90)+X0
I understand the three parameters of the FOR loop; when does it start, when does it finish, what changes when it runs.
What I can't see is how to implement the formulas into the FOR loop.
Many thanks
Here is the code I do have
void setup () {
size (600, 600);
background (255, 255, 255);
smooth ();
ellipse (width/2, height/2, 200, 200); // the guide circle. Not needed in final code.
}
void draw() {
for (int i = 0; i < 20; i ++) {
for (int j = 0; j < 20; j ++) {
ellipse (i *20, j * 20, 20, 20);
}
}
}
This code should do the trick:
float incrementalAngle = 0.0;
void setup(){
size(600, 600);
smooth();
background(0);
ellipse(width/2, height/2, 200, 200);
drawCircles(20, 200);
}
void draw(){
}
void drawCircles(int circlesNumber, int bigCircleNumber){
float angle = incrementalAngle;
for(int i = 0; i < circlesNumber; i++){
ellipse(bigCircleNumber * cos(incrementalAngle) + height/2,
bigCircleNumber * sin(incrementalAngle) + width/2,
circlesNumber, circlesNumber);
incrementalAngle += TWO_PI / circlesNumber;
}
}
So the second loop wasn't needed, and the formula you were trying to introduce would go in the X and Y position of your ellipse, there by playing whit the angle and the cos and sin you can get the result you were looking for.
What's left now is for you to get the number of circles you want by the clicking inside a mousePressed() method and drawing that amount.
Hope this comes useful and call me if you need more help
Regards
Jose.
Thank you to everyone who helped.
I managed to do it (slightly differently to you #Jose Gonzalez
int nbr_circles = 2;
void setup() {
size(600, 600);
smooth();
background(255);
}
void draw() {
background(255);
float cx = width/2.0;
float cy = height/2.0;
fill(0);
//float x, y; //
for (int i = 0; i < nbr_circles; i++)
{
float angle = i * TWO_PI / nbr_circles;
float x = cx + 110.0 * cos(angle);
float y = cy + 110.0 * sin(angle);
ellipse(x, y, 20, 20);
}
}
void mousePressed() {
if (mouseButton == LEFT) {
if (nbr_circles < 20)
nbr_circles = nbr_circles + 1;
} else if (mouseButton == RIGHT) {
if (nbr_circles > 2)
nbr_circles = nbr_circles - 1;
}
}
void setup()
{
size(600, 600);
colorMode(HSB);
background(255);
}
void draw()
int size;
size(600, 600);
smooth();
noFill();
float cx = width/2;
float cy = height/2;
float diameter = width;
ellipse(cx, cy, diameter, diameter);
size = 10;
for (int x=size; x<width; x+=size) {
for (int y=size; y<height; y+=size) {
float dist;
dist = 10;
fill((x + y)%256, 255, 255);
noStroke();
ellipseMode(CENTER);
ellipse(x, y, size, size);
}
}
}
This is what I have so far and I can't seem to figure out how to make it so it only fills to the edge of the circle. This is using the processing 2 program created by MIT. https://www.processing.org/
Or do you mean this?
void setup()
{
size(600, 600);
colorMode(HSB);
background(255);
}
void draw(){
int size;
size(600, 600);
smooth();
noFill();
float cx = width/2;
float cy = height/2;
float diameter = width;
float radius = diameter/2;
float radiusSqrd = radius*radius;
ellipse(cx, cy, diameter, diameter);
size = 10;
for (int x=size; x<width; x+=size) {
for (int y=size; y<height; y+=size) {
float dist;
//dist = sqrt( (cx-x)*(cx-x) + (cy-y)*(cy-y) );
float distSqrd = (cx-x)*(cx-x) + (cy-y)*(cy-y);
if ( distSqrd <= radiusSqrd ){
fill((x + y)%256, 255, 255);
noStroke();
ellipseMode(CENTER);
ellipse(x, y, size, size);
}
}
}
}
This checks how far x and y are from the center ( cx, cy ) and if that is less than the circle, it draws an ellipse. Uses distance squared and radius squared, because the math is faster.
You mean this?
void setup()
{
size(600, 600);
colorMode(HSB);
background(255);
}
void draw(){
int size;
size(600, 600);
smooth();
noFill();
float cx = width/2;
float cy = height/2;
float diameter = width;
ellipse(cx, cy, diameter, diameter);
size = 10;
for (int a=0; a<360; a+=2) {
float dist;
dist = 10;
fill((a)%256, 255, 255);
noStroke();
float x = width/2 + cos(radians(a))*diameter/2;
float y = height/2 + sin(radians(a))*diameter/2;
ellipseMode(CENTER);
ellipse(x, y, size, size);
}
}