You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

196 lines
7.1 KiB

#ifndef BUSBAR_SEGMENT_HPP
#define BUSBAR_SEGMENT_HPP
#include "point.hpp"
#include "vector3.hpp"
#include "busbar_types.hpp"
#include <vector>
#include <memory>
// ============================================================================
// BusbarSegment »ùÀà
// ============================================================================
class BusbarSegment {
protected:
SegmentType type_;
Point start_pos_;
Vector3 start_normal_;
Point end_pos_;
Vector3 end_normal_;
float width_;
float thickness_;
public:
BusbarSegment(SegmentType type,
const Point& start, const Vector3& start_normal,
const Point& end, const Vector3& end_normal,
float width, float thickness)
: type_(type), start_pos_(start), start_normal_(start_normal),
end_pos_(end), end_normal_(end_normal),
width_(width), thickness_(thickness) {}
virtual ~BusbarSegment() = default;
// ´¿Ð麯Êý
virtual std::vector<Point> getOccupiedVoxels() const = 0;
virtual float getLength() const = 0;
virtual float getCost() const { return getLength(); }
virtual Vector3 getStartTangent() const = 0;
virtual Vector3 getEndTangent() const = 0;
// ·ÃÎÊÆ÷
SegmentType type() const { return type_; }
Point startPos() const { return start_pos_; }
Point endPos() const { return end_pos_; }
Vector3 startNormal() const { return start_normal_; }
Vector3 endNormal() const { return end_normal_; }
float width() const { return width_; }
float thickness() const { return thickness_; }
};
// ============================================================================
// StraightSegment£¨Ö±¶Î£©
// ============================================================================
class StraightSegment : public BusbarSegment {
public:
StraightSegment(const Point& start, const Vector3& start_normal,
const Point& end, const Vector3& end_normal,
float width, float thickness)
: BusbarSegment(SegmentType::STRAIGHT, start, start_normal,
end, end_normal, width, thickness) {}
std::vector<Point> getOccupiedVoxels() const override;
float getLength() const override;
Vector3 getStartTangent() const override;
Vector3 getEndTangent() const override;
};
// ============================================================================
// FlatBendSegment£¨Æ½Íä¶Î£©
// - ´Óˮƽ·½ÏòÍäÏò´¹Ö±·½Ïò£¨»ò·´Ïò£©
// - ¹Ì¶¨90¶ÈÍäÇú
// - ÍäÇú°ë¾¶ = f ¡Á H
// - ·¨Ïò¸Ä±ä90¶È
// - »áµ¼ÖÂZÖá±ä»¯
// ============================================================================
class FlatBendSegment : public BusbarSegment {
private:
Point center_; // Ô²ÐÄλÖÃ
float radius_; // ÍäÇú°ë¾¶
bool upward_; // true=ÏòÉÏÍä, false=ÏòÏÂÍä
public:
FlatBendSegment(const Point& start, const Vector3& start_normal,
const Point& end, const Vector3& end_normal,
float width, float thickness,
const Point& center, float radius, bool upward)
: BusbarSegment(SegmentType::FLAT_BEND, start, start_normal,
end, end_normal, width, thickness),
center_(center), radius_(radius), upward_(upward) {}
std::vector<Point> getOccupiedVoxels() const override;
float getCost() const override { return getLength() * 1.3f; }
float getLength() const override { return radius_ * M_PI / 2.0f; } // 90¶È»¡³¤
Vector3 getStartTangent() const override;
Vector3 getEndTangent() const override;
Point center() const { return center_; }
float radius() const { return radius_; }
bool isUpward() const { return upward_; }
};
// ============================================================================
// VerticalBendSegment£¨Á¢Íä¶Î£©
// - ÔÚË®Æ½ÃæÄÚÍäÇú
// - ZÖá²»±ä£¨»ò±ä»¯¼«Ð¡£©
// - ÍäÇú°ë¾¶ = v ¡Á W
// - ·¨Ïò±£³Ö²»±ä£¨Ê¼ÖÕÊúÖ±£©
// - ÏñÌùÔÚµØÉϵÄÔ²»·
// ============================================================================
class VerticalBendSegment : public BusbarSegment {
private:
Point center_; // Ô²ÐÄλÖã¨Z×ø±êÓëÆðµãÏàͬ£©
float radius_; // ÍäÇú°ë¾¶
float angle_; // ÍäÇú½Ç¶È£¨»¡¶È£©£º¡À90¡ã, ¡À180¡ãµÈ,¿ÉÀ©Õ¹ÎªÆäËû½Ç¶È
public:
VerticalBendSegment(const Point& start, const Vector3& start_normal,
const Point& end, const Vector3& end_normal,
float width, float thickness,
const Point& center, float radius, float angle)
: BusbarSegment(SegmentType::VERTICAL_BEND, start, start_normal,
end, end_normal, width, thickness),
center_(center), radius_(radius), angle_(angle) {}
std::vector<Point> getOccupiedVoxels() const override;
float getCost() const override { return getLength() * 1.3f; }
float getLength() const override { return radius_ * std::abs(angle_); }
Vector3 getStartTangent() const override;
Vector3 getEndTangent() const override;
Point center() const { return center_; }
float radius() const { return radius_; }
float angle() const { return angle_; }
};
// ============================================================================
// TwistSegment£¨Å¤×ª¶Î£©
// - ÑØ³¤¶È·½ÏòŤת
// - ·¨ÏòÐýת¡À90¶È
// - Ťת³¤¶È = t ¡Á W
// ============================================================================
class TwistSegment : public BusbarSegment {
private:
float twist_angle_; // Ťת½Ç¶È£¨»¡¶È£©£¬Ä¿Ç°¹Ì¶¨90¶È
public:
TwistSegment(const Point& start, const Vector3& start_normal,
const Point& end, const Vector3& end_normal,
float width, float thickness,
float twist_angle)
: BusbarSegment(SegmentType::TWIST, start, start_normal,
end, end_normal, width, thickness),
twist_angle_(twist_angle) {}
std::vector<Point> getOccupiedVoxels() const override;
float getCost() const override { return getLength() * 2.5f; }
float getLength() const override;
Vector3 getStartTangent() const override;
Vector3 getEndTangent() const override;
float twistAngle() const { return twist_angle_; }
};
// ============================================================================
// Bend45Segment
// - µÈЧÓÚ2±¶ºñ¶ÈµÄÁ¢Íä
// - ÔÚË®Æ½ÃæÄÚתÍ䣬ZÖá²»±ä
// - ·¨Ïò±£³Ö²»±ä
// ============================================================================
class Bend45Segment : public BusbarSegment {
private:
Point center_;
float radius_;
bool is_positive_; // true = ÏòÉÏ·­, false = ÏòÏ·­
public:
Bend45Segment(const Point& start, const Vector3& start_normal,
const Point& end, const Vector3& end_normal,
float width, float thickness,
const Point& center, float radius, bool is_positive)
: BusbarSegment(SegmentType::BEND_45, start, start_normal,
end, end_normal, width, thickness),
center_(center), radius_(radius), is_positive_(is_positive) {}
std::vector<Point> getOccupiedVoxels() const override;
float getCost() const override { return getLength() * 1.3f; }
float getLength() const override { return radius_ * M_PI / 4.0f; }
Vector3 getStartTangent() const override;
Vector3 getEndTangent() const override;
float getAngle() const { return is_positive_ ? M_PI / 4.0f : -M_PI / 4.0f; }
Point center() const { return center_; }
float radius() const { return radius_; }
};
#endif