I am working on an animation of a simplified solar system and want to apply rotation to the Sun. It seems to be a simple task, but somehow it won't work. I try to write my program using object-oriented paradigm, so each planet, moon and the Sun is an object of the CelestialBody class.
I tried to put the rotate(angle) line in an following excerpt from the CelestialBody class, as follows:
if(Type == 4){
emissive(255, 255, 255);
pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
lightFalloff(0, 0, 0.00020); //light falls off right behind the surface of the sun
ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
rotate(angle);
}
Sadly, it does nothing. How to fix this and make the sun rotate, for example along the x-axis?
Here's my code:
Main file:
import peasy.*; //<>//
PImage bg;
float angle = 0;
CelestialBody planet1;
CelestialBody planet2;
CelestialBody planet3;
CelestialBody planet4;
CelestialBody planet5;
CelestialBody sun;
PImage sunTexture;
PImage rocketTexture;
PShape rocket;
PeasyCam cam;
void setup() {
fullScreen(P3D);
bg = loadImage("background.jpg");
sunTexture = loadImage("sun.jpg");
cam = new PeasyCam(this, 1200);
rocket = loadShape("rocket.obj");
noStroke();
sun = new CelestialBody(70, 0, 0, 255, 200, 50, 4);//4 - type: sun
sun.planet.setTexture(sunTexture);
//noStroke();
//emissive(0, 0, 0);
planet1 = new CelestialBody(16, 150, 0.01, 150, 50, 255, 1);
planet1.spawnMoon(2);
planet2 = new CelestialBody(25, 300, 0.014, 50, 100, 255, 1);
planet2.spawnMoon(3);
planet3 = new CelestialBody(35, 450, -0.015, 255, 100, 40, 2);
planet3.spawnMoon(1);
planet4 = new CelestialBody(50, 650, 0.011, 50, 200, 255, 1);
planet4.spawnMoon(2);
planet5 = new CelestialBody(65, 900, -0.014, 0, 100, 0, 1);
planet5.planet = rocket;
planet5.planet.scale(0.9);
}
void makeOrbit(int a, int r){
for(int i=0; i<a; i++){
stroke(255, 10);
ellipse(height/2,width/2,r,r);
r-=180;
}
noStroke();
}
void draw() {
background(bg);
//lights();
noFill();
//translate(width/2, height/2);
stroke(#FFFFFF);
//ellipse(0,0,300,300);
//ellipse(0,0,600,600);
//ellipse(0,0,900,900);
//ellipse(0,0,planet4.distance,planet4.distance
// int z = 100;
//for (int i = 0; i<2; i++){
// z = -z;
// pointLight(255, 255, 255, -100, -100, z);
// pointLight(255, 255, 255, 100, -100, z);
// pointLight(255, 255, 255, 100, 100, z);
// pointLight(255, 255, 255, -100, 100, z);
//}
//emissive(255, 255, 255);
//pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
//lightFalloff(0, 0, 0.00025); //light falls off right behind the surface of the sun
//ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
sun.show();
planet1.show();
planet1.orbit();
planet2.show();
planet2.orbit();
planet3.show();
planet3.orbit();
planet4.show();
planet4.orbit();
planet5.show();
planet5.orbit();
}
CelestialBody class:
class CelestialBody {
float radius;
float angle = random(TWO_PI);
float distance;
float orbitSpeed;
PShape planet;
CelestialBody[] moons;
int red;
int green;
int blue;
PVector v;
//PShape globe;
int Type;
CelestialBody(float _radius, float _distance, float _orbitSpeed, int _red, int _green, int _blue, int type) {
v = PVector.random3D();
radius = _radius;
distance = _distance;
v.mult(distance);
orbitSpeed = _orbitSpeed;
red = _red;
green = _green;
blue = _blue;
//stroke(red, green, blue);
fill(red, green, blue);
if(type == 1 || type == 4){
planet = createShape(SPHERE, _radius);
}
else if(type == 2){
planet = createShape(BOX, _radius);
}
Type = type;
}
void orbit() {
angle += orbitSpeed;
if (moons != null) {
for (int i = 0; i < moons.length; i++) {
moons[i].orbit();
}
}
}
void spawnMoon(int total){
moons = new CelestialBody[total];
for(int i = 0; i < moons.length; i++){
float r = radius / random(2,5);
float d = random((radius + r), (radius + r)*2);
float o = random(0.01, 0.05);
moons[i] = new CelestialBody(r, d, o, (int)random(0, 256), (int)random(0, 256), (int)random(0, 256), 1);
}
}
void show() {
pushMatrix();
PVector v2 = new PVector(1,0,1);
PVector p = v.cross(v2);
rotate(angle,p.x, p.y, p.z);
translate(v.x, v.y, v.z);
if(Type == 4){
emissive(255, 255, 255);
pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
lightFalloff(0, 0, 0.00020); //light falls off right behind the surface of the sun
ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
}
//shape(globe);
shape(planet);
if (moons != null) {
for (int i = 0; i < moons.length; i++) {
moons[i].show();
}
}
noStroke();
popMatrix();
}
}
Related
I have a P5.js art, but when I remove the background, the effect changes. I'd like to remove the background but keep the effect the same. The reason for this is because I plan to overlay this on top of another canvas.
The line I'd like to remove is this: background(30); However, when I remove it, the effect becomes different.
The full code can be found here: https://editor.p5js.org/timexer/sketches/Rbbo72xVi
class Particle {
constructor(){
this.pos = createVector(width/2,height/2)
this.vel = createVector(0,0)
this.acc = p5.Vector.random2D().normalize()
this.r = map(this.pos.x, 0, width, 255, 0)
this.g = map(this.pos.y, 0, height, 0, 255)
this.b = map(dist(width / 2, height / 2, this.pos.x, this.pos.y), 0, width/2, 0, 255)
this.alpha = 255
}
update(){
var m = map(sin(frameCount), -1, 1, 0.3, 0.6)
this.acc.mult(m)
this.vel.add(this.acc)
this.pos.add(this.vel)
this.r = map(this.pos.x, 0, width, 255, 0)
this.g = map(this.pos.y, 0, height, 0, 255)
this.b = map(dist(width / 2, height / 2, this.pos.x, this.pos.y), 0, width, 0, 255)
if ( dist(width / 2, height / 2, this.pos.x, this.pos.y) > 80){
this.alpha -= 5
}
}
show(){
noStroke()
fill(this.r, this.g, this.b, this.alpha)
ellipse(this.pos.x, this.pos.y, 2)
}
}
var particles = []
function setup() {
createCanvas(800, 800);
angleMode(DEGREES)
}
function draw() {
background(30);
for(var i = 0; i <10; i++){
p = new Particle()
particles.push(p)
}
for(var i = 0; i < particles.length ; i++){
if(particles[i].alpha > 0){
particles[i].update()
particles[i].show()
}else{
particles.splice(i,1)
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
Instead of calling background(30) call clear()
var particles = []
function setup() {
createCanvas(windowWidth, windowHeight);
angleMode(DEGREES)
}
function draw() {
clear();
for (var i = 0; i < 10; i++) {
const p = new Particle()
particles.push(p)
}
for (var i = 0; i < particles.length; i++) {
if (particles[i].alpha > 0) {
particles[i].update()
particles[i].show()
} else {
particles.splice(i, 1)
}
}
}
class Particle {
constructor() {
this.pos = createVector(width / 2, height / 2)
this.vel = createVector(0, 0)
this.acc = p5.Vector.random2D().normalize()
this.r = map(this.pos.x, 0, width, 255, 0)
this.g = map(this.pos.y, 0, height, 0, 255)
this.b = map(dist(width / 2, height / 2, this.pos.x, this.pos.y), 0, width / 2, 0, 255)
this.alpha = 255
}
update() {
var m = map(sin(frameCount), -1, 1, 0.3, 0.6)
this.acc.mult(m)
this.vel.add(this.acc)
this.pos.add(this.vel)
this.r = map(this.pos.x, 0, width, 255, 0)
this.g = map(this.pos.y, 0, height, 0, 255)
this.b = map(dist(width / 2, height / 2, this.pos.x, this.pos.y), 0, width, 0, 255)
if (dist(width / 2, height / 2, this.pos.x, this.pos.y) > 80) {
this.alpha -= 5
}
}
show() {
noStroke()
fill(this.r, this.g, this.b, this.alpha)
ellipse(this.pos.x, this.pos.y, 2)
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
I have a scene with a cube and a custom obj. I am attempting to apply a gradient as a texture to the cube via createGraphics, but every time I use createGraphics as a texture on the cube it flickers
The custom model does not have the same issue when using the createGraphics texture for it, it is exclusively a problem with the cube.
Here is my code:
var camy;
var camz;
var camoffset;
var horiZon;
var c1;
var c2;
function preload() {
fria = loadImage('nocity.png');
island = loadModel('untitled.obj');
}
function setup() {
canvas = createCanvas(windowWidth, windowHeight, WEBGL);
pixelDensity=1;
c1 = color(255, 255, 255);
c2 = color(0, 0, 0);
sunset = createGraphics(200, 200);
}
function windowResized() {
resizeCanvas(windowWidth,windowHeight);
}
function draw() {
background(0, 5, 100);
angleMode(DEGREES);
camoffset = 2500 - windowWidth;
horiZon = map(mouseY, 0, height, -35, -65);
camx = map(mouseX, 0, width, -500, 500);
camz = map(mouseY, height, 0, -1400 - camoffset, -2100 - camoffset);
camy = map(mouseY, height, 0, -1000 - camoffset, -400);
setGradient(0, 0, 200, 200, c1, c2);
perspective(PI / 3.0, width / height, 0.1, 10000);
camera(camx, camy, camz, 0, 0, 0, 0, 1, -0.25);
translate(-2.5, 6, 0);
rotateZ(180);
rotateY(180);
noStroke();
texture(fria);
model(island);
texture(sunset);
translate(0, 100, horiZon);
box(200, 200, 1);
}
function setGradient(x, y, w, h, c1, c2) {
noFill();
for (var i = y; i <= y + h; i++) {
var inter = map(i, y, y + h, 0, 1);
var c = lerpColor(c1, c2, inter);
sunset.stroke(c);
sunset.line(x, i, x + w, i);
}
}
I found a solution to this problem. When I removed the camera code, the flickering disappeared. So the solution I made was I instead used translation and rotation to emulate the camera motions that I wanted. It is quite hard to think of it this way, but you can figure out what translation you need to do with simple trig.
I have completed my sketch in working in P3D mode apart from titles and legends. How do I write these texts normally like 2D when working from this mode. I've introduced a camera in the sketch to enable panning and zooming functionality. This causes the titles to transform according to the camera. I've tried transforming the title to correct position but it still looks somewhat off
Also how can I make it free from mouse zoom and panning. ie it holds its position even though other parts of the sketch moves.
Here is my code:
PImage worldMap;
PShape box;
Table table;
int rowCount;
float x1, y1, z1, x2, y2, z2;
//Interaction Zoom and Pan Variables:
float zoom = 600;
float panLeft = 0;
float panTop = 0;
void setup() {
size(1400, 800, P3D);
table = new Table("From_USA_Coordinates.tsv");
rowCount = table.getRowCount();
worldMap = loadImage("world.topo.bathy.200406.3x5400x2700.jpg");
worldMap.resize(500, 300);
textureMode(NORMAL);
fill(255);
//stroke(color(44,48,32));
box = createShape(BOX, -650, 300, 0);
box.beginShape(BOX);
box.endShape();
box.setTexture(worldMap);
}
void draw() {
background(255);
fill(0);
titlesAndLegends();
display();
}
void mouseDragged() {
if((mouseX- pmouseX) > 0){
panLeft -= 5;
} else {
panLeft += 5;
}
if((mouseY-pmouseY) > 0) {
//panTop -=5;
}
}
void mouseWheel(MouseEvent event) {
float e = event.getCount();
if(e == 1) {
zoom += 30;
}else {
zoom -= 30;
}
}
public void display() {
camera(panLeft, zoom , zoom, panLeft, 0, panTop, 0, 1, 0); // eye(0, 600, 600) center(0, 0, 0) up(0, 1, 0)
pushMatrix();
translate(-350, 0, 0);
shape(box);
//box.scale(zoom);
popMatrix();
pushMatrix();
translate(350, 0, 0);
shape(box);
popMatrix();
pushMatrix();
// To use the center of the left box as center coordinates
translate(-350, 0, 0);
textSize(15);
for(int row = 1; row < rowCount; row++) {
float USALatitude = table.getFloat(row, 3);
float USALongitude = table.getFloat(row, 4);
String countryName = table.getString(row,1);
//Mapped Within X-axis of the left side map box
float mappedLatitude = map(USALatitude,-90, 90, 150, -150); // Latitude is in Y axis
float mappedLongitude = map(USALongitude, -180, 180, -325, 325); // Longitude in X Axis
x1 = mappedLongitude;
y1 = mappedLatitude;
z1 = 0;
float tripCountryLatitude = table.getFloat(row, 5);
float tripCountryLongitude = table.getFloat(row, 6);
float tripLatitude = map(tripCountryLatitude, -90, 90, 150, -150); // In Y, same mapping
float tripLongitude = map(tripCountryLongitude, -180, 180, 375, 1025);
// In X, having the position of the right box depending on the coordinates center
x2 = tripLongitude;
y2 = tripLatitude;
z2 = 0;
float zOff = map(0, 0, height, 300, 0); // Move mouse up and down
float a = (x2-x1)/3;
float b = (y2-y1)/3;
stroke(#F05252);
noFill();
bezier(x1, y1, z1, // First point
x1 + a, y1 + b, z1 + zOff, // First intermediate point
x2 - a, y2 - b, z2 + zOff, // Second intermediate point
x2, y2, z2);
//rotate(PI);
stroke(255);
fill(255);
text(countryName, x2-10, y2+10, z2+20);
}
popMatrix();
}
void titlesAndLegends() {
pushMatrix();
translate(-1000, -900, 0);
//rotateY(-PI/4);
textSize(50);
fill(0);
text("From USA to Other Parts of the World - 2019", width/2, 50);
popMatrix();
}
Code for table:
class Table {
int rowCount;
String[][] data;
Table(String filename) {
String[] rows = loadStrings(filename);
data = new String[rows.length][];
for (int i = 0; i < rows.length; i++) {
if (trim(rows[i]).length() == 0) {
continue; // skip empty rows
}
if (rows[i].startsWith("#")) {
continue; // skip comment lines
}
// split the row on the tabs
String[] pieces = split(rows[i], TAB);
// copy to the table array
data[rowCount] = pieces;
rowCount++;
// this could be done in one fell swoop via:
//data[rowCount++] = split(rows[i], TAB);
}
// resize the 'data' array as necessary
data = (String[][]) subset(data, 0, rowCount);
}
int getRowCount() {
return rowCount;
}
// find a row by its name, returns -1 if no row found
int getRowIndex(String name) {
for (int i = 0; i < rowCount; i++) {
if (data[i][0].equals(name)) {
return i;
}
}
println("No row named '" + name + "' was found");
return -1;
}
String getRowName(int row) {
return getString(row, 0);
}
String getString(int rowIndex, int column) {
return data[rowIndex][column];
}
String getString(String rowName, int column) {
return getString(getRowIndex(rowName), column);
}
int getInt(String rowName, int column) {
return parseInt(getString(rowName, column));
}
int getInt(int rowIndex, int column) {
return parseInt(getString(rowIndex, column));
}
float getFloat(String rowName, int column) {
return parseFloat(getString(rowName, column));
}
float getFloat(int rowIndex, int column) {
return parseFloat(getString(rowIndex, column));
}
void setRowName(int row, String what) {
data[row][0] = what;
}
void setString(int rowIndex, int column, String what) {
data[rowIndex][column] = what;
}
void setString(String rowName, int column, String what) {
int rowIndex = getRowIndex(rowName);
data[rowIndex][column] = what;
}
void setInt(int rowIndex, int column, int what) {
data[rowIndex][column] = str(what);
}
void setInt(String rowName, int column, int what) {
int rowIndex = getRowIndex(rowName);
data[rowIndex][column] = str(what);
}
void setFloat(int rowIndex, int column, float what) {
data[rowIndex][column] = str(what);
}
void setFloat(String rowName, int column, float what) {
int rowIndex = getRowIndex(rowName);
data[rowIndex][column] = str(what);
}
}
The links to my image files and datatable
https://drive.google.com/file/d/1sZw5Gc3xf_RTM_Ti6FeJ-_PVj49b0mlT/view
https://drive.google.com/file/d/111Tmhy6YDBQBmI2AaJuTPrrtdGZZpJSy/view
You should be able to isolate coordinate systems using pushMatrix()/popMatrix() calls. See the 2D Transformations tutorial as the same principle applies in 3D.
In your particular case it looks like display() is responsible for the 3D view.
You might want to isolate the camera() call into it's own coordinate system so it doesn't affect the legend:
public void display() {
// begin isolate camera transformed coordinate system
pushMatrix();
camera(panLeft, zoom , zoom, panLeft, 0, panTop, 0, 1, 0); // eye(0, 600, 600) center(0, 0, 0) up(0, 1, 0)
pushMatrix();
translate(-350, 0, 0);
shape(box);
//box.scale(zoom);
popMatrix();
pushMatrix();
translate(350, 0, 0);
shape(box);
popMatrix();
pushMatrix();
// To use the center of the left box as center coordinates
translate(-350, 0, 0);
textSize(15);
for(int row = 1; row < rowCount; row++) {
float USALatitude = table.getFloat(row, 3);
float USALongitude = table.getFloat(row, 4);
String countryName = table.getString(row,1);
//Mapped Within X-axis of the left side map box
float mappedLatitude = map(USALatitude,-90, 90, 150, -150); // Latitude is in Y axis
float mappedLongitude = map(USALongitude, -180, 180, -325, 325); // Longitude in X Axis
x1 = mappedLongitude;
y1 = mappedLatitude;
z1 = 0;
float tripCountryLatitude = table.getFloat(row, 5);
float tripCountryLongitude = table.getFloat(row, 6);
float tripLatitude = map(tripCountryLatitude, -90, 90, 150, -150); // In Y, same mapping
float tripLongitude = map(tripCountryLongitude, -180, 180, 375, 1025);
// In X, having the position of the right box depending on the coordinates center
x2 = tripLongitude;
y2 = tripLatitude;
z2 = 0;
float zOff = map(0, 0, height, 300, 0); // Move mouse up and down
float a = (x2-x1)/3;
float b = (y2-y1)/3;
stroke(#F05252);
noFill();
bezier(x1, y1, z1, // First point
x1 + a, y1 + b, z1 + zOff, // First intermediate point
x2 - a, y2 - b, z2 + zOff, // Second intermediate point
x2, y2, z2);
//rotate(PI);
stroke(255);
fill(255);
text(countryName, x2-10, y2+10, z2+20);
}
popMatrix();
// end isolate camera
popMatrix();
}
As an illustration, here's a modifider version of the camera() example, printing the transformation matrix before and after transformations:
size(100, 100, P3D);
noFill();
background(204);
// reset all transformations
resetMatrix();
println("before camera");
printMatrix();
pushMatrix();
camera(70.0, 35.0, 120.0, 50.0, 50.0, 0.0,
0.0, 1.0, 0.0);
println("after camera");
printMatrix();
translate(50, 50, 0);
rotateX(-PI/6);
rotateY(PI/3);
noFill();
box(45);
popMatrix();
// back to no transformations
printMatrix();
fill(0);
text("text2D",-50,-40,-100);
I am creating a simulator using P5.js. Within the simulator, I need a green box, however it does not seem to be appearing. The code is below:
var outputs = [];
function setup() {
createCanvas(600, 400, WEBGL);
background(200);
for (var i = 0; i < 1; i++) {
drop = new Water(width / 2, height / 2, 0, 1);
outputs[i] = drop;
}
}
function draw() {
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
for (var i = 0; i < outputs.length; i++) {
outputs[i].update();
}
background(200);
}
Here is the water class:
function Water(x_, y_, z_, yVel_) {
this.r = random(0.25, 1);
this.xOff = random(-(this.r / 10), (this.r / 10));
this.zOff = random(-(this.r / 10), (this.r / 10));
this.x = x_ + this.xOff;
this.y = y_;
this.z = z_ + this.zOff;
this.yVel = yVel_;
this.pos = createVector(this.x, this.y, this.z);
this.show = function() {
push();
translate(this.pos.x, this.pos.y, this.pos.z);
noStroke();
fill(0, 0, 255);
sphere(this.r * 2);
pop();
}
this.update = function() {
this.vel = createVector(random(-(this.r / 10), (this.r / 10)),
this.yVel, random(-(this.r / 10),
(this.r / 10)));
this.pos.add(this.vel);
this.show();
}
}
This is a web based simulation, with another module which appears to be working fine.
Any help would be greatly appreciated. Thanks in advance!
Removing the parts that require the Water class, and moving the background function call to the top of draw, it seems to work just fine.
So, the problem is
Either that you forgot to put background on top
Or something's wrong with the Water class.
Here's your code with the mentioned problems fixed.
var outputs = [];
function setup() {
createCanvas(600, 400, WEBGL);
}
function draw() {
background(200);
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/p5.min.js"></script>
Its not rendering because you're background is over your scene
function draw() {
background(200);
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
for (var i = 0; i < outputs.length; i++) {
outputs[i].update();
}
}
What your doing is drawing the box and the drops and you cover it all up with your background
if you don't have a background you will see how p5.js renders animation
p5.js not moving it, its just looping through draw every frame and the background covers up the previous frame
I keep getting a "cannot run pushMatrix more than 32 times" in the middle of running this sketch. I'm aware that this can be an issue of having pushMatrix(); calls without a matching popMatrix(); but I don't see it in my code. Any help appreciated.
For the record; I'm aware this code is not very pretty and could be refactored extensively. I'm still new to programming and this is just an ongoing project I've been working on since the day I started coding.
Thanks again for any help.
float x, y, d, r, g, b, t;
float c = random(0, mouseY+75);
float easing = 0.03;
int diameter= 40;
int timer= -3000;
int direction = 1;
float speed = .7;
float angle = 0.0;
float offset;
float scalar = 60;
boolean button = false;
void setup() {
size(1000, 400);
smooth();
strokeWeight(5);
}
void draw() {
background(204);
int currentTime = millis();
textSize(16);
fill (125);
text ("Flying Circles", 20, 20);
if ((currentTime < 5000) && (mousePressed==false)){
r = noise(frameCount * 0.01) * 255; //clockwise spin
g = frameCount % 255;
b = 255 - noise(1 + frameCount * 0.025) * 255;
rectMode(CENTER);
background(204);
pushMatrix();
translate(mouseX, mouseY);
pushMatrix();
rotate(-angle);
ellipse(0,0, 150, 150);
ellipse(0,0, 125, 125);
rect(0,0, 80, 80);
popMatrix();
pushMatrix();
rotate(angle);
rect(0, 0, 80, 80);
rect(0, 0, 60, 60);
popMatrix();
pushMatrix();
rotate(-angle);
fill(r,g,b);
rect(-270, 0, 80, 80);
rect(270, 0, 80, 80);
rect(0, 0, 40, 40);
angle += 0.1;
popMatrix();
popMatrix();
}else{
drawCounterspin();
}
}
void keyPressed() {
button = !button;
}
void drawFighter(){
float targetX = mouseX;
float d = random(0, 150);
x += (targetX - x) * easing*1.5;
fill(mouseY, mouseY/2, mouseY/3);
ellipse(x-300, mouseY, 100, 100);
fill(d, d*1.2, d*1.5);
ellipse(x, mouseY, 80, 80);
fill(mouseY, mouseY/2, mouseY/3);
ellipse(x+300, mouseY, 100, 100);
line(x+40, mouseY,x+250, mouseY);
line(x-40, mouseY,x-250, mouseY);
fill(d, d, d);
ellipse(x, mouseY+100, 80, 80);
fill(d, d, d);
ellipse(x, mouseY+200, 60,60);
line(x+30,mouseY+30, width, mouseY*2);
line(x-30,mouseY+30, 0, mouseY*2);
}
void drawOilbounce() {
x = width/2;
y += speed * direction;
if ((y > height/2+diameter) || (y < 0)) {
direction = -direction;
scalar = -scalar;
}
float spinspeed = speed * .1;
float spinx = x+ cos(angle) * scalar;
float spiny = y+ sin(angle) * scalar;
angle += spinspeed;
scalar += spinspeed;
scalar = constrain(scalar, 30, 300);
fill(r,g,b);
ellipse(spinx, spiny, 30, 30);
fill(r*.95, g*.85, b*.75);
ellipse(x, y, diameter, diameter);
fill(r*.85, g*.75, b*.65);
ellipse(x, y*1.2, y*.02*diameter, diameter);
fill(r*.75, g*.65, b*.55);
ellipse(x, y*1.5, y*.05*diameter, diameter);
}
void drawCounterspin(){
pushMatrix();
rectMode(CENTER);
mouseX = constrain (mouseX, 250, width-250);
mouseY = constrain (mouseY, 48, height-48);
fill(mouseY, 80, 100);
if (mouseButton == LEFT) {
translate(mouseX, mouseY);
scale(sin(angle));
rotate(angle);
ellipse(0,0, 150, 150);
ellipse(0,0, 125, 125);
fill(mouseY, mouseX/2, mouseX);
rect(0, 0, 80, 80);
fill(mouseY/2, mouseX/3, mouseX);
rect(250, 0, 80, 80);
fill(mouseY, mouseX, mouseX/2);
rect(-250, 0, 80, 80);
angle += 0.05;
popMatrix();
}
}
Getting rid of the two calls (push and pop) inside the function drawCounterspin() seams to solve the problem without side effects. But I don't really know why... I have sen this behaviour before using push/popMatrix inside functions. If needed, isolate the call in draw, and not in the function, like:
pushMatrix();
drawCounterspin();
popMatrix();
Worked for me before.