// #include loads up library files, the order can matter
// generally load glut.h last
#include <stdio.h> // this library is for standard input and output
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "glut.h"// this library is for glut the OpenGL Utility Toolkit
//this defines a constant for the array size
#define SPRAYSIZE 500
// the properties of a spray particle are defined in a struct
struct sprayParticle {
float x = 0; // current position x
float y = 0; // current position y
float startx = 0; // birth position x
float starty = 0; // birth position y
int startTime; // a birthtime in frames when it will be born
int startRange = 100; // the maximum time at which a birth can happen
bool started = false; // tracks whether the particle has benn born or not
float speed = 0.1;
float radius;
float startxd = 0; // starting direction vector x value
float startyd = 0; // startingdirection vestor y value
float xd = 0; // current direction vector x value
float yd = 0; // current direction vector x value
float alpha = 1.0; // transparency
};
int winWidth = 1000, winHeight = 1000;
int counter = 0;
time_t t;
sprayParticle spray[SPRAYSIZE];
float angle = 90; // the angle of the spray: 0 degrees is to the left,
// 90 degrees straight up, 180 to the right etc
float sprayWidth = 30;// the width of the spray in degrees
float sprayCenterX, sprayCenterY;
//variables for spray colour, set once per spray
float fr = 1; float fg = 1; float fb = 1;
// the gravity vector
float gx = 0;
float gy = -0.0005;
// the position of thepartcle ystem emitter, wher the rocket should be drawn
float rocketstartx = winWidth - 100, rocketstarty = winHeight - 100;
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0); // set what colour you want the background to be
glMatrixMode(GL_PROJECTION); // set the matrix mode, we will look at this later
gluOrtho2D(0.0, winWidth, 0.0, winHeight);
}
void circle(double radius, double xc, double yc) {
int i;
double angle = 2 * 3.1415 / 20; // circle is drawn using 20 line.
double circle_xy[40][2];
circle_xy[0][0] = radius + xc;
circle_xy[0][1] = yc;
glBegin(GL_POLYGON);
for (i = 1; i < 20; i++) {
circle_xy[i][0] = radius * cos(i *angle) + xc;
circle_xy[i][1] = radius * sin(i * angle) + yc;
glVertex2f(circle_xy[i - 1][0], circle_xy[i - 1][1]);
glVertex2f(circle_xy[i][0], circle_xy[i][1]);
}
glEnd();
}
void normalise(int i) {
float mag;
mag = sqrt((spray[i].xd*spray[i].xd) + (spray[i].yd*spray[i].yd));
spray[i].xd = spray[i].xd / mag;
spray[i].yd = spray[i].yd / mag;
}
// we calculate the direction vector of the current particle from the global
variable angle and spread
void setDirectionVector(int i) {
float minAngle, maxAngle, range, newangle;
double newAngleInRadians; // variable
int rangeInt;
minAngle = angle - (sprayWidth / 2.0); // calc the minimum angle the particle could move along
maxAngle = angle + (sprayWidth / 2.0); // calc the maximum angle
range = maxAngle - minAngle;
rangeInt = (int)(range*100.0);
newangle = minAngle + ((float)(rand() % rangeInt) / 100.0); // generate a random angle between mi and max angles
newAngleInRadians = (double)(newangle / 360.0)*(2 * 3.1415); // convert it to radians
spray[i].xd = (float)cos(newAngleInRadians);// calc the diection vector x value
spray[i].yd = (float)sin(newAngleInRadians);// calc the diection vector y value
}
void initspray() {
for (int i = 0; i < SPRAYSIZE; i++) {
spray[i].x = winWidth / 2; // set current start x position
spray[i].y = 100;// set current start y position
spray[i].startx = spray[i].x; spray[i].starty = spray[i].y;// set start x and y position
spray[i].speed = 0.1 + (float)(rand() % 150) / 1000.0;// speed is 0.1 to 0.25
spray[i].startTime = rand() % spray[i].startRange;// set birth time
spray[i].radius = (float)(rand() % 15); // random radius
setDirectionVector(i);// set the current direction vector
spray[i].startxd = spray[i].xd; spray[i].startyd = spray[i].yd; // set start direction vector to current
}
// set colour of spray
fr = 0.5 + (float)(rand() % 500) / 1000.0;
fg = 0.5 + (float)(rand() % 500) / 1000.0;
fb = 0.5 + (float)(rand() % 500) / 1000.0;
}
void drawsprayParticle(int i) {
glLineWidth(2);
if (!spray[i].started) {
if (counter == spray[i].startTime) {
spray[i].started = true;
}
}
if (spray[i].started) {
glColor4f(fr, fg, fb, spray[i].alpha); // white particiles
circle(spray[i].radius, spray[i].x, spray[i].y);
spray[i].x = spray[i].x + (spray[i].xd*spray[i].speed);
spray[i].y = spray[i].y + (spray[i].yd*spray[i].speed);
// this produces a direction vector that is a little longer than 1
spray[i].yd = spray[i].yd + gy;
// so the normalise the vector to make length 1
normalise(i);
// reduce transparency
spray[i].alpha -= 0.00015;
}
if (spray[i].x<0 || spray[i].x>winWidth + 500 || spray[i].y<0 || spray[i].y>winHeight) {
spray[i].x = spray[i].startx; spray[i].y = spray[i].starty; //rocketstartx
spray[i].xd = spray[i].startxd; spray[i].yd = spray[i].startyd;
spray[i].alpha = 1.0;
}
}
void drawspray() {
// draw each spray particle
for (int i = 0; i < SPRAYSIZE; i++) {
drawsprayParticle(i);
}
// increment rocket position
rocketstartx += 0.2;
// if the rocket is oof the screen more nad 500 pixels to the right the rest it to 0
if (rocketstartx > winWidth + 500) { rocketstartx = 0; }
counter++;
}
// This is the display function it is called when ever you want to draw something
void display() {
glClear(GL_COLOR_BUFFER_BIT); // clear the screen using the background colour
glColor3f(1.0, 1.0, 1.0); // set colour to white
drawspray();
glFlush(); // force all drawing to finish
}
// This is the idle function it is called whenever the program is idle
void idle() {
display();
}
// As with many programming languages the main() function is the entry point for execution of the program
int main(int argc, char** argv) {
srand((unsigned)time(&t));
// initialise first spray work
initspray();
glutInit(&argc, argv); //perform the GLUT initialization
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); // more initialisation
glutInitWindowSize(winWidth, winHeight); // set window position
glutInitWindowPosition(0, 0); // set window size
glutCreateWindow("Fire"); // create a display with a given caption for the title bar
glEnable(GL_BLEND); //Enable blending.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
init(); // call init function defined above
glutIdleFunc(idle); // define what function to call when the program is idle
glutDisplayFunc(display); // define what function to call to draw
glutMainLoop();
// this line exits the program
return 0;
}
上面的原始代码通常会创建一个在整个屏幕上喷射粒子的喷泉,但我更改了喷射的大小和范围,因此我可以创建一个火焰。问题是我无法阻止粒子的传播,它一直向上移动。我希望它留在原位。
最佳答案
用公式
spray[i].x = spray[i].x + (spray[i].xd*spray[i].speed);
spray[i].y = spray[i].y + (spray[i].yd*spray[i].speed);
点到它原点的距离线性增加。您必须逐渐降低速度才能平稳地接近极限位置。
例如
spray[i].speed *= 0.9992f;
当然,当点在其原点“重新开始”时,您必须保持速度 (spray[i].speed)。如果该点的速度或该点的 alpha 值低于阈值,则该点也必须“重新启动”:
void drawsprayParticle(int i) {
glLineWidth(2);
if (!spray[i].started) {
if (counter == spray[i].startTime) {
spray[i].started = true;
}
}
if (spray[i].started) {
glColor4f(fr, fg, fb, spray[i].alpha); // white particles
circle(spray[i].radius, spray[i].x, spray[i].y);
spray[i].x = spray[i].x + (spray[i].xd*spray[i].speed);
spray[i].y = spray[i].y + (spray[i].yd*spray[i].speed);
// this produces a direction vector that is a little longer than 1
spray[i].yd = spray[i].yd + gy;
// so the normalize the vector to make length 1
normalise(i);
// reduce transparency
spray[i].alpha -= 0.0003;
spray[i].speed *= 0.9992f;
}
if ( spray[i].x<0 || spray[i].x>winWidth + 500 ||
spray[i].y<0 || spray[i].y>winHeight ||
spray[i].alpha < 1.0f/256.0f ||
spray[i].speed < 0.04f ) {
spray[i].x = spray[i].startx; spray[i].y = spray[i].starty;
spray[i].xd = spray[i].startxd; spray[i].yd = spray[i].startyd;
spray[i].alpha = 1.0;
spray[i].speed = 0.1 + (float)(rand() % 150) / 1000.0;
}
}
这是一个经验算法,因此您必须使用这些值来获得您需要的效果。
此外,我增加了起始范围:int startRange = 1300;
预览:
关于c++ - 停止喷涂并保持原位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53833514/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t
关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby有很大不同。由于我与ruby之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?
我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat