草庐IT

c++ - 将继承与基于 stdvector 的植绒结合使用

coder 2024-02-22 原文

目前我正在完成一项任务,为此我必须制作一个具有不同子类且行为不同的植绒系统。我正在使用 OpenFrameworks 和 C++。 我对开放框架和 C++ 还很陌生。

作为基础,我使用了这段代码: https://sites.google.com/site/ofauckland/examples/ofxflocking-example

但问题是,这段代码的结构与我习惯的不同;使用“new ...”创建新的类对象

我的问题是,如何使用两个植绒类?开始时,首先只使用不同的颜色。

到目前为止我添加的子类之一是:

class Team1 : public Boid {
public:

   Team1(): Boid() {};
   Team1(int x, int y): Boid(x,y) {};



   void draw()
    {

    }
};

我为父类(super class) Boid 的 void draw 使用了 virtual void draw 并使用了 boids.push_back(*new Team1());在设置和鼠标拖动中。这会产生以下错误:

  • Team1 之前需要类型说明符
  • 预计 )之前 Team1
  • 没有匹配函数来调用std::vector<Boid, std::allocator<Boid> >::push_back(int&)

完整代码:(所有代码都在一个 testapp.cpp 文件中,以排除链接问题)

//number of boids
const int BoidAmount = 25;

父类(super class) Boid:

class Boid {
public:
Boid();
Boid(int x, int y);

void update(vector<Boid> &boids);
virtual void draw() {};

void seek(ofVec2f target);
void avoid(ofVec2f target);
void arrive(ofVec2f target);

void flock(vector<Boid> &boids);

ofVec2f steer(ofVec2f target, bool slowdown);   

ofVec2f separate(vector<Boid> &boids);
ofVec2f align(vector<Boid> &boids);
ofVec2f cohesion(vector<Boid> &boids);

ofVec2f location,direction

,acceleration;

float r;
float attraction;
float maxspeed;
};

构造函数:

 //---Constructors(overload)-----------------------------------------
Boid::Boid() {
location.set(ofRandomWidth(),ofRandomHeight());
direction.set(0,0);
acceleration.set(0,0);
r = 3.0;
maxspeed = 4;
attraction = 0.05; 
}

Boid::Boid(int x, int y) {
location.set(x,y); //initial location
direction.set(0,0); //initial direction
acceleration.set(0,0); //initial acceleration   
r = 3.0;
maxspeed = 4; // initial max speed
attraction = 0.1; // initial max force
}

子类:

class Team1 : public Boid {
public:

Team1(): Boid() {};
Team1(int x, int y): Boid(x,y) {};



void draw()
{
    // Draw a triangle rotated in the direction of direction
    float angle = (float)atan2(-direction.y, direction.x);
    float theta =  -1.0*angle;
    float heading2D = ofRadToDeg(theta)+90;

    ofPushStyle();
    ofFill();


    ofPushMatrix();
    ofTranslate(location.x, location.y);

    ofRotateZ(heading2D);
    ofSetColor(255,255,255,80);

    ofEllipse(0, -r*2, 7, 12);
    ofBeginShape();
    ofVertex(0, -r*2);
    ofVertex(-r, r*2);
    ofVertex(r, r*2);
    ofEndShape(true);   
    ofPopMatrix();
    ofPopStyle();
}
};

class Team2 : public Boid {
public:

Team2(): Boid() {};
Team2(int x, int y): Boid(x,y) {};


void draw()
{


}

};

Methods:

// Method to update location
void Boid::update(vector<Boid> &boids) {

flock(boids);

direction += acceleration;   // Update direction
direction.x = ofClamp(direction.x, -maxspeed, maxspeed);  // Limit speed
direction.y = ofClamp(direction.y, -maxspeed, maxspeed);  // Limit speed
location += direction;
acceleration = 0;  // Reset accelertion to 0 each cycle

if (location.x < -r) location.x = ofGetWidth()+r;
if (location.y < -r) location.y = ofGetHeight()+r;

if (location.x > ofGetWidth()+r) location.x = -r;
if (location.y > ofGetHeight()+r) location.y = -r;
}

//SEEK
void Boid::seek(ofVec2f target) {
acceleration += steer(target, false);
}



// A method that calculates a steering vector towards a target
// Takes a second argument, if true, it slows down as it approaches the target
ofVec2f Boid::steer(ofVec2f target, bool slowdown) {
   ofVec2f steer;  // The steering vector
   ofVec2f desired = target - location;  // A vector pointing from the location to the target

float d = ofDist(target.x, target.y, location.x, location.y); // Distance from the target is the magnitude of the vector


// If the distance is greater than 0, calc steering (otherwise return zero vector)
if (d > 0) {

    desired /= d; // Normalize desired

    // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
    if ((slowdown) && (d < 100.0f)) {
        desired *= maxspeed * (d/100.0f); // This damping is somewhat arbitrary
    } else {
        desired *= maxspeed;
    }
    // Steering = Desired minus direction
    steer = desired - direction;
    steer.x = ofClamp(steer.x, -attraction, attraction); // Limit to maximum steering force
    steer.y = ofClamp(steer.y, -attraction, attraction); 

}
return steer;
}



//----------FLOCKING-BEHAVIOUR-------------------------------------------

void Boid::flock(vector<Boid> &boids) {
ofVec2f Seperation = separate(boids);
ofVec2f Alignment = align(boids);
ofVec2f Cohesion = cohesion(boids);

// Arbitrarily weight these forces
Seperation *= 1.5;
Alignment *= 1.0;
Cohesion *= 1.0;

acceleration += Seperation + Alignment + Cohesion;
}

//--SEPERATION--
// Method checks for nearby boids and steers away
ofVec2f Boid::separate(vector<Boid> &boids) {
float desiredseparation = 30.0;
ofVec2f steer;
int count = 0;

// For every boid in the system, check if it's too close
for (int i = 0 ; i < boids.size(); i++) {
    Boid &other = boids[i];

    float d = ofDist(location.x, location.y, other.location.x, other.location.y);

    // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
    if ((d > 0) && (d < desiredseparation)) {
        // Calculate vector pointing away from neighbor
        ofVec2f diff = location - other.location;
        diff /= d;          // normalize
        diff /= d;        // Weight by distance
        steer += diff;
        count++;            // Keep track of how many
    }
}
// Average -- divide by how many
if (count > 0) {
    steer /= (float)count;
}


// As long as the vector is greater than 0
//float mag = sqrt(steer.x*steer.x + steer.y*steer.y);

float mag = sqrt(steer.x*steer.x + steer.y*steer.y);
if (mag > 0) {
    // Steering = Desired - direction
    steer /= mag;
    steer *= maxspeed;
    steer -= direction;
    steer.x = ofClamp(steer.x, -attraction, attraction);
    steer.y = ofClamp(steer.y, -attraction, attraction);
}
return steer;
}

//--ALIGNMENT--
// For every nearby boid in the system, calculate the average direction
ofVec2f Boid::align(vector<Boid> &boids) {
float neighbordist = 60.0;
ofVec2f steer;
int count = 0;
for (int i = 0 ; i < boids.size(); i++) {
    Boid &other = boids[i];

    float d = ofDist(location.x, location.y, other.location.x, other.location.y);
    if ((d > 0) && (d < neighbordist)) {
        steer += (other.direction);
        count++;
    }
}
if (count > 0) {
    steer /= (float)count;
}

// As long as the vector is greater than 0
float mag = sqrt(steer.x*steer.x + steer.y*steer.y);
if (mag > 0) {
    // Implement Reynolds: Steering = Desired - direction
    steer /= mag;
    steer *= maxspeed;
    steer -= direction;
    steer.x = ofClamp(steer.x, -attraction, attraction);
    steer.y = ofClamp(steer.y, -attraction, attraction);
}
return steer;
}

//--COHESION--
// For the average location (i.e. center) of all nearby boids, calculate steering vector towards     that location
ofVec2f Boid::cohesion(vector<Boid> &boids) {
float neighbordist = 50.0;
ofVec2f sum;   // Start with empty vector to accumulate all locations
int count = 0;
for (int i = 0 ; i < boids.size(); i++) {
    Boid &other = boids[i];
    float d = ofDist(location.x, location.y, other.location.x, other.location.y);
    if ((d > 0) && (d < neighbordist)) {
        sum += other.location; // Add location
        count++;
    }
}
if (count > 0) {
    sum /= (float)count;
    return steer(sum, false);  // Steer towards the location
}
return sum;
}

//--------------------------------------------------------------
bool isMouseMoving() {
static ofPoint pmouse;
ofPoint mouse(ofGetMouseX(),ofGetMouseY());
bool mouseIsMoving = (mouse!=pmouse);
pmouse = mouse;
return mouseIsMoving;
}

vector 初始化:

std::vector<Boid*> boids;

-

//--------------------------------------------------------------
void testApp::setup() {
ofSetBackgroundAuto(false);
ofBackground(0,0,0);
ofSetFrameRate(60);
ofEnableAlphaBlending();
for(int i=0; i<10; i++) 
{
    boids.push_back(new Team1());
    //boids.push_back(Boid());
}
}

//--------------------------------------------------------------
void testApp::update() {


    for(int i=0; i<boids.size(); i++) {            
        boids[i]->seek(ofPoint(mouseX,mouseY));
    }



    for(int i=0; i<boids.size(); i++) {
        boids[i]->update(boids);
    }

}

//--------------------------------------------------------------
void testApp::draw() {

ofSetColor(0,0,0,20);
ofRect(0,0,ofGetWidth(),ofGetHeight());

for(int i=0; i<boids.size(); i++) 
{
    boids[i]->draw();
}
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button) {


boids.push_back(new Team1(x,y));
    ////boids.push_back(Boid());
    //boids.push_back(Boid(x,y));
}

最佳答案

从错误来看,您似乎有一个 std::vector<Boid> .你需要持有Boids多态的,所以你的 vector 应该保存(最好是智能)指向 Boid 的指针:

std::vector<Boid*> boids;

std::vector<std::unique_ptr<Boid>> boids;

然后你可以这样填写:

boids.push_back(new Team1());

boids.push_back(std::unique_ptr<Boid>(new Team1()));

分别。

请注意 std::unique_ptr需要 C++11 支持。更多关于 smart pointers here .

关于c++ - 将继承与基于 stdvector 的植绒结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13253116/

有关c++ - 将继承与基于 stdvector 的植绒结合使用的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby-on-rails - 结合 meta_search 与 acts_as_taggable_on - 2

    我在开发的Rails3网站的一些搜索功能上遇到了一个小问题。我有一个简单的Post模型,如下所示:classPost我正在使用acts_as_taggable_on来更轻松地向我的帖子添加标签。当我有一个标记为“rails”的帖子并执行以下操作时,一切正常:@posts=Post.tagged_with("rails")问题是,我还想搜索帖子的标题。当我有一篇标题为“Helloworld”并标记为“rails”的帖子时,我希望能够通过搜索“hello”或“rails”来找到这篇帖子。因此,我希望标题列的LIKE语句与acts_as_taggable_on提供的tagged_with方法

  10. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

随机推荐