Hello Everyone,
I'm struggling with this code for quite some time so I need a little adivce on how to work this out.
I have a Hero class which is a an ellipse moving around following mouse clicks with physics. I have an arc class to create an arrayList of arcs which will create a maze.
I need to find the opening in my arc , and handle collisions beetween my hero and my arc. And of course the arc is rotating around the center.
So I guess what best is using polar coordinates but I'm having trouble using acos() and asin() functions and finding the angle of my hero in the (0,TWO_PI) range I want to compare it to my arc starting angle and stoping angle.
I tried to calculate a bunch of stuff converting polar to cartesian but I think I'm getting lost... So any pointers would be greatly appreciated on how to resolve that.
Here's my code to get a grasp of what's going on at the moment.
- Hero hero;
- ArrayList arcs;
- // unlock :ending animation
- boolean locked = true;
- void setup() {
- size(600, 600);
- background(0);
- strokeWeight(2);
- stroke(180);
- PVector a = new PVector(0.0, 0.125);
- PVector v = new PVector(0.0, 0.0);
- PVector l = new PVector(width/2, height/2);
- hero = new Hero(a, v, l);
- arcs = new ArrayList();
- for (int i=1 ; i<7 ;i++) {
- arcs.add(new Arc(width/2, height/2, i*100, i*100, random (PI/3, PI), random (TWO_PI, TWO_PI-PI/2)));
- }
- }
- void draw() {
- background(0);
- float c = -0.23; // Drag coefficient
- PVector heroVel = hero.getVel(); // Velocity of our thing
- PVector force = PVector.mult(heroVel, c); // Following the formula
- hero.applyForce(force); // Adding the force to our object, which will ultimately affect its acc
- // Run the Thing object
- hero.makeAppear();
- hero.go();
- // for (int i=0; i<arcs.size();i++){
- // drawing only the third one for tests (uncomment the for loop to see the maze)
- Arc a = (Arc) arcs.get(3);
- a.display();
- a.collide(hero);
- // }
- if (mousePressed) {
- // Compute difference vector between mouse and object location
- // 3 steps -- (1) Get Mouse Location, (2) Get Difference Vector, (3) Normalize difference vector
- PVector m = new PVector(mouseX, mouseY);
- PVector diff = PVector.sub(m, hero.getLoc());
- diff.normalize();
- float factor = 0.1; // Magnitude of Acceleration (not increasing it right now)
- diff.mult(factor);
- //object accelerates towards mouse
- hero.setAcc(diff);
- }
- else {
- hero.setAcc(new PVector(0, 0));
- }
- // Boundaries of our window
- if (hero.loc.x<0) {
- PVector newV = hero.getVel();
- newV.x*=-1;
- hero.setVel(newV);
- }
- if (hero.loc.x>width) {
- PVector newV = hero.getVel();
- newV.x*=-1;
- hero.setVel(newV);
- }
- if (hero.loc.y<0) {
- PVector newV = hero.getVel();
- newV.y*=-1;
- hero.setVel(newV);
- }
- if (hero.loc.y>height) {
- PVector newV = hero.getVel();
- newV.y*=-1;
- hero.setVel(newV);
- }
- /*
- if (button.activate){
- if(hero.loc.x > 450 ||hero.loc.x< 150 || hero.loc.y>450 || hero.loc.y<150){
- locked = false;
- }
- }
- if (!locked){
- // animate
- // run particle system
- // diminish alpha value of lab
- }
- */
- }
- class Arc {
- float xpos, ypos;
- float awidth, aheight;
- float astart, astop;
- float angle = 0;
- float updater;
- // not complitely usefull
- float xline, yline;
- float x1pin, y1pin, x2pin, y2pin;
- float starta, stopa;
- float goodAngle=0;
- Arc(float xpos0, float ypos0, float awidth0, float aheight0, float astart0, float astop0) {
- xpos = xpos0;
- ypos = ypos0;
- awidth = awidth0;
- aheight = aheight0;
- astart = astart0;
- astop = astop0;
- updater = random(1)/100;
- xline=0;
- yline=0;
- }
- void display() {
- pushMatrix();
- pushStyle();
- stroke(255);
- strokeWeight(4);
- noFill();
- translate(xpos, ypos);
- rotate(angle);
- arc(0, 0, awidth, aheight, astart, astop);
- ellipse(awidth/2*cos(astart), aheight/2*sin(astart), 5, 5);
- ellipse(awidth/2*cos(astop), aheight/2*sin(astop), 5, 5);
- popStyle();
- popMatrix();
- angle += updater;
- }
- void collide(Hero h) {
- // we have to use polar coordinate to ease collision detection.
- // calculate hero radius
- float hradius = dist (h.loc.x, h.loc.y, width/2, height/2);
- // calculate hero angle
- float hangle = acos(map(hero.loc.x, 0, width, -width/2, width/2) / (hradius));
- float hangle2 = asin(map(hero.loc.y, 0, height, -height/2, height/2) / (hradius));
- // calculate updated start and end angles
- starta = (astart + angle);
- stopa = (astop + angle);
- // drawing ellipses at start and end of the arc
- x1pin = (awidth/2) * cos(astart+angle)+width/2;
- y1pin = (aheight/2) * sin(astart+angle)+height/2;
- x2pin = (awidth/2) * cos(astop+angle)+width/2;
- y2pin = (aheight/2) * sin(astop+angle)+height/2;
- // start
- fill(255, 0, 0);
- ellipse(x1pin, y1pin, 5, 5);
- text(starta, x1pin, y1pin);
- //end
- fill(0, 250, 0);
- ellipse(x2pin, y2pin, 5, 5);
- text(stopa, x2pin, y2pin);
- // drawing from center to hero using polar coordinates to check if they are good
- // notice that sometimes i need to use the value obtain by the sin and sometimes by the cos
- // i think it's the reason I'm having a hard time figuring this out
- if (hero.loc.x< width/2 && hero.loc.y<height/2) {
- xline = width/2 + (hradius) * cos(hangle);
- yline = height/2 + (hradius) *sin(hangle2);
- }
- if (hero.loc.x< width/2 && hero.loc.y>height/2) {
- xline = width/2 + (hradius) * cos(hangle);
- yline = height/2 + (hradius) *sin(hangle);
- }
- if (hero.loc.x> height/2 && hero.loc.y<height/2) {
- xline = width/2 + (hradius) * cos(hangle2);
- yline = height/2 + (hradius) *sin(hangle2);
- }
- if (hero.loc.x> height/2 && hero.loc.y>height/2) {
- xline = width/2 + (hradius) * cos(hangle2);
- yline = height/2 + (hradius) *sin(hangle);
- }
- line(width/2, height/2, xline, yline);
- // collision first check radius
- if (hradius-h.diameter/2<awidth/2+4 && hradius+h.diameter/2>awidth/2-4) {
- // check angle
- // ... ? ...
- }
- }
- }
- class Hero {
- PVector loc;
- PVector vel;
- PVector acc;
- float maxvel;
- float mass;
- // to tween our object
- float diameter =30;
- float sDist;
- float tweenfactor=0;
- float cellS, cellS2;
- // to makeAppear() and makeDisAppear()
- float alph = 0;
- //The Constructor (called when the object is first created)
- Hero(PVector a, PVector v, PVector l) {
- acc = a;
- vel = v;
- loc = l;
- maxvel = 4;
- mass = 20;
- }
- //main function to operate object
- void go() {
- update();
- render();
- }
- //function to update location
- void update() {
- vel.add(acc);
- loc.add(vel);
- //limit speed to max
- if (vel.mag() > maxvel) {
- vel.normalize();
- vel.mult(maxvel);
- }
- }
- //function to display
- void render() {
- strokeWeight(8);
- stroke(220, alph);
- fill(175, alph);
- tween(); // change appearance while moving
- ellipse(loc.x, loc.y, diameter-cellS, diameter+cellS2);
- }
- // transform movement (used in draw)
- void applyForce(PVector force) {
- force.div(mass); // Newton's second law
- acc.add(force); // Accumulate acceleration
- }
- //Add functions to our thing object to access the location, velocity and acceleration from outside the class
- PVector getVel() {
- return vel.get();
- }
- PVector getAcc() {
- return acc.get();
- }
- PVector getLoc() {
- return loc.get();
- }
- void setLoc(PVector v) {
- loc = v.get();
- }
- void setVel(PVector v) {
- vel = v.get();
- }
- void setAcc(PVector v) {
- acc = v.get();
- }
- // ou tween function !
- void tween() {
- // distance from mouse
- sDist = dist(mouseX, mouseY, loc.x, loc.y);
- // change tween factor (angle for our wavelet animation)
- if (sDist>75) {
- tweenfactor+=0.3;
- }
- else {
- tweenfactor+= map(sDist, 0, 75, 0.09, 0.25);
- }
- //scale our multiplication factor for our tween effect
- float sMult = map(sDist, 0, 100, 0.09*diameter, .25 * diameter);
- // fill to global variables to affect the drawing of our ellipse
- cellS = sMult * cos(tweenfactor);
- cellS2 = sMult * (.5 +(cos(tweenfactor)/2));
- }
- // time related functions called whe starting and leaving
- void makeAppear() {
- alph+=1;
- alph = constrain(alph, 0, 180);
- }
- void makeDisappear() {
- alph-=1;
- alph = constrain(alph, 0, 180);
- }
- }
1