裂缝 高导缝 画图

This commit is contained in:
crqiqi77 2026-04-14 11:03:11 +08:00
parent 2453ae90b3
commit 6cf2bc43f1
6 changed files with 1691 additions and 1304 deletions

View File

@ -48,12 +48,6 @@ public:
double getCpCoreValue() const;
void setCpCoreValue(double value);
// double getCpRotationAngle() const;
// void setCpRotationAngle(double value);
// QString getCpDisplayName() const;
// void setCpDisplayName(const QString &value);
int getCpLineWidth() const;
void setCpLineWidth(int value);
@ -72,9 +66,6 @@ public:
int getCpScaleType() const;
void setCpScaleType(int value);
// int getCpScaleDivisionsOrCustom() const;
// void setCpScaleDivisionsOrCustom(int value);
QString getCpDisplayUnit() const;
void setCpDisplayUnit(const QString &value);
@ -113,23 +104,16 @@ public:
QColor getCpSymbolFillColor() const;
void setCpSymbolFillColor(QColor value);
// int getCpFieldName() const;
// void setCpFieldName(const int &value);
signals:
void rangeChanged(QCPRange newRange);
private:
// double m_cp_rotationAngle; // 旋转角度
// QString m_cp_displayName; // 显示名称
int m_cp_lineWidth; // 线宽
QColor m_cp_lineColor; // 线条颜色
Qt::PenStyle m_cp_lineStyle; // 线型
double m_cp_leftScale = 0; // 左刻度
double m_cp_rightScale = 100; // 右刻度
int m_cp_scaleType = 0; // 刻度类型
// int m_cp_scaleDivisionsOrCustom; // 等分刻度数或自定序列
QString m_cp_displayUnit; // 显示单位
QString m_cp_curveName; // 曲线名称
QString m_cp_curveUnit; // 曲线单位
@ -143,7 +127,6 @@ private:
QColor m_cp_symbolBorderColor; // 边框颜色
int m_cp_symbolSize; // 大小
QColor m_cp_symbolFillColor; // 填充颜色
// int m_cp_fieldName; // 字段名称
// 这四个是slf文件保存读取的
int m_cp_order; // 序号
double m_cp_depth; // 深度

View File

@ -0,0 +1,247 @@
#include "TransparentDraggableCrackObject.h"
#include <QMouseEvent>
#include <QWheelEvent>
#include <cmath>
QList<TransparentDraggableCrackObject*> TransparentDraggableCrackObject::s_allCurves;
TransparentDraggableCrackObject* TransparentDraggableCrackObject::s_activeCurve = nullptr;
TransparentDraggableCrackObject::TransparentDraggableCrackObject(QMyCustomPlot *parentPlot,
const QString &strUuid,
double depth)
: QObject(parentPlot)
, mPlot(parentPlot)
, m_depth(depth)
, m_endX(mPlot->m_iX2)
, m_orig_x1(m_endX * 0.18)
, m_orig_x2(m_endX * 0.82)
, m_orig_y1(depth + 1.0)
, m_orig_y2(depth - 1.0)
, m_orig_startX(0)
, m_orig_endX(m_endX)
, m_orig_startDirX(m_endX * 0.3)
, m_orig_endDirX(m_endX * 0.7)
, m_offsetX(0.0)
, m_offsetY(0.0)
{
mPlot->setInteraction(QCP::iRangeDrag, false);
mPlot->setInteraction(QCP::iRangeZoom, true);
mCurve = new QCPItemCurve(mPlot);
mCurve->setPen(QPen(Qt::black, 2));
mCurve->setLayer("overlay");
updateCurveFromTargets();
updateCurvePosition();
auto createTracer = [this](double x, double y, const QColor &color) -> QCPItemTracer* {
QCPItemTracer *t = new QCPItemTracer(mPlot);
t->setStyle(QCPItemTracer::tsCircle);
t->setSize(12);
t->setPen(QPen(Qt::black, 1));
t->setBrush(QBrush(color));
t->setSelectable(true);
t->setLayer("overlay");
t->position->setCoords(x, y);
return t;
};
m_tracer1 = createTracer(m_orig_x1, m_orig_y1, Qt::cyan);
m_tracer2 = createTracer(m_orig_x2, m_orig_y2, Qt::cyan);
updateTracers();
// 注册到全局列表
s_allCurves.append(this);
mPlot->installEventFilter(this);
mPlot->replot();
}
TransparentDraggableCrackObject::~TransparentDraggableCrackObject()
{
s_allCurves.removeAll(this);
if (s_activeCurve == this) s_activeCurve = nullptr;
}
void TransparentDraggableCrackObject::updateCurveFromTargets()
{
double t1 = m_orig_x1 / m_endX;
double t2 = m_orig_x2 / m_endX;
double u1 = 1 - t1, u2 = 1 - t2;
double P0x = 0, P0y = m_depth;
double P3x = m_endX, P3y = m_depth;
double P1x = m_orig_x1, P2x = m_orig_x2;
double a11 = 3 * u1 * u1 * t1;
double a12 = 3 * u1 * t1 * t1;
double b1 = m_orig_y1 - (u1*u1*u1 * P0y + t1*t1*t1 * P3y);
double a21 = 3 * u2 * u2 * t2;
double a22 = 3 * u2 * t2 * t2;
double b2 = m_orig_y2 - (u2*u2*u2 * P0y + t2*t2*t2 * P3y);
double det = a11 * a22 - a12 * a21;
if (fabs(det) > 1e-6) {
double P1y = (b1 * a22 - a12 * b2) / det;
double P2y = (a11 * b2 - b1 * a21) / det;
m_orig_startDirX = P1x;
m_orig_startDirY = P1y;
m_orig_endDirX = P2x;
m_orig_endDirY = P2y;
}
}
void TransparentDraggableCrackObject::updateCurvePosition()
{
mCurve->start->setCoords(m_orig_startX + m_offsetX, m_depth + m_offsetY);
mCurve->end->setCoords(m_orig_endX + m_offsetX, m_depth + m_offsetY);
mCurve->startDir->setCoords(m_orig_startDirX + m_offsetX, m_orig_startDirY + m_offsetY);
mCurve->endDir->setCoords(m_orig_endDirX + m_offsetX, m_orig_endDirY + m_offsetY);
}
void TransparentDraggableCrackObject::updateTracers()
{
m_tracer1->position->setCoords(m_orig_x1 + m_offsetX, m_orig_y1 + m_offsetY);
m_tracer2->position->setCoords(m_orig_x2 + m_offsetX, m_orig_y2 + m_offsetY);
}
void TransparentDraggableCrackObject::setTracerHighlight(QCPItemTracer *tracer, bool highlight)
{
if (!tracer) return;
if (highlight) {
tracer->setPen(QPen(Qt::red, 2));
tracer->setBrush(QBrush(Qt::red));
} else {
tracer->setPen(QPen(Qt::black, 1));
tracer->setBrush(QBrush(Qt::cyan));
}
mPlot->replot();
}
bool TransparentDraggableCrackObject::eventFilter(QObject *obj, QEvent *event)
{
if (obj != mPlot) return false;
if (event->type() == QEvent::Wheel) return false;
QMouseEvent *me = static_cast<QMouseEvent*>(event);
switch (event->type()) {
case QEvent::MouseButtonPress:
if (me->button() == Qt::LeftButton) {
QPointF pixel = me->localPos();
// 找出所有曲线中命中距离最近的那个
TransparentDraggableCrackObject* bestCurve = nullptr;
double bestDist = 1e9;
int hitType = -1; // 0:point1, 1:point2, 2:curve
for (auto *curve : s_allCurves) {
double d1 = curve->m_tracer1->selectTest(pixel, false);
double d2 = curve->m_tracer2->selectTest(pixel, false);
double dCurve = curve->mCurve->selectTest(pixel, false);
if (d1 >= 0 && d1 < 15 && d1 < bestDist) {
bestDist = d1;
bestCurve = curve;
hitType = 0;
}
if (d2 >= 0 && d2 < 15 && d2 < bestDist) {
bestDist = d2;
bestCurve = curve;
hitType = 1;
}
if (dCurve >= 0 && dCurve < 20 && dCurve < bestDist) {
bestDist = dCurve;
bestCurve = curve;
hitType = 2;
}
}
if (bestCurve) {
// 清除当前活动曲线的高亮
if (s_activeCurve && s_activeCurve != bestCurve) {
s_activeCurve->setTracerHighlight(s_activeCurve->m_tracer1, false);
s_activeCurve->setTracerHighlight(s_activeCurve->m_tracer2, false);
s_activeCurve->m_dragState = Idle;
}
s_activeCurve = bestCurve;
if (hitType == 0) {
s_activeCurve->m_dragState = DraggingPoint1;
s_activeCurve->setTracerHighlight(s_activeCurve->m_tracer1, true);
} else if (hitType == 1) {
s_activeCurve->m_dragState = DraggingPoint2;
s_activeCurve->setTracerHighlight(s_activeCurve->m_tracer2, true);
} else {
s_activeCurve->m_dragState = DraggingCurve;
s_activeCurve->m_lastDragPixel = pixel;
}
event->accept();
return true;
} else {
// 未命中任何曲线,清除活动曲线
if (s_activeCurve) {
s_activeCurve->setTracerHighlight(s_activeCurve->m_tracer1, false);
s_activeCurve->setTracerHighlight(s_activeCurve->m_tracer2, false);
s_activeCurve->m_dragState = Idle;
s_activeCurve = nullptr;
mPlot->replot();
}
return false;
}
}
break;
case QEvent::MouseMove:
if (s_activeCurve != this) return false;
if (m_dragState == DraggingPoint1 || m_dragState == DraggingPoint2) {
double newY = mPlot->yAxis->pixelToCoord(me->localPos().y());
double currentAbsY1 = m_orig_y1 + m_offsetY;
double deltaY = newY - currentAbsY1;
if (m_dragState == DraggingPoint1) {
m_orig_y1 += deltaY;
m_orig_y2 -= deltaY;
} else {
m_orig_y2 += deltaY;
m_orig_y1 -= deltaY;
}
updateCurveFromTargets();
updateCurvePosition();
updateTracers();
mPlot->replot();
event->accept();
return true;
} else if (m_dragState == DraggingCurve) {
QPointF currentPixel = me->localPos();
double oldX = mPlot->xAxis->pixelToCoord(m_lastDragPixel.x());
double newX = mPlot->xAxis->pixelToCoord(currentPixel.x());
double oldY = mPlot->yAxis->pixelToCoord(m_lastDragPixel.y());
double newY = mPlot->yAxis->pixelToCoord(currentPixel.y());
double deltaX = newX - oldX;
double deltaY = newY - oldY;
if (fabs(deltaX) > 1e-6) m_offsetX += deltaX;
if (fabs(deltaY) > 1e-6) m_offsetY += deltaY;
updateCurvePosition();
updateTracers();
mPlot->replot();
m_lastDragPixel = currentPixel;
event->accept();
return true;
}
break;
case QEvent::MouseButtonRelease:
if (me->button() == Qt::LeftButton && s_activeCurve == this) {
setTracerHighlight(m_tracer1, false);
setTracerHighlight(m_tracer2, false);
m_dragState = Idle;
s_activeCurve = nullptr;
mPlot->replot();
event->accept();
return true;
}
break;
default:
break;
}
return false;
}

View File

@ -0,0 +1,51 @@
#ifndef TRANSPARENTDRAGGABLECRACKOBJECT_H
#define TRANSPARENTDRAGGABLECRACKOBJECT_H
#include <QObject>
#include "qmycustomplot.h"
#include <QList>
class TransparentDraggableCrackObject : public QObject
{
Q_OBJECT
public:
explicit TransparentDraggableCrackObject(QMyCustomPlot *parentPlot,
const QString &strUuid = "",
double depth = 0);
~TransparentDraggableCrackObject();
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
static QList<TransparentDraggableCrackObject*> s_allCurves; // 所有曲线实例
static TransparentDraggableCrackObject* s_activeCurve; // 当前活动曲线
QMyCustomPlot *mPlot;
QCPItemCurve *mCurve;
double m_depth;
double m_endX;
double m_orig_x1, m_orig_x2;
double m_orig_y1, m_orig_y2;
double m_orig_startX, m_orig_endX;
double m_orig_startDirX, m_orig_startDirY;
double m_orig_endDirX, m_orig_endDirY;
double m_offsetX;
double m_offsetY;
QCPItemTracer *m_tracer1;
QCPItemTracer *m_tracer2;
enum DragState { Idle, DraggingPoint1, DraggingPoint2, DraggingCurve };
DragState m_dragState = Idle;
QPointF m_lastDragPixel;
void updateCurveFromTargets();
void updateCurvePosition();
void updateTracers();
void setTracerHighlight(QCPItemTracer *tracer, bool highlight);
};
#endif

View File

@ -44,6 +44,7 @@ SOURCES += \
QCPSizeHandle.cpp \
QCPSizeHandleManager.cpp \
TransparentDraggableCorePhysics.cpp \
TransparentDraggableCrackObject.cpp \
TransparentDraggableFac.cpp \
TransparentDraggableGeoLith.cpp \
TransparentDraggableGujing.cpp \
@ -110,6 +111,7 @@ HEADERS += \
QCPSizeHandle.h \
QCPSizeHandleManager.h \
TransparentDraggableCorePhysics.h \
TransparentDraggableCrackObject.h \
TransparentDraggableFac.h \
TransparentDraggableGeoLith.h \
TransparentDraggableGujing.h \

File diff suppressed because it is too large Load Diff

View File

@ -210,6 +210,7 @@ public:
QMap<QString, QObject*> m_mapDraggable_SelectRect;
QMap<QString, QObject*> m_mapDraggable_RightList;
QMap<QString, QObject*> m_mapDraggable_CorePhysics; // 岩心分析
QMap<QString, QObject*> m_mapDraggable_CrackObject; // 裂缝
QObject* m_SelectShiftLine=nullptr;//当前选中的分段线
@ -468,6 +469,9 @@ public slots:
void deleteCorePhysics(); //全部清空
void refreshCorePhysics(); //刷新数据
//右键--裂缝
void addCrackObject(); // 添加裂缝
//右键--编辑井壁取心
void addItem_SWallCore(); //增加井壁取心
void moveItems_SWallCore(); //平移水平位置