{"action":"created","issue":{"url":"https://api.github.com/repos/Siv3D/OpenSiv3D/issues/199","repository_url":"https://api.github.com/repos/Siv3D/OpenSiv3D","labels_url":"https://api.github.com/repos/Siv3D/OpenSiv3D/issues/199/labels{/name}","comments_url":"https://api.github.com/repos/Siv3D/OpenSiv3D/issues/199/comments","events_url":"https://api.github.com/repos/Siv3D/OpenSiv3D/issues/199/events","html_url":"https://github.com/Siv3D/OpenSiv3D/issues/199","id":253922460,"number":199,"title":"Circular型の改造案","user":{"login":"para7","id":18499975,"avatar_url":"https://avatars3.githubusercontent.com/u/18499975?v=4","gravatar_id":"","url":"https://api.github.com/users/para7","html_url":"https://github.com/para7","followers_url":"https://api.github.com/users/para7/followers","following_url":"https://api.github.com/users/para7/following{/other_user}","gists_url":"https://api.github.com/users/para7/gists{/gist_id}","starred_url":"https://api.github.com/users/para7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/para7/subscriptions","organizations_url":"https://api.github.com/users/para7/orgs","repos_url":"https://api.github.com/users/para7/repos","events_url":"https://api.github.com/users/para7/events{/privacy}","received_events_url":"https://api.github.com/users/para7/received_events","type":"User","site_admin":false},"labels":[{"id":677073562,"url":"https://api.github.com/repos/Siv3D/OpenSiv3D/labels/proposal","name":"proposal","color":"0e8a16","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-08-30T08:45:27Z","updated_at":"2017-08-30T18:52:17Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"```cpp\r\nnamespace s3d\r\n{\r\n\ttemplate<int32 Oclock>\r\n\tstruct Polar\r\n\t{\r\n\tprivate:\r\n\r\n\t\tstatic constexpr double Clock() noexcept\r\n\t\t{\r\n\t\t\treturn Oclock * (Math::TwoPi / 12);\r\n\t\t}\r\n\r\n\tpublic:\r\n\r\n\t\t// 中心\r\n\t\tVec2 center;\r\n\r\n\t\t// 半径\r\n\t\tdouble r;\r\n\r\n\t\t// 角度\r\n\t\tdouble theta;\r\n\r\n\t\t//デフォルトコンストラクタ\r\n\t\tPolar() = default;\r\n\r\n\t\t//コピーコンストラクタ\r\n\t\tPolar(const Polar& polar) noexcept = default;\r\n\r\n\t\tPolar(const Vec2& _center, double _r, double _theta) noexcept\r\n\t\t\t: center(_center)\r\n\t\t\t, r(_r)\r\n\t\t\t, theta(_theta)\r\n\t\t{}\r\n\r\n\t\t// 始点と終点を設定し、その関係を極座標で表現します\r\n\t\tPolar(const Vec2& center, const Vec2& pos)\r\n\t\t{\r\n\t\t\tconst Vec2 vec = pos - center;\r\n\r\n\t\t\t*this = Polar(pos, vec.length(), atan2(vec.y, vec.x) - Clock());\r\n\t\t}\r\n\r\n\t\tPolar operator +() const noexcept\r\n\t\t{\r\n\t\t\treturn *this;\r\n\t\t}\r\n\r\n\t\tPolar operator -() const noexcept\r\n\t\t{\r\n\t\t\treturn rotated(Math::Pi);\r\n\t\t}\r\n\r\n\t\tVec2 operator +(const Vec2& v) const noexcept\r\n\t\t{\r\n\t\t\treturn toVec2() + v;\r\n\t\t}\r\n\r\n\t\tVec2 operator -(const Vec2& v) const noexcept\r\n\t\t{\r\n\t\t\treturn toVec2() - v;\r\n\t\t}\r\n\r\n\t\t// 極座標が示す先の座標を取得\r\n\t\tVec2 toVec2() const\r\n\t\t{\r\n\t\t\treturn center.movedBy(std::sin(theta + Clock()) * r, -std::cos(theta + Clock()) * r);\r\n\t\t}\r\n\r\n\t\tFloat2 toFloat2() const\r\n\t\t{\r\n\t\t\treturn { center.x + std::sin(theta + Clock()) * r, center.y - std::cos(theta + Clock()) * r };\r\n\t\t}\r\n\r\n\t\toperator Vec2() const noexcept\r\n\t\t{\r\n\t\t\treturn toVec2();\r\n\t\t}\r\n\r\n\t\t// 始点を移動\r\n\t\tPolar& setCenter(const Vec2& _center)\r\n\t\t{\r\n\t\t\tcenter = _center;\r\n\t\t\treturn *this;\r\n\t\t}\r\n\r\n\t\t// 極座標が指し示す先を座標で指定し直す\r\n\t\tPolar& setPos(const Vec2& to)\r\n\t\t{\r\n\t\t\t*this = Polar(center, to);\r\n\t\t\treturn *this;\r\n\t\t}\r\n\r\n\t\t// 一時的に回転させる\r\n\t\tPolar rotated(double _theta) const\r\n\t\t{\r\n\t\t\tPolar polar(*this);\r\n\t\t\tpolar.theta += _theta;\r\n\t\t\treturn polar;\r\n\t\t}\r\n\r\n\t\t// 半径を変更した新しいオブジェクトを返す\r\n\t\tPolar resized(double _r) const noexcept\r\n\t\t{\r\n\t\t\tPolar polar(*this);\r\n\t\t\tpolar.r = _r;\r\n\t\t\treturn polar;\r\n\t\t}\r\n\r\n\t\t// 半径に倍率をかけた新しいオブジェクトを返す\r\n\t\tPolar scaled(double _scale) const\r\n\t\t{\r\n\t\t\tPolar polar(*this);\r\n\t\t\tpolar.r *= _scale;\r\n\t\t\treturn polar;\r\n\t\t}\r\n\r\n\t\t// 始点と終点を結んだ線を返す\r\n\t\tLine Polar::getLine() const\r\n\t\t{\r\n\t\t\treturn Line(center, toVec2());\r\n\t\t}\r\n\t};\r\n\r\n\tusing Polar3 = Polar<3>;\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/Siv3D/OpenSiv3D/issues/comments/326085007","html_url":"https://github.com/Siv3D/OpenSiv3D/issues/199#issuecomment-326085007","issue_url":"https://api.github.com/repos/Siv3D/OpenSiv3D/issues/199","id":326085007,"user":{"login":"Reputeless","id":3108136,"avatar_url":"https://avatars3.githubusercontent.com/u/3108136?v=4","gravatar_id":"","url":"https://api.github.com/users/Reputeless","html_url":"https://github.com/Reputeless","followers_url":"https://api.github.com/users/Reputeless/followers","following_url":"https://api.github.com/users/Reputeless/following{/other_user}","gists_url":"https://api.github.com/users/Reputeless/gists{/gist_id}","starred_url":"https://api.github.com/users/Reputeless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Reputeless/subscriptions","organizations_url":"https://api.github.com/users/Reputeless/orgs","repos_url":"https://api.github.com/users/Reputeless/repos","events_url":"https://api.github.com/users/Reputeless/events{/privacy}","received_events_url":"https://api.github.com/users/Reputeless/received_events","type":"User","site_admin":false},"created_at":"2017-08-30T18:52:17Z","updated_at":"2017-08-30T18:52:17Z","author_association":"OWNER","body":"### Rev. 2\r\n整理しました。挙動や機能の過不足について意見をください。\r\n\r\n```cpp\r\nnamespace s3d\r\n{\r\n    template <int32 Oclock>\r\n    struct CircularOffsetBase\r\n    {\r\n    private:\r\n\r\n        static constexpr double Clamp(double theta) noexcept\r\n        {\r\n            return theta <= -Math::Pi ? theta + Math::TwoPi : theta;\r\n        }\r\n\r\n        static constexpr double Clock() noexcept\r\n        {\r\n            return Oclock * (Math::TwoPi / 12);\r\n        }\r\n\r\n        static constexpr double Offset(double theta) noexcept\r\n        {\r\n            return Clamp(theta - Clock());\r\n        }\r\n\r\n    public:\r\n\r\n        Vec2 center;\r\n\r\n        double r;\r\n\r\n        double theta;\r\n\r\n        CircularOffsetBase() = default;\r\n\r\n        constexpr CircularOffsetBase(const Vec2& _center, double _r = 0.0, double _theta = 0.0) noexcept\r\n            : center(_center)\r\n            , r(_r)\r\n            , theta(_theta) {}\r\n\r\n        constexpr CircularOffsetBase(const Vec2& _center, Arg::r_<double> _r, Arg::theta_<double> _theta) noexcept\r\n            : center(_center)\r\n            , r(*_r)\r\n            , theta(*_theta) {}\r\n\r\n        constexpr CircularOffsetBase(const Vec2& _center, Arg::theta_<double> _theta, Arg::r_<double> _r) noexcept\r\n            : center(_center)\r\n            , r(*_r)\r\n            , theta(*_theta) {}\r\n\r\n        CircularOffsetBase(const Vec2& _center, const Vec2& target) noexcept\r\n            : center(_center)\r\n        {\r\n            setTarget(target);\r\n        }\r\n\r\n        constexpr CircularOffsetBase operator +() const noexcept\r\n        {\r\n            return *this;\r\n        }\r\n\r\n        constexpr CircularOffsetBase operator -() const noexcept\r\n        {\r\n            return{ center, r, Clamp(theta - Math::Pi) };\r\n        }\r\n\r\n        constexpr CircularOffsetBase operator +(const Vec2& v) const noexcept\r\n        {\r\n            return movedBy(v);\r\n        }\r\n\r\n        constexpr CircularOffsetBase operator -(const Vec2& v) const noexcept\r\n        {\r\n            return movedBy(-v);\r\n        }\r\n\r\n        constexpr CircularOffsetBase& operator +=(const Vec2& v) noexcept\r\n        {\r\n            return moveBy(v.x, v.y);\r\n        }\r\n\r\n        constexpr CircularOffsetBase& operator -=(const Vec2& v) noexcept\r\n        {\r\n            return moveBy(-v.x, -v.y);\r\n        }\r\n\r\n        constexpr CircularOffsetBase& moveBy(double x, double y) noexcept\r\n        {\r\n            center.moveBy(x, y);\r\n\r\n            return *this;\r\n        }\r\n\r\n        constexpr CircularOffsetBase& moveBy(const Vec2& v) noexcept\r\n        {\r\n            return moveBy(v.x, v.y);\r\n        }\r\n\r\n        [[nodiscard]] constexpr CircularOffsetBase movedBy(double x, double y) const noexcept\r\n        {\r\n            return CircularOffsetBase(*this).moveBy(v);\r\n        }\r\n\r\n        [[nodiscard]] constexpr CircularOffsetBase movedBy(const Vec2& v) const noexcept\r\n        {\r\n            return movedBy(v.x, v.y);\r\n        }\r\n\r\n        constexpr CircularOffsetBase& setCenter(const Vec2& _center) noexcept\r\n        {\r\n            center = _center;\r\n\r\n            return *this;\r\n        }\r\n\r\n        CircularOffsetBase& setTarget(const Vec2& target) noexcept\r\n        {\r\n            const Vec2 v = target - center;\r\n\r\n            r = v.length();\r\n\r\n            theta = Offset(std::atan2(v.x, -v.y));\r\n\r\n            return *this;\r\n        }\r\n\r\n        constexpr CircularOffsetBase& rotate(double angle) noexcept\r\n        {\r\n            polar.theta += angle;\r\n\r\n            return *this;\r\n        }\r\n\r\n        [[nodiscard]] constexpr CircularOffsetBase rotated(double angle) const noexcept\r\n        {\r\n            return Polar(*this).rotate(angle);\r\n        }\r\n\r\n        Vec2 toVec2() const noexcept\r\n        {\r\n            return center.movedBy(std::sin(theta + Clock()) * r, -std::cos(theta + Clock()) * r);\r\n        }\r\n\r\n        Float2 toFloat2() const noexcept\r\n        {\r\n            return{ center.x + std::sin(theta + Clock()) * r, center.y - std::cos(theta + Clock()) * r };\r\n        }\r\n\r\n        operator Vec2() const noexcept\r\n        {\r\n            return toVec2();\r\n        }\r\n    };\r\n\r\n    template <int32 Oclock> struct CircularOffsetBase;\r\n    using CircularOffset  = CircularOffsetBase<0>;\r\n    using CircularOffset0 = CircularOffsetBase<0>;\r\n    using CircularOffset3 = CircularOffsetBase<3>;\r\n    using CircularOffset6 = CircularOffsetBase<6>;\r\n    using CircularOffset9 = CircularOffsetBase<9>;\r\n}\r\n\r\n//////////////////////////////////////////////////////////////////////////////\r\n//\r\n//  Formatting CircularOffsetBase\r\n//\r\n//  [x] Siv3D Formatter\r\n//  [x] ostream\r\n//  [x] wostream\r\n//  [x] istream\r\n//  [x] wistream\r\n//  [x] fmtlib BasicFormatter<wchar>\r\n//\r\nnamespace s3d\r\n{\r\n    template <int32 Oclock>\r\n    inline void Formatter(FormatData& formatData, const CircularOffsetBase<Oclock>& c)\r\n    {\r\n        Formatter(formatData, Vec4(c.center, c.r, c.theta));\r\n    }\r\n\r\n    /// <summary>\r\n    /// 出力ストリームに円座標を渡します。\r\n    /// </summary>\r\n    /// <param name=\"os\">\r\n    /// 出力ストリーム\r\n    /// </param>\r\n    /// <param name=\"c\">\r\n    /// 円座標\r\n    /// </param>\r\n    /// <returns>\r\n    /// 渡した後の出力ストリーム\r\n    /// </returns>\r\n    template <class CharType, int32 Oclock>\r\n    inline std::basic_ostream<CharType>& operator <<(std::basic_ostream<CharType>& os, const CircularOffsetBase<Oclock>& c)\r\n    {\r\n        return os << CharType('(')\r\n            << c.center.x << CharType(',')\r\n            << c.center.y << CharType(',')\r\n            << c.r << CharType(',')\r\n            << c.theta << CharType(')');\r\n    }\r\n\r\n    /// <summary>\r\n    /// 入力ストリームに円座標を渡します。\r\n    /// </summary>\r\n    /// <param name=\"is\">\r\n    /// 入力ストリーム\r\n    /// </param>\r\n    /// <param name=\"c\">\r\n    /// 円座標\r\n    /// </param>\r\n    /// <returns>\r\n    /// 渡した後の入力ストリーム\r\n    /// </returns>\r\n    template <class CharType, int32 Oclock>\r\n    inline std::basic_istream<CharType>& operator >>(std::basic_istream<CharType>& is, CircularOffsetBase<Oclock>& c)\r\n    {\r\n        CharType unused;\r\n        return is >> unused\r\n            >> c.center.x >> unused\r\n            >> c.center.y >> unused\r\n            >> c.r >> unused\r\n            >> c.theta >> unused;\r\n    }\r\n}\r\n\r\nnamespace fmt\r\n{\r\n    template <class ArgFormatter, s3d::int32 Oclock>\r\n    void format_arg(BasicFormatter<s3d::wchar, ArgFormatter>& f, const s3d::wchar*& format_str, const s3d::CircularOffsetBase<Oclock>& c)\r\n    {\r\n        const auto tag = s3d::detail::GetTag(format_str);\r\n\r\n        const auto fmt = S3DSTR(\"({\") + tag + S3DSTR(\"},{\") + tag + S3DSTR(\"},{\") + tag + S3DSTR(\"},{\") + tag + S3DSTR(\"})\");\r\n\r\n        f.writer().write(fmt, c.center.x, c.center.y, c.r, c.theta);\r\n    }\r\n}\r\n//\r\n//////////////////////////////////////////////////////////////////////////////\r\n```"}}
{"actor":{"display_login":"Reputeless"}}