struct LinePoint {
Vector2 position;
float distance;
}
class HandDrawLine {
public:
void StartDraw(Vector2 start_pos)
void AddPoint(Vector2 new_pos); // 鼠标每移动 5.0f 距离添加一个新点 (意思是连续的线由一个个线段拼起来)
void EndDraw();
void RenderLine(); // 根据 points_ 画出一个个线段,连起来看就是一条直线了
float GetTotalLength() const { return total_length_; }
bool IsDrawing() const { return is_drawing_; }
bool IsCurrentlyDrawing() const { return is_drawing_; }
bool IsEmpty() const { return points.size() < 2; }
private:
std::vector<LinePoint> points_;
float total_length_;
bool is_drawing_;
}
HandDrawLine::HandDrawLine() {}
HandDrawLine::~HandDrawLine() {}
void HandDrawLine::StartDraw(Vector2 start_pos) {
points.clear();
points.emplace_back(start_pos, 0.0f);
total_length_ = 0.0f;
is_drawing_ = true;
}
void HandDrawLine::AddPoint(Vector2 new_pos) {
if (!is_drawing_ || points.empty()) return;
Vector2 last_pos = points.back().position;
float segment_length = sqrt((pow(new_pos.x - last_pos.x, 2) + pow(new_pos.y - last_pos.y, 2)));
if (segment_length > 5.0f) {
total_length_ += segment_length;
points.emplace_back(new_pos, total_length_);
}
}
void HandDrawLine::EndDraw() { is_drawing_ = false; }
void HandDrawLine::RenderLine() {
if (points.size() < 2) return;
for (size_t i = 1; i < points.size(); i++) {
DrawLineEx(points[i].position, points[i + 1].position, 3.0f, BLUE);
}
}
Vector2 HandDrawLine::GetPositionAtDistance(float target_distance) const {
if (points.size() < 2) return {0, 0};
if (target_distance <= 0) return points.front().position;
if (target_distance >= total_length_) return points.back().position;
for (size_t i = 1; i < points.size(); i++) {
if (points[i].distance >= target_distance) {
Vector2 p1 = points[i - 1].position;
Vector2 p2 = points[i].position;
float segment_length = points[i].distance - points[i - 1].distance;
float t = (target_distance - points[i - 1].distance) / segment_length;
return {p1.x + t * (p2.x - p1.x), p1.y + t * (p2.y - p1.y)};
}
}
return points.back().position;
}