Пример #1
0
void Particle::draw() {
    glColor3fv(&color.red);
    float diam = 2*radius*view.relscale();	// set diameter in screen space
    if (diam<1.5) diam = 1.5;			// don't let them disappear
    glPointSize(diam); // sets diameter in screen space units, not world space
    glBegin(GL_POINTS);
    glVertex2f(pos[0], pos[1]);			// draw point
    glEnd();
}
Пример #2
0
Particle *World::pick_particle(int sx, int sy, View &view) {

    Vec2 q = view.screen_to_world(sx, sy);
	// transform screen space (sx,sy) to world space q

    Real thresh_world = thresh_screen/view.viewport.width/view.relscale(); 
	// threshold distance in world space

    int i;
    Real d, min = HUGE;
    Particle *nearest = NULL;
    for (i=0; i<n; i++) {
	d = sqrlen(pt[i].pos-q);		// distance squared
	if (d<min) {
	    min = d;
	    nearest = &pt[i];
	}
    }
    if (sqrt(min) > thresh_world) nearest = NULL;
    printf("World::pick_particle %d\n", nearest==NULL ? -1 : nearest-pt);
    return nearest;
}
Пример #3
0
void handle_event(XEvent *event) {
    /* see /usr/include/X11/X.h for definitions of X Windows event types */

    // you won't want to leave these printf's in here for your finished program,
    // but they should help you get started and debug.

    static int xprev, yprev, xstart, ystart;

    switch (event->type) {
	case ButtonPress:    /* button press */
	    printf("  ButtonPress.  button %d at (%d, %d)\n",
		event->xbutton.button, event->xbutton.x, event->xbutton.y);
	    switch (event->xbutton.button) {
		case 1:
		    world.curp = world.pick_particle(event->xbutton.x,
			event->xbutton.y, view);
		    if (!world.curp) break;
		    if (is_key_pressed(pane.display, XK_Shift_L) ||
		        is_key_pressed(pane.display, XK_Shift_R)) {
			    world.delete_particle(world.curp);
			    world.curp = NULL;
			}
		    else
			fl_set_slider_value(ui->mass_slider, world.curp->mass);
			    // set slider to show the mass of this particle
		    break;
		case 2:
		    {
			Vec2 p = view.screen_to_world(event->xbutton.x,
			    event->xbutton.y);
			world.curp = world.insert_particle(p[0], p[1], 0, 0,
			    fl_get_slider_value(ui->mass_slider));
		    }
		    break;
		case 3:
		    // save these for later use when MotionNotify event comes
		    xstart = xprev = event->xbutton.x;
		    ystart = yprev = event->xbutton.y;
		    break;
	    }
	    world.draw();
	    break;

	case ButtonRelease:  /* button release */
	    printf("  ButtonRelease. button %d\n", event->xbutton.button);
	    break;

	case MotionNotify:   /* mouse pointer moved */
	    printf("  MotionNotify at (%d, %d) state=%d=(%s %s %s)\n",
		event->xmotion.x, event->xmotion.y,
		event->xmotion.state,
		event->xmotion.state&Button1Mask ? "button1" : ".",
		event->xmotion.state&Button2Mask ? "button2" : ".",
		event->xmotion.state&Button3Mask ? "button3" : ".");
	    if (world.curp && (
		event->xmotion.state & (Button1Mask|Button2Mask))) {
		    /* printf("moving particle %d\n", world.curp-world.pt); */
		    world.curp->pos = view.screen_to_world(event->xmotion.x,
			event->xmotion.y);
	    }
	    else if (event->xmotion.state & Button3Mask) {
		if (is_key_pressed(pane.display, XK_Shift_L) ||
		    is_key_pressed(pane.display, XK_Shift_R)) {
			float s = 1. + (event->xmotion.x - xprev)/100.;
			/* printf("s=%g\n", s); */
			Vec2 pos = view.screen_to_world(xstart, ystart);
			// scale view around the point where user moused down
			glTranslatef(pos[0], pos[1], 0.);
			glScalef(s, s, 1.);
			glTranslatef(-pos[0], -pos[1], 0.);
		}
		else {
		    float t = view.viewport.width*view.relscale();
		    glTranslatef((event->xmotion.x - xprev)/t,
			-(event->xmotion.y - yprev)/t, 0.);
		}
		view.update();
		xprev = event->xmotion.x;
		yprev = event->xmotion.y;
	    }
	    world.draw();
	    break;

	case EnterNotify:       /* mouse pointer entered window */
	    printf("  EnterNotify.\n");
	    break;

	case LeaveNotify:       /* mouse pointer left window */
	    printf("  LeaveNotify.\n");
	    break;

	case KeyPress:          /* key pressed */
	case KeyRelease:        /* key released */
	    {
		char buf[10];
		int n;
		KeySym keysym;

		printf(event->type==KeyPress ? "  KeyPress." : "  KeyRelease.");
		n = XLookupString(&event->xkey, buf, sizeof buf - 1,
		    &keysym, 0);
		buf[n] = 0;
		/* print key as ascii and in hexadecimal */
		/* see /usr/include/X11/keysymdef.h for key codes */
		printf(" key=(%c)=0x%x\n", keysym, keysym);
	    }
	    break;

	case Expose:            /* window just uncovered */
	    printf("  Expose.\n");
	    world.draw();
	    break;

	case VisibilityNotify:  /* window occluded or exposed */
	    printf("  VisibilityNotify.\n");
	    break;

	default:
	    printf("  unknown event type.\n");
	    break;
    }
}