File indexing completed on 2025-02-02 04:11:07
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "polystar.hpp" 0008 #include "math/math.hpp" 0009 0010 0011 GLAXNIMATE_OBJECT_IMPL(glaxnimate::model::PolyStar) 0012 0013 glaxnimate::math::bezier::Bezier glaxnimate::model::PolyStar::to_bezier(model::FrameTime t) const 0014 { 0015 return draw( 0016 type.get(), 0017 position.get_at(t), 0018 inner_radius.get_at(t), 0019 outer_radius.get_at(t), 0020 math::deg2rad(angle.get_at(t)), 0021 points.get_at(t), 0022 inner_roundness.get_at(t), 0023 outer_roundness.get_at(t), 0024 reversed.get() 0025 ); 0026 } 0027 0028 glaxnimate::math::bezier::Bezier glaxnimate::model::PolyStar::draw( 0029 model::PolyStar::StarType type, const QPointF& pos, 0030 float radius_inner, float radius_outer, float angle_radians, int p, 0031 float round_inner, float round_outer, 0032 bool reverse 0033 ) 0034 { 0035 math::bezier::Bezier bezier; 0036 bezier.close(); 0037 0038 qreal direction = reverse ? -1 : 1; 0039 qreal halfd = math::pi / p * direction; 0040 qreal tangent_len_outer = round_outer * (math::tau * radius_outer) / (p * 4) * direction; 0041 qreal tangent_len_inner = round_inner * (math::tau * radius_inner) / (p * 4) * direction; 0042 0043 for ( int i = 0; i < p; i++ ) 0044 { 0045 qreal main_angle = -math::pi / 2 + angle_radians + i * halfd * 2; 0046 qreal dx = radius_outer * math::cos(main_angle); 0047 qreal dy = radius_outer * math::sin(main_angle); 0048 0049 QPointF tangents_outer; 0050 if ( radius_outer != 0 ) 0051 tangents_outer = { 0052 dy / radius_outer, 0053 -dx / radius_outer, 0054 }; 0055 0056 bezier.add_point( 0057 QPointF(pos.x() + dx, pos.y() + dy), 0058 tangent_len_outer * tangents_outer, 0059 -tangent_len_outer * tangents_outer 0060 ); 0061 0062 if ( type == Star ) 0063 { 0064 dx = radius_inner * math::cos(main_angle+halfd); 0065 dy = radius_inner * math::sin(main_angle+halfd); 0066 0067 QPointF tangents_inner; 0068 if ( radius_inner != 0 ) 0069 tangents_inner = { 0070 dy / radius_inner, 0071 -dx / radius_inner, 0072 }; 0073 0074 bezier.add_point( 0075 QPointF(pos.x() + dx, pos.y() + dy), 0076 tangent_len_inner * tangents_inner, 0077 -tangent_len_inner * tangents_inner 0078 ); 0079 } 0080 } 0081 0082 return bezier; 0083 } 0084 0085