Graphviz 14.0.2~dev.20251008.0253
Loading...
Searching...
No Matches
arcball.c
Go to the documentation of this file.
1/*************************************************************************************/
23/*************************************************************************************/
24
25#include <glcomp/glcompdefs.h>
26#define ARCBALL_C
27#include "smyrnadefs.h"
28#include "arcball.h"
29
30static void setBounds(ArcBall_t *a, float NewWidth, float NewHeight) {
31 assert((NewWidth > 1.0f) && (NewHeight > 1.0f));
32 //Set adjustment factor for width/height
33 a->AdjustWidth = 1.0f / ((NewWidth - 1.0f) * 0.5f);
34 a->AdjustHeight = 1.0f / ((NewHeight - 1.0f) * 0.5f);
35}
36
37static Vector3fT mapToSphere(ArcBall_t *a, const Point2fT *NewPt) {
38 Point2fT TempPt;
39
40 //Copy paramter into temp point
41 TempPt = *NewPt;
42
43 //Adjust point coords and scale down to range of [-1 ... 1]
44 TempPt.X = TempPt.X * a->AdjustWidth - 1.0f;
45 TempPt.Y = 1.0f - TempPt.Y * a->AdjustHeight;
46
47 //Compute the square of the length of the vector to the point from the center
48 float length = TempPt.X * TempPt.X + TempPt.Y * TempPt.Y;
49
50 //If the point is mapped outside of the sphere... (length > radius squared)
51 if (length > 1.0f) {
52
53 //Compute a normalizing factor (radius / sqrt(length))
54 float norm = 1.0f / FuncSqrt(length);
55
56 //Return the "normalized" vector, a point on the sphere
57 return (Vector3fT){.X = TempPt.X * norm, .Y = TempPt.Y * norm};
58 } else //Else it's on the inside
59 {
60 //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
61 return (Vector3fT){.X = TempPt.X, .Y = TempPt.Y, .Z = FuncSqrt(1.0f - length)};
62 }
63}
64
65static Matrix4fT Transform = { {1.0f, 0.0f, 0.0f, 0.0f, // NEW: Final Transform
66 0.0f, 1.0f, 0.0f, 0.0f,
67 0.0f, 0.0f, 1.0f, 0.0f,
68 0.0f, 0.0f, 0.0f, 1.0f}
69};
70
71static Matrix3fT LastRot = { {1.0f, 0.0f, 0.0f, // NEW: Last Rotation
72 0.0f, 1.0f, 0.0f,
73 0.0f, 0.0f, 1.0f}
74};
75
76static Matrix3fT ThisRot = { {1.0f, 0.0f, 0.0f, // NEW: This Rotation
77 0.0f, 1.0f, 0.0f,
78 0.0f, 0.0f, 1.0f}
79};
80
81//Create/Destroy
82ArcBall_t init_arcBall(float NewWidth, float NewHeight) {
83 ArcBall_t a = {.Transform = Transform, .LastRot = LastRot,
84 .ThisRot = ThisRot};
85
86 //Set initial bounds
87 setBounds(&a, NewWidth, NewHeight);
88 return a;
89}
90
91//Mouse down
92static void click(ArcBall_t * a, const Point2fT * NewPt)
93{
94 //Map the point to the sphere
95 a->StVec = mapToSphere(a, NewPt);
96}
97
98//Mouse drag, calculate rotation
99static Quat4fT drag(ArcBall_t *a, const Point2fT *NewPt) {
100 //Map the point to the sphere
101 a->EnVec = mapToSphere(a, NewPt);
102
103 //Return the quaternion equivalent to the rotation
104 // compute the vector perpendicular to the begin and end vectors
105 const Vector3fT Perp = Vector3fCross(a->StVec, a->EnVec);
106
107 // compute the length of the perpendicular vector
108 if (Vector3fLength(Perp) > Epsilon) { // if it’s non-zero
109 // we're OK, so return the perpendicular vector as the transform after
110 // all
111 return (Quat4fT){.X = Perp.X,
112 .Y = Perp.Y,
113 .Z = Perp.Z,
114 // in the quaternion values, W is cosine (theta / 2), where theta is
115 // rotation angle
116 .W = Vector3fDot(a->StVec, a->EnVec)};
117 } else { // if it’s zero
118 // the begin and end vectors coincide, so return an identity transform
119 return (Quat4fT){0};
120 }
121}
122
124{
125 view->arcball->isDragging = 1; // Prepare For Dragging
126 view->arcball->LastRot = view->arcball->ThisRot; // Set Last Static Rotation To Last Dynamic One
128
129}
130
131void arcmouseDrag(void)
132{
133 Quat4fT ThisQuat = drag(view->arcball, &view->arcball->MousePt);
134 view->arcball->ThisRot = Matrix3fSetRotationFromQuat4f(ThisQuat); // Convert Quaternion Into Matrix3fT
135 Matrix3fMulMatrix3f(&view->arcball->ThisRot, view->arcball->LastRot); // Accumulate Last Rotation Into This One
136 Matrix4fSetRotationFromMatrix3f(&view->arcball->Transform, &view->arcball->ThisRot); // Set Our Final Transform's Rotation From This One
137
138}
static void click(ArcBall_t *a, const Point2fT *NewPt)
Definition arcball.c:92
ArcBall_t init_arcBall(float NewWidth, float NewHeight)
Definition arcball.c:82
void arcmouseClick(void)
Definition arcball.c:123
void arcmouseDrag(void)
Definition arcball.c:131
static void setBounds(ArcBall_t *a, float NewWidth, float NewHeight)
Definition arcball.c:30
static Matrix3fT LastRot
Definition arcball.c:71
static Quat4fT drag(ArcBall_t *a, const Point2fT *NewPt)
Definition arcball.c:99
static Matrix3fT ThisRot
Definition arcball.c:76
static Matrix4fT Transform
Definition arcball.c:65
static Vector3fT mapToSphere(ArcBall_t *a, const Point2fT *NewPt)
Definition arcball.c:37
#define Quat4fT
Definition arcball.h:131
#define Epsilon
Definition arcball.h:140
#define FuncSqrt
Definition arcball.h:136
#define Vector3fT
Definition arcball.h:133
#define Point2fT
Definition arcball.h:129
static Extype_t length(Exid_t *rhs, Exdisc_t *disc)
Definition compile.c:1606
static double norm(int n, const double *x)
ViewInfo * view
Definition viewport.c:37
Vector3fT EnVec
Definition arcball.h:420
Point2fT MousePt
Definition arcball.h:426
Matrix3fT LastRot
Definition arcball.h:424
Matrix3fT ThisRot
Definition arcball.h:425
Matrix4fT Transform
Definition arcball.h:423
float AdjustWidth
Definition arcball.h:421
int isDragging
Definition arcball.h:427
float AdjustHeight
Definition arcball.h:422
Vector3fT StVec
Definition arcball.h:419
ArcBall_t * arcball
Definition smyrnadefs.h:333