1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include "[Circle.h]"19 #include "[Plane.h]"20 #include "../Math/MathFunc.h"21 #include "../Math/float2.h"22 #include "../Math/float3x3.h"23 #include "../Math/float3x4.h"24 #include "../Math/float4x4.h"25 #include "../Math/Quat.h"26 #include "[Ray.h]"27 #include "[AABB.h]"28 #include "[OBB.h]"29 #include "[LineSegment.h]"30 #include "[Line.h]"31 32 #ifdef MATH_ENABLE_STL_SUPPORT33 #include <iostream>34 #endif35 36 [MATH_BEGIN_NAMESPACE]37 38 [Circle::Circle](const vec ¢er, const vec &n, float radius)39 :pos(center),40 normal(n),41 r(radius)42 {43 }44 45 vec [Circle::BasisU]() const46 {47 return [normal].[Perpendicular]();48 }49 50 vec [Circle::BasisV]() const51 {52 return [normal].[AnotherPerpendicular]();53 }54 55 vec [Circle::GetPoint](float angleRadians) const56 {57 float sin, cos;58 [SinCos](angleRadians, sin, cos);59 return [pos] + [r] * (sin * [BasisU]() + cos * [BasisV]());60 }61 62 vec [Circle::GetPoint](float angleRadians, float [d]) const63 {64 float sin, cos;65 [SinCos](angleRadians, sin, cos);66 return [pos] + [r] * d * (cos * [BasisU]() + sin * [BasisV]());67 }68 69 vec [Circle::ExtremePoint](const vec &direction) const70 {71 vec [d] = direction - direction.[ProjectToNorm]([normal]);72 if (d.IsZero())73 return [pos];74 else75 return [pos] + d.[ScaledToLength]([r]);76 }77 78 [Plane] [Circle::ContainingPlane]() const79 {80 return [Plane]([pos], [normal]);81 }82 83 void [Circle::Translate](const vec &offset)84 {85 [pos] += offset;86 }87 88 void [Circle::Transform](const [float3x3] &transform)89 {90 [assume](transform.[HasUniformScale]());91 [assume](transform.[IsColOrthogonal]());92 [pos] = transform.[Mul](pos);93 [normal] = transform.[Mul]([normal]).Normalized();94 [r] *= transform.[Col](0).[Length](); 95 }96 97 void [Circle::Transform](const [float3x4] &transform)98 {99 [assume](transform.[HasUniformScale]());100 [assume](transform.[IsColOrthogonal]());101 pos = transform.[MulPos](pos);102 [normal] = transform.[MulDir]([normal]).[Normalized]();103 [r] *= transform.[Col](0).[Length](); 104 }105 106 void [Circle::Transform](const [float4x4] &transform)107 {108 [assume](transform.[HasUniformScale]());109 [assume](transform.[IsColOrthogonal3]());110 pos = transform.[MulPos](pos);111 [normal] = transform.[MulDir]([normal]).[Normalized]();112 [r] *= transform.[Col3](0).[Length](); 113 }114 115 void [Circle::Transform](const [Quat] &transform)116 {117 pos = transform.[Mul](pos);118 [normal] = transform.[Mul]([normal]);119 }120 121 bool [Circle::EdgeContains](const vec &point, float maxDistance) const122 {123 return [DistanceToEdge](point) <= maxDistance;124 }125 126 127 128 129 130 131 132 float [Circle::DistanceToEdge](const vec &point) const133 {134 return [ClosestPointToEdge](point).[Distance](point);135 }136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 float [Circle::DistanceToDisc](const vec &point) const171 {172 return [ClosestPointToDisc](point).[Distance](point);173 }174 175 vec [Circle::ClosestPointToEdge](const vec &point) const176 {177 vec pointOnPlane = [ContainingPlane]().[Project](point);178 vec diff = pointOnPlane - [pos];179 if (diff.IsZero())180 return [GetPoint](0); 181 return pos + diff.[ScaledToLength]([r]);182 }183 184 vec [Circle::ClosestPointToDisc](const vec &point) const185 {186 vec pointOnPlane = [ContainingPlane]().[Project](point);187 vec diff = pointOnPlane - [pos];188 float dist = diff.[LengthSq]();189 if (dist > [r]*[r])190 diff = diff * (r / [Sqrt](dist));191 192 return pos + diff;193 }194 195 int [Circle::Intersects](const [Plane] &plane, vec *pt1, vec *pt2) const196 {197 return plane.[Intersects](*this, pt1, pt2);198 }199 200 int [Circle::Intersects](const [Plane] &plane) const201 {202 return plane.[Intersects](*this);203 }204 205 bool [Circle::IntersectsDisc](const [Line] &line) const206 {207 float [d];208 bool intersectsPlane = line.[Intersects]([ContainingPlane](), &d);209 if (intersectsPlane)210 return false;211 return line.[GetPoint](d).[DistanceSq](pos) <= [r]*[r];212 }213 214 bool [Circle::IntersectsDisc](const [LineSegment] &lineSegment) const215 {216 float [d];217 bool intersectsPlane = lineSegment.[Intersects]([ContainingPlane](), &d);218 if (intersectsPlane)219 return false;220 return lineSegment.[GetPoint](d).[DistanceSq](pos) <= [r]*[r];221 }222 223 bool [Circle::IntersectsDisc](const [Ray] &ray) const224 {225 float [d];226 bool intersectsPlane = ray.[Intersects]([ContainingPlane](), &d);227 if (intersectsPlane)228 return false;229 return ray.[GetPoint](d).[DistanceSq](pos) <= [r]*[r];230 }231 232 #ifdef MATH_ENABLE_STL_SUPPORT233 [VecArray] [Circle::IntersectsFaces](const [AABB] &aabb) const234 {235 return [IntersectsFaces](aabb.[ToOBB]());236 }237 238 [VecArray] [Circle::IntersectsFaces](const [OBB] &obb) const239 {240 [VecArray] intersectionPoints;241 for(int i = 0; i < 6; ++i)242 { 243 [Plane] p = obb.[FacePlane](i);244 vec pt1, pt2;245 int numIntersections = [Intersects](p, &pt1, &pt2);246 if (numIntersections >= 1 && obb.[Contains](pt1))247 intersectionPoints.push_back(pt1);248 if (numIntersections >= 2 && obb.[Contains](pt2))249 intersectionPoints.push_back(pt2);250 }251 return intersectionPoints;252 }253 254 std::string [Circle::ToString]() const255 {256 char str[256];257 sprintf(str, "Circle(pos:(%.2f, %.2f, %.2f) normal:(%.2f, %.2f, %.2f), r:%.2f)",258 pos.x, pos.y, pos.z, [normal].[x], [normal].[y], [normal].[z], [r]);259 return str;260 }261 262 std::ostream &[operator <<](std::ostream &o, const [Circle] &circle)263 {264 o << circle.[ToString]();265 return o;266 }267 268 #endif269 270 [Circle] [operator *](const [float3x3] &transform, const [Circle] &circle)271 {272 [Circle] c(circle);273 c.Transform(transform);274 return c;275 }276 277 [Circle] [operator *](const [float3x4] &transform, const [Circle] &circle)278 {279 [Circle] c(circle);280 c.Transform(transform);281 return c;282 }283 284 [Circle] [operator *](const [float4x4] &transform, const [Circle] &circle)285 {286 [Circle] c(circle);287 c.Transform(transform);288 return c;289 }290 291 [Circle] [operator *](const [Quat] &transform, const [Circle] &circle)292 {293 [Circle] c(circle);294 c.Transform(transform);295 return c;296 }297 298 [MATH_END_NAMESPACE] Go back to previous page