int Cam_int::zoom2( CEvent &e, State *& ) { if (debug_fsa) cerr << "Cam_int::zoom2" << endl; DEVice_2d *ptr = (DEVice_2d *)e._d; CAMptr cam (e.view()->cam()); PIXEL curpt (ptr->cur()); XYpt startpt(_start_pix); int w,h; e.view()->get_size(w,h); double zoom_factor = 1 + Sign(ptr->delta()[0]) * (PIXEL(ptr->cur())-PIXEL(ptr->old())).length()/(w/4); cam->set_zoom(cam->zoom() * zoom_factor); cam->set_min (cam->min() + NDCvec(XYpt(_start_pix) - startpt)); ptr->set_cur(curpt); cam->data()->changed(); return 0; }
int Cam_int::rot( CEvent &e, State *& ) { if (debug_fsa) cerr << "Cam_int::rot" << endl; CAMptr cam (e.view()->cam()); CAMdataptr data(cam->data()); DEVice_2d *ptr=(DEVice_2d *)e._d; cam->set_zoom(1); cam->set_min(NDCpt(XYpt(-1,-1))); cam->data()->changed(); XYpt cpt = data->center(); double radsq = sqr(1+fabs(cpt[0])); // squared rad of virtual cylinder XYpt tp = ptr->old(); XYpt te = ptr->cur(); Wvec op (tp[0], 0, 0); // get start and end X coordinates Wvec oe (te[0], 0, 0); // of cursor motion double opsq = op * op, oesq = oe * oe; double lop = opsq > radsq ? 0 : sqrt(radsq - opsq); double loe = oesq > radsq ? 0 : sqrt(radsq - oesq); Wvec nop = Wvec(op[0], 0, lop).normalized(); Wvec noe = Wvec(oe[0], 0, loe).normalized(); double dot = nop * noe; if (fabs(dot) > 0.0001) { data->rotate(Wline(data->center(), Wvec::Y()), -2*Acos(dot) * Sign(te[0]-tp[0])); double rdist = te[1]-tp[1]; CAMdata dd = CAMdata(*data); Wline raxe(data->center(),data->right_v()); data->rotate(raxe, rdist); data->set_up(data->from() + Wvec::Y()); if (data->right_v() * dd.right_v() < 0) *data = dd; } return 0; }