Accessing single element in shared pointer


#1

I’m using ofxBox2d in this openFrameworks project, working specifically with the joints. I want to eventually access the circle at the end of the joint and rotate it around the mouse in a circle. I know how to do this in a normal array, but I’m more unfamiliar with how it works in this structure. This is the relevant code:

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetVerticalSync(true);
    ofBackgroundHex(000000);
    ofSetLogLevel(OF_LOG_NOTICE);
    ofDisableAntiAliasing();
    
    box2d.init();
    box2d.setGravity(0, 0);
    box2d.createBounds();
    box2d.setFPS(60.0);
    box2d.registerGrabbing();
    
//  anchor.setup(box2d.getWorld(), ofGetWidth()/2, ofGetHeight()/2, 4);
    
    //add a few circles
    for (int i = 0; i < 30; i++)
    {
        shared_ptr<ofxBox2dCircle> circle = shared_ptr<ofxBox2dCircle>(new ofxBox2dCircle);
        circle.get()->setPhysics(3.0, 0.53, 0.1);
        circle.get()->setup(box2d.getWorld(), ofGetWidth()/2, 100+(i*20), 8);
        circles.push_back(circle);
    }
    
    //connect each circle with joint
    for (int i = 0; i < circles.size(); i++)
    {
        shared_ptr<ofxBox2dJoint> joint = shared_ptr<ofxBox2dJoint>(new ofxBox2dJoint);
        
        //if first point, connect to top anchor
        if (i == 0)
        {
            joint.get()->setup(box2d.getWorld(), anchor.body, circles[i].get()->body);
        }
        else
        {
            joint.get()->setup(box2d.getWorld(), circles[i-1].get()->body, circles[i].get()->body);
        }
        
        joint.get()->setLength(25);
        joints.push_back(joint);
    }
}

//--------------------------------------------------------------
void ofApp::update(){
    box2d.update();
    
    angle += 0.2;
    distance += 0.1;
    
    timeElapsed = ofGetElapsedTimef();
    
    ofPoint mouse(ofGetMouseX(), ofGetMouseY());
    
    //"friendly" values: 25, 50
    float repelDist = 150;
    float attractDist = 400;
    
    for (int i = 0; i < circles.size(); i++)
    {
        float dist = mouse.distance(circles[i].get()->getPosition());
        float force = ofMap(dist, 0, 1262, 1.3, 0.1);
        circles[i].get()->addRepulsionForce(mouse, force);

            if (dist < repelDist)
            {
//              circles[i].get()->addRepulsionForce(mouse, 5.5);
            }
            if (dist > attractDist)
            {
                circles[i].get()->addAttractionPoint(mouse, 1.2);
            }
        std::cout << dist << endl;
    }
    
//    std::cout << dist << endl;
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    ofSetHexColor(0xf2ab01);
    ofSetLineWidth(5);
    
//    anchor.draw();
            for (int i = 0; i < circles.size(); i++)
            {
                ofFill();
                ofSetHexColor(0x01b1f2);
                circles[i].get()->draw();
                
            }
    
            for (int i = 0; i < joints.size(); i++)
            {
                ofSetHexColor(0xFFFFFF);
                joints[i].get()->draw();
            }
    
    string info = "";
}

#2

I added these lines in the draw() function in the cpp file;

        float radius = 1.0;
        for (int deg = 0; deg < 360*6; deg += 10)
        {
            angle = ofDegToRad(deg);
            float x = ofGetMouseX() + sin(angle) * radius;
            float y = ofGetMouseY() + cos(angle) * radius;
            circles[30]->setPosition(x, y);
        }

So now it looks like:

void ofApp::draw(){
    
    ofSetHexColor(0xf2ab01);
    ofSetLineWidth(5);
    
//    anchor.draw();
            for (int i = 0; i < circles.size(); i++)
            {
                ofFill();
                ofSetHexColor(0x01b1f2);
                circles[i].get()->draw();
                
                float radius = 1.0;
                for (int deg = 0; deg < 360*6; deg += 10)
                {
                    angle = ofDegToRad(deg);
                    float x = ofGetMouseX() + sin(angle) * radius;
                    float y = ofGetMouseY() + cos(angle) * radius;
                    circles[circles.size()].get()->setPosition(x, y);
                }
                
            }
    
            for (int i = 0; i < joints.size(); i++)
            {
                ofSetHexColor(0xFFFFFF);
                joints[i].get()->draw();
            }
    
    string info = "";
}

But I am still getting a green highlight where I say circles[circles.size()]->setPosition(x, y) which says:

Thread1: EXC_BAD_ACCESS (code=EXC_l386_GPFLT)

Is this an incorrect way to set the position of this circle?


#3

Solved it – for anyone wondering it was because I was saying circles[circles.size()].get(), instead of circles[circles.size()-1]. I was accessing the 31st element of the array – which doesn’t exist – rather than the 30th (since arrays are zero-based).


#4

You beat me to it! Nice work. That little trick always goes for 0 based arrays, whether it’s Java or C / C++, even Unity, Javascript etc. The only non-zero-based array language I’ve used is Matlab … and it always confused me.


#5

I’ve never heard of Matlab before. Is that language used for anything specific?


#6

Mostly scientific computing.