原理分析
鼠标中心缩放的核心原理是通过视口变换矩阵调整摄像机位置或投影参数。OpenCASCADE通过和
StartZoomAtPoint两个关键方法实现:
ZoomAtPoint
视点锚定:将鼠标当前位置作为缩放中心点,避免传统缩放导致的视觉偏移。模拟拖动:通过计算虚拟位移量(delta)触发动态缩放效果,实际是修改投影矩阵的缩放因子。
关键概念
1. 视口坐标系转换
鼠标坐标()需转换为OpenCASCADE内部使用的视口坐标系。OCC视图默认原点在左上角,Y轴向下为正方向。
mx, my
2. 滚轮刻度处理
高精度滚轮事件返回的数值以120为基本单位。正值表示滚轮向前(放大),负值表示向后(缩小)。
angleDelta()
3. 缩放因子计算
固定比例系数(示例为1.1)控制缩放幅度。通过判断滚轮方向决定放大或缩小:
zoomFactor
放大:缩小:
scale = zoomFactor
scale = 1.0 / zoomFactor
代码实现解析
步骤1:获取鼠标位置
const QPoint pos = theEvent->position().toPoint();
const Standard_Integer mx = pos.x();
const Standard_Integer my = pos.y();
将Qt的浮点坐标转换为整型,适应OCC接口要求。
步骤2:处理滚轮事件
const int steps = theEvent->angleDelta().y() / 120;
if (steps == 0) { theEvent->accept(); return; }
过滤无效事件(如横向滚轮),避免不必要的计算。
步骤3:计算缩放比例
const Standard_Real zoomFactor = 1.1;
const Standard_Real scale = (steps > 0) ? zoomFactor : 1.0 / zoomFactor;
通过三元运算符快速确定缩放方向。
步骤4:执行缩放操作
myView->StartZoomAtPoint(mx, my);
const Standard_Integer delta = (steps > 0) ? -10 : 10;
myView->ZoomAtPoint(mx, my, mx + delta, my + delta);
:锁定当前鼠标位置为缩放中心。
StartZoomAtPoint:通过虚拟位移触发动态缩放。正负delta控制放大/缩小方向。
ZoomAtPoint
扩展优化
非线性缩放
可通过动态调整实现加速缩放效果:
zoomFactor
const Standard_Real zoomFactor = 1.0 + 0.1 * abs(steps);
视口边界保护
添加边界检查防止过度缩放:
if (myView->Scale() > MAX_SCALE || myView->Scale() < MIN_SCALE) return;
完整代码
void wheelEvent(QWheelEvent* theEvent)
{
if (myView.IsNull()) return;
const QPoint pos = theEvent->position().toPoint();
const Standard_Integer mx = pos.x();
const Standard_Integer my = pos.y();
// 高分辨率滚轮:每120为一刻度
const int steps = theEvent->angleDelta().y() / 120;
if (steps == 0) { theEvent->accept(); return; }
// 使用OpenCASCADE内置的缩放功能
const Standard_Real zoomFactor = 1.1;
const Standard_Real scale = (steps > 0) ? zoomFactor : 1.0 / zoomFactor;
// 以鼠标位置为中心进行缩放
myView->StartZoomAtPoint(mx, my);
// 模拟拖动来缩放
const Standard_Integer delta = (steps > 0) ? -10 : 10;
myView->ZoomAtPoint(mx, my, mx + delta, my + delta);
theEvent->accept(); // 已处理,不传递给 QWidget
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END
















暂无评论内容