diff --git a/CMakeLists.txt b/CMakeLists.txt
index 73fd37693f35e5528edbb07aa81cd1489e3cd5ce..843bc7e81f2e4ba63b2e9335561020e8b5154456 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -377,6 +377,8 @@ target_sources(petrack_core PRIVATE
     include/moCapSelectionWidget.h
     include/personStorage.h
     include/autosave.h
+    include/manualTrackpointMover.h
+    include/frameRange.h
     )
 
 target_sources(petrack_core PRIVATE
@@ -437,6 +439,7 @@ target_sources(petrack_core PRIVATE
     src/moCapSelectionWidget.cpp
     src/personStorage.cpp
     src/autosave.cpp
+    src/manualTrackpointMover.cpp
     ui/about.ui
     ui/codeMarker.ui
     ui/colorMarker.ui
diff --git a/include/frameRange.h b/include/frameRange.h
new file mode 100644
index 0000000000000000000000000000000000000000..b532d1d96127c94c388116a8a90d7e8af2e7a3a0
--- /dev/null
+++ b/include/frameRange.h
@@ -0,0 +1,31 @@
+/*
+ * PeTrack - Software for tracking pedestrians movement in videos
+ * Copyright (C) 2010-2022 Forschungszentrum Jülich GmbH,
+ * Maik Boltes, Juliane Adrian, Ricardo Martin Brualla, Arne Graf, Paul Häger, Daniel Hillebrand,
+ * Deniz Kilic, Paul Lieberenz, Daniel Salden, Tobias Schrödter, Ann Katrin Seemann
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef FRAMERANGE_H
+#define FRAMERANGE_H
+
+struct FrameRange
+{
+    int before  = 0;
+    int after   = 0;
+    int current = 0;
+};
+
+#endif // FRAMERANGE_H
diff --git a/include/manualTrackpointMover.h b/include/manualTrackpointMover.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1df17693a10bde7122295e8d92222a57b5dcd3a
--- /dev/null
+++ b/include/manualTrackpointMover.h
@@ -0,0 +1,42 @@
+/*
+ * PeTrack - Software for tracking pedestrians movement in videos
+ * Copyright (C) 2010-2022 Forschungszentrum Jülich GmbH,
+ * Maik Boltes, Juliane Adrian, Ricardo Martin Brualla, Arne Graf, Paul Häger, Daniel Hillebrand,
+ * Deniz Kilic, Paul Lieberenz, Daniel Salden, Tobias Schrödter, Ann Katrin Seemann
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef MANUALTRACKPOINTMOVER_H
+#define MANUALTRACKPOINTMOVER_H
+
+#include "frameRange.h"
+#include "personStorage.h"
+
+class ManualTrackpointMover
+{
+public:
+    bool selectTrackPoint(
+        const QPointF       &pos,
+        const PersonStorage &personStore,
+        const QSet<int>     &peds,
+        const FrameRange    &range);
+    void moveTrackPoint(const QPointF &pos, PersonStorage &personStore) const;
+    void setTrackPoint();
+
+private:
+    PersonFrame mSelectedPerson = PersonFrame{-1, -1};
+};
+
+#endif // MANUALTRACKPOINTMOVER_H
diff --git a/include/personStorage.h b/include/personStorage.h
index 2798fe197471661e449a6a2b200bca694b7332d8..2b1286a88ea4d63a457949b9c5bebe33ff58f189 100644
--- a/include/personStorage.h
+++ b/include/personStorage.h
@@ -21,6 +21,7 @@
 #ifndef PERSONSTORAGE_H
 #define PERSONSTORAGE_H
 
+#include "frameRange.h"
 #include "tracker.h"
 
 #include <vector>
@@ -56,6 +57,7 @@ public:
     bool editTrackPersonComment(const Vec2F &p, int frame, const QSet<int> &onlyVisible);
     bool setTrackPersonHeight(const Vec2F &p, int frame, const QSet<int> &onlyVisible);
     bool resetTrackPersonHeight(const Vec2F &p, int frame, QSet<int> onlyVisible);
+    void moveTrackPoint(int personID, int frame, const Vec2F &newPosition);
 
     size_t                          nbPersons() const { return mPersons.size(); }
     const TrackPerson              &at(size_t i) const { return mPersons.at(i); }
@@ -82,8 +84,8 @@ public:
     int  largestFirstFrame() const;
     int  largestLastFrame() const;
     int  smallestFirstFrame() const;
-    std::vector<PersonFrame>
-         getProximalPersons(const QPointF &pos, int frame, QSet<int> selected, int before, int after) const;
+    [[nodiscard]] std::vector<PersonFrame>
+         getProximalPersons(const QPointF &pos, QSet<int> selected, const FrameRange &frameRange) const;
     void recalcHeight(float altitude);
 
     void clear() { mPersons.clear(); }
diff --git a/include/petrack.h b/include/petrack.h
index 59431550dca0612708628123f2d49fedd960d12e..f9278b2b844df116b6129da2c2c2aa2d2a7fa553 100644
--- a/include/petrack.h
+++ b/include/petrack.h
@@ -39,6 +39,7 @@
 #include "brightContrastFilter.h"
 #include "coordItem.h"
 #include "extrCalibration.h"
+#include "manualTrackpointMover.h"
 #include "moCapController.h"
 #include "moCapPerson.h"
 #include "personStorage.h"
@@ -156,6 +157,9 @@ public slots:
     void deleteTrackPointAll(PersonStorage::Direction direction);
     void deleteTrackPointROI();
     void deleteTrackPointInsideROI();
+    void moveTrackPoint(QPointF pos);
+    void selectPersonForMoveTrackPoint(QPointF pos);
+    void releaseTrackPoint();
     //    void showContextMenu(QPointF pos);
     void updateSourceInOutFrames();
     void skipToFrameWheel(int delta);
@@ -497,6 +501,8 @@ private:
     double        mHeadSize;
     double        mCmPerPixel;
 
+    ManualTrackpointMover mManualTrackPointMover;
+
     double mShowFPS;
 
     bool mAutoBackTrack;
diff --git a/include/view.h b/include/view.h
index 9dac4763ce83dcb17c2ad02bcfe12ba8224b5937..115e81661fb9b7032f9de849e70566e88955bd40 100644
--- a/include/view.h
+++ b/include/view.h
@@ -48,7 +48,10 @@ public:
     void wheelEvent(QWheelEvent *event) override;
     void mouseDoubleClickEvent(QMouseEvent *event) override;
     void keyPressEvent(QKeyEvent *event) override;
+    void keyReleaseEvent(QKeyEvent *event) override;
     void mousePressEvent(QMouseEvent *event) override;
+    void mouseReleaseEvent(QMouseEvent *event) override;
+    void mouseMoveEvent(QMouseEvent *event) override;
 
 signals:
     void mouseDoubleClick();
@@ -59,6 +62,10 @@ signals:
     void mouseRightDoubleClick(QPointF pos, int direction);
     void mouseMiddleDoubleClick(PersonStorage::Direction direction);
     void mouseShiftWheel(int delta);
+    void mouseAltPressed(QPointF pos);
+    void mouseAltReleased(QPointF pos);
+    void altReleased();
+    void mouseAltMoved(QPointF pos);
     void colorSelected();
     void setColorEvent();
 };
diff --git a/src/manualTrackpointMover.cpp b/src/manualTrackpointMover.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..52f76df9fdaef2ea7f64fbfefce5db28b6e6a52c
--- /dev/null
+++ b/src/manualTrackpointMover.cpp
@@ -0,0 +1,60 @@
+/*
+ * PeTrack - Software for tracking pedestrians movement in videos
+ * Copyright (C) 2010-2022 Forschungszentrum Jülich GmbH,
+ * Maik Boltes, Juliane Adrian, Ricardo Martin Brualla, Arne Graf, Paul Häger, Daniel Hillebrand,
+ * Deniz Kilic, Paul Lieberenz, Daniel Salden, Tobias Schrödter, Ann Katrin Seemann
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "manualTrackpointMover.h"
+
+#include "pMessageBox.h"
+
+bool ManualTrackpointMover::selectTrackPoint(
+    const QPointF       &pos,
+    const PersonStorage &personStore,
+    const QSet<int>     &peds,
+    const FrameRange    &range)
+{
+    auto res = personStore.getProximalPersons(pos, peds, range);
+
+    bool successfulSelection = res.size() == 1;
+
+    if(successfulSelection)
+    {
+        mSelectedPerson = res.front();
+    }
+    else if(res.size() > 1)
+    {
+        PWarning(
+            nullptr,
+            "Too many trajectories",
+            "PeTrack can't determine which point you meant. Try selecting fewer trajectories first.");
+    }
+    return successfulSelection;
+}
+
+void ManualTrackpointMover::moveTrackPoint(const QPointF &pos, PersonStorage &personStore) const
+{
+    if(mSelectedPerson.personID != -1 && mSelectedPerson.frame != -1)
+    {
+        personStore.moveTrackPoint(mSelectedPerson.personID, mSelectedPerson.frame, Vec2F{pos});
+    }
+}
+
+void ManualTrackpointMover::setTrackPoint()
+{
+    mSelectedPerson = {-1, -1};
+}
diff --git a/src/personStorage.cpp b/src/personStorage.cpp
index 8a7a091f5717163c444e2ea3a844a1370f497a07..fa08541d8d3c1fc11a4e6f21c6902889ea788f0c 100644
--- a/src/personStorage.cpp
+++ b/src/personStorage.cpp
@@ -404,6 +404,25 @@ bool PersonStorage::resetTrackPersonHeight(const Vec2F &point, int frame, QSet<i
     return false;
 }
 
+void PersonStorage::moveTrackPoint(int personID, int frame, const Vec2F &newPosition)
+{
+    auto      &person = mPersons.at(personID);
+    TrackPoint newPoint;
+    newPoint = newPosition;
+    newPoint.setQual(100);
+    if(person.trackPointExist(frame))
+    {
+        int idx     = frame - person.firstFrame();
+        person[idx] = newPoint;
+    }
+    else
+    {
+        // only logging since this is a software bug, not a user bug; precondition of function not fulfilled
+        debout << "Warning: Trying to move nonexisting trackpoint of person " << personID << " at frame " << frame
+               << std::endl;
+    }
+}
+
 // used for calculation of 3D point for all points in frame
 // returns number of found points or -1 if no stereoContext available (also points without disp found are counted)
 int PersonStorage::calcPosition(int /*frame*/)
@@ -711,7 +730,7 @@ int PersonStorage::smallestFirstFrame() const
  * @return list of the id of all proximal persons with the frame at which they are nearest to pos
  */
 std::vector<PersonFrame>
-PersonStorage::getProximalPersons(const QPointF &pos, int frame, QSet<int> selected, int before, int after) const
+PersonStorage::getProximalPersons(const QPointF &pos, QSet<int> selected, const FrameRange &frameRange) const
 {
     std::vector<PersonFrame> result;
     for(int i = 0; i < static_cast<int>(mPersons.size()); ++i)
@@ -723,14 +742,14 @@ PersonStorage::getProximalPersons(const QPointF &pos, int frame, QSet<int> selec
 
         double minDist  = std::numeric_limits<double>::max();
         int    minFrame = -1;
-        for(int f = frame - before; f <= frame + after; ++f)
+        for(int f = frameRange.current - frameRange.before; f <= frameRange.current + frameRange.after; ++f)
         {
             if(!mPersons[i].trackPointExist(f))
             {
                 continue;
             }
             auto dist = mPersons[i].trackPointAt(f).distanceToPoint(pos);
-            if(dist < minDist && dist < (mMainWindow.getHeadSize(nullptr, i, frame) / 2.))
+            if(dist < minDist && dist < (mMainWindow.getHeadSize(nullptr, i, frameRange.current) / 2.))
             {
                 minDist  = dist;
                 minFrame = f;
diff --git a/src/petrack.cpp b/src/petrack.cpp
index 169a7e6aae89e9437c352b226e9f2a2157df157f..22cdc5b2f46c318aa91128ae3d47b15b11346814 100644
--- a/src/petrack.cpp
+++ b/src/petrack.cpp
@@ -173,6 +173,11 @@ Petrack::Petrack() :
     connect(mView, &GraphicsView::mouseMiddleDoubleClick, this, &Petrack::deleteTrackPointAll);
     connect(mView, &GraphicsView::mouseShiftWheel, this, &Petrack::skipToFrameWheel);
     connect(mView, &GraphicsView::mouseAltDoubleClick, this, &Petrack::skipToFrameFromTrajectory);
+    connect(mView, &GraphicsView::mouseAltMoved, this, &Petrack::moveTrackPoint);
+    connect(mView, &GraphicsView::mouseAltPressed, this, &Petrack::selectPersonForMoveTrackPoint);
+    connect(mView, &GraphicsView::altReleased, this, &Petrack::releaseTrackPoint);
+    connect(mView, &GraphicsView::mouseAltReleased, this, &Petrack::releaseTrackPoint);
+
 
     mPlayerWidget = new Player(mAnimation, this);
 
@@ -1619,7 +1624,9 @@ void Petrack::keyBindings()
         "<dt><kbd>Alt + double-click middle mouse button</kbd></dt><dd>deletes the future part of all trajectories</dd>"
         "<dt><kbd>Shift + t</kbd></dt><dd>toggles tracking online calculation</dd>"
         "<dt><kbd>Shift + double-click left mouse button</kbd></dt><dd>inserts new or moves near trackpoint and "
-        "enables showing only the modified trajectory</dd></dl>"
+        "enables showing only the modified trajectory</dd>"
+        "<dt><kbd>Alt + double-click left mouse button</kbd></dt><dd>jumps to frame of trackpoint under cursor</dd>"
+        "<dt><kbd>Alt + holding left mouse button</kbd></dt><dd>moves trackpoint under cursor</dd></dl>"
         "<p>Further key bindings you will find next to the entries of the menus.</p>");
 
     PMessageBox *mb = new PMessageBox(this, tr("Key Bindings"), out, QIcon());
@@ -4214,6 +4221,35 @@ void Petrack::deleteTrackPointInsideROI()
     updateControlWidget();
     mScene->update();
 }
+
+void Petrack::moveTrackPoint(QPointF pos)
+{
+    mManualTrackPointMover.moveTrackPoint(pos, mPersonStorage);
+    mScene->update();
+}
+
+void Petrack::selectPersonForMoveTrackPoint(QPointF pos)
+{
+    FrameRange range;
+    range.before  = mControlWidget->trackShowBefore->value();
+    range.after   = mControlWidget->trackShowAfter->value();
+    range.current = mPlayerWidget->getPos();
+    auto successfullySelected =
+        mManualTrackPointMover.selectTrackPoint(pos, mPersonStorage, getPedestrianUserSelection(), range);
+
+    if(successfullySelected)
+    {
+        setCursor(QCursor{Qt::CursorShape::DragMoveCursor});
+    }
+}
+
+void Petrack::releaseTrackPoint()
+{
+    mManualTrackPointMover.setTrackPoint();
+    mAutosave.trackPersonModified();
+    setCursor(QCursor{});
+}
+
 void Petrack::updateSourceInOutFrames()
 {
     mPlayerWidget->setFrameInNum(mAnimation->getSourceInFrameNum());
@@ -4232,8 +4268,9 @@ void Petrack::skipToFrameFromTrajectory(QPointF pos)
     const auto before    = mControlWidget->trackShowBefore->value();
     const auto after     = mControlWidget->trackShowAfter->value();
     const auto currFrame = mPlayerWidget->getPos();
+    FrameRange frameRange{before, after, currFrame};
 
-    auto res = mPersonStorage.getProximalPersons(pos, currFrame, peds, before, after);
+    auto res = mPersonStorage.getProximalPersons(pos, peds, frameRange);
 
     if(res.size() == 1)
     {
diff --git a/src/view.cpp b/src/view.cpp
index 841c10e78c9af67e84d3996b43fe03929b04c42a..43d94aa2f572dae06a35996d951c397adbe09877 100644
--- a/src/view.cpp
+++ b/src/view.cpp
@@ -154,6 +154,16 @@ void GraphicsView::keyPressEvent(QKeyEvent *event)
     }
 }
 
+void GraphicsView::keyReleaseEvent(QKeyEvent *event)
+{
+    switch(event->key())
+    {
+        case Qt::Key_Alt:
+            emit altReleased();
+            break;
+    }
+}
+
 void GraphicsView::mousePressEvent(QMouseEvent *event)
 {
     if(event->modifiers() & Qt::ShiftModifier)
@@ -164,9 +174,35 @@ void GraphicsView::mousePressEvent(QMouseEvent *event)
     {
         emit colorSelected();
     }
+
+    if(event->modifiers().testFlag(Qt::AltModifier) && event->button() == Qt::LeftButton)
+    {
+        emit mouseAltPressed(mapToScene(event->pos()));
+    }
     QGraphicsView::mousePressEvent(event);
 }
 
+void GraphicsView::mouseReleaseEvent(QMouseEvent *event)
+{
+    if(event->modifiers().testFlag(Qt::AltModifier))
+    {
+        emit mouseAltReleased(mapToScene(event->pos()));
+    }
+    QGraphicsView::mouseReleaseEvent(event);
+}
+
+void GraphicsView::mouseMoveEvent(QMouseEvent *event)
+{
+    if(event->modifiers().testFlag(Qt::AltModifier))
+    {
+        emit mouseAltMoved(mapToScene(event->pos()));
+    }
+    else
+    {
+        QGraphicsView::mouseMoveEvent(event);
+    }
+}
+
 //---------------------------------------------------------------------