Skip to content

Instantly share code, notes, and snippets.

@C4Tutorials
Last active December 16, 2015 00:29
Show Gist options
  • Save C4Tutorials/5348431 to your computer and use it in GitHub Desktop.
Save C4Tutorials/5348431 to your computer and use it in GitHub Desktop.
Trigonometry Tutorial
//
// C4WorkSpace.m
// Trigonometry Tutorial
//
// Created by Travis Kirton.
//
#import "C4WorkSpace.h"
@implementation C4WorkSpace {
CGPoint A, B, C, D, M, P, Q, X, Y;
CGFloat radius, theta, dX, dY, s, slope, b, thetaA, thetaB;
C4Shape *circle, *poly, *mPt, *pPt, *qPt, *xPt, *yPt, *angleB, *angleD, *linePQ;
C4Label *lblA, *lblB, *lblC, *lblD, *lblM, *lblP, *lblQ, *lblX, *lblY;
}
-(void)setup {
[self setupCircleAndPoly];
xPt = [C4Shape ellipse:CGRectMake(0, 0, 7, 7)];
xPt.lineWidth = 2.0f;
xPt.strokeColor = C4GREY;
xPt.fillColor = C4RED;
[self setX];
mPt = [xPt copy];
[self setM];
yPt = [mPt copy];
[self setY];
pPt = [yPt copy];
qPt = [pPt copy];
[self setPQ];
angleD = [C4Shape ellipse:CGRectMake(0, 0, 80, 80)];
angleD.style = circle.style;
angleB = [angleD copy];
[self setAngleBD];
[self createLabels];
[self setLabelPositions];
[self addShapesToPoly];
[self addLabelsToPoly];
[self addGesture:PAN name:@"adjust" action:@"adjust:"];
[self maximumNumberOfTouches:1 forGesture:@"adjust"];
[self addGesture:PAN name:@"rotate" action:@"rotate:"];
[self minimumNumberOfTouches:2 forGesture:@"rotate"];
}
-(void)setupCircleAndPoly {
circle = [C4Shape ellipse:CGRectMake(0,0,368,368)];
circle.lineWidth = 2.0f;
circle.strokeColor = C4GREY;
circle.fillColor = [UIColor clearColor];
thetaA = 1.15f;
thetaB = 0.3f;
radius = circle.width / 2.0f;
theta = PI * thetaA;
A = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
theta = PI * thetaB;
B = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
theta = PI * (2.0f-thetaA);
C = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
theta = PI * (2.0f-thetaB);
D = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
CGPoint polypts[4] = {A,B,C,D};
poly = [C4Shape polygon:polypts pointCount:4];
poly.style = circle.style;
poly.lineJoin = JOINBEVEL;
[poly closeShape];
CGPoint polyAnchor = A;
polyAnchor.x = [C4Math map:polyAnchor.x fromMin:poly.origin.x max:poly.origin.x+poly.width toMin:0 max:1];
polyAnchor.y = [C4Math map:polyAnchor.y fromMin:poly.origin.y max:poly.origin.y+poly.height toMin:0 max:1];
poly.anchorPoint = polyAnchor;
poly.center = CGPointMake(circle.center.x+A.x,circle.center.x+A.y);
[circle addShape:poly];
[self.canvas addShape:circle];
circle.center = self.canvas.center;
}
-(void)setX {
//X is the mid-point of AD
X = CGPointMake((D.x + A.x)/2.0f,(D.y+A.y)/2.0f);
xPt.center = X;
}
-(void)setM {
//M is the intersection of the two internal lines of the polygon
CGFloat a1 = B.y - A.y;
CGFloat b1 = A.x - B.x;
CGFloat c1 = a1*A.x + b1*A.y;
CGFloat a2 = D.y - C.y;
CGFloat b2 = C.x - D.x;
CGFloat c2 = a2*C.x + b2*C.y;
CGFloat det = a1*b2 - a2 * b1;
M = CGPointMake((b2*c1 - b1*c2)/det, (a1*c2 - a2*c1)/det);
mPt.center = M;
}
-(void)setY {
CGFloat angleMCB = [self angleFromA:M b:C c:B];
CGFloat angleCMY = [self angleFromA:X b:M c:D];//because they're equal
CGFloat angleCYM = PI - angleMCB - angleCMY;
CGFloat dCM = [C4Vector distanceBetweenA:C andB:M];
CGFloat dMY = dCM/[C4Math sin:angleCYM] * [C4Math sin:angleMCB];
dX = M.x - X.x;
dY = M.y - X.y;
CGFloat dMX = [C4Vector distanceBetweenA:M andB:X];
CGFloat multiplier = (dMX + dMY)/dMX;
Y = CGPointMake(X.x + dX * multiplier, X.y + dY * multiplier);
yPt.center = Y;
}
-(CGFloat)angleFromA:(CGPoint)pt1 b:(CGPoint)pt2 c:(CGPoint)pt3 {
pt1.x -= pt2.x;
pt1.y -= pt2.y;
pt3.x -= pt2.x;
pt3.y -= pt2.y;
return [C4Vector angleBetweenA:pt1 andB:pt3];
}
-(void)setPQ {
slope = dY / dX;
b = M.y;
CGFloat dr = [C4Math sqrt:(dX*dX+dY*dY)];
CGFloat bigD = X.x*M.y - M.x*X.y;
CGFloat x, y;
//equ for x via wolfram
//x = (D*dY +- sgn(dY)*dx *sqrt(r2*dr2-D2))/dr2;
CGFloat sgn = dY / [C4Math absf:dY];
x = (bigD*dY+sgn*dX*[C4Math sqrt:radius*radius*dr*dr-bigD*bigD])/(dr*dr);
y = slope*x + b;
P = CGPointMake(x, y);
x = (bigD*dY-sgn*dX*[C4Math sqrt:radius*radius*dr*dr-bigD*bigD])/(dr*dr);
y = slope*x + b;
Q = CGPointMake(x, y);
if(slope > 0) {
CGPoint temp = P;
P = Q;
Q = temp;
}
pPt.center = P;
qPt.center = Q;
}
-(void)addShapesToPoly {
CGPoint linePts[2] = {P,Q};
linePQ = [C4Shape line:linePts];
linePQ.style = circle.style;
[poly addObjects:@[angleB,angleD]];
[poly addObjects:@[linePQ,mPt,xPt,yPt,pPt,qPt]];
}
-(void)addLabelsToPoly {
[poly addObjects:@[lblA, lblB, lblC, lblD, lblM, lblP, lblQ, lblX, lblY]];
}
-(void)setAngleBD {
theta = [self angleFromA:A b:D c:C];
[angleD removeFromSuperview];
angleD = nil;
[angleB removeFromSuperview];
angleB = nil;
CGFloat dAD = [C4Vector distanceBetweenA:A andB:D];
CGFloat r = [C4Math maxOfA:80 B:10.0f];
angleD = [C4Shape ellipse:CGRectMake(0, 0, r, r)];
angleD.style = circle.style;
angleD.center = D;
angleB = [angleD copy];
angleB.center = B;
CGFloat rot = [self angleFromA:C b:D c:B];
angleD.strokeStart = 1 - theta/TWO_PI - rot/TWO_PI;
angleD.strokeEnd = angleD.strokeStart + theta/TWO_PI;
angleB.strokeStart = rot/TWO_PI + 0.5f;
angleB.strokeEnd = angleB.strokeStart + theta/TWO_PI;
}
-(void)createLabels {
lblA = [C4Label labelWithText:@"A" font:[C4Font fontWithName:@"TimesNewRomanPS-ItalicMT" size:16.0f]];
lblB = [C4Label labelWithText:@"B" font:lblA.font];
lblC = [C4Label labelWithText:@"C" font:lblA.font];
lblD = [C4Label labelWithText:@"D" font:lblA.font];
lblP = [C4Label labelWithText:@"P" font:lblA.font];
lblQ = [C4Label labelWithText:@"Q" font:lblA.font];
lblM = [C4Label labelWithText:@"M" font:lblA.font];
lblX = [C4Label labelWithText:@"X" font:lblA.font];
lblY = [C4Label labelWithText:@"Y" font:lblA.font];
}
-(void)setLabelPositions {
lblA.center = CGPointMake(A.x - 6.0f, A.y - 8.0f);
lblB.center = CGPointMake(B.x + 5.0f, B.y + 8.0f);
lblC.center = CGPointMake(C.x + 6.0f, C.y - 8.0f);
lblD.center = CGPointMake(D.x - 6.0f, D.y + 8.0f);
lblP.center = CGPointMake(P.x - 16.0f, P.y + 4.0f);
lblQ.center = CGPointMake(Q.x + 14.0f, Q.y - 4.0f);
lblM.center = CGPointMake(M.x-1.0f, M.y-16.0f);
lblX.center = CGPointMake(X.x-10.0f, X.y-8.0f);
lblY.center = CGPointMake(Y.x+12.0f, Y.y+8.0f);
}
-(void)adjust:(UIPanGestureRecognizer *)gesture {
CGPoint p = [gesture locationInView:self.canvas];
CGFloat rot = (p.x / self.canvas.width)/2.0f;
if(p.y < self.canvas.center.y) [self setThetaA:rot+1 thetaB:thetaB];
else [self setThetaA:thetaA thetaB:rot];
}
-(void)rotate:(UIPanGestureRecognizer *)gesture {
CGPoint p = [gesture translationInView:self.canvas];
p.x *= TWO_PI/self.canvas.width;
circle.rotation += p.x;
[gesture setTranslation:CGPointZero inView:self.canvas];
lblA.rotation = -circle.rotation;
lblB.rotation = -circle.rotation;
lblC.rotation = -circle.rotation;
lblD.rotation = -circle.rotation;
lblM.rotation = -circle.rotation;
lblP.rotation = -circle.rotation;
lblQ.rotation = -circle.rotation;
lblX.rotation = -circle.rotation;
lblY.rotation = -circle.rotation;
}
-(void)setThetaA:(CGFloat)_thetaA thetaB:(CGFloat)_thetaB {
thetaA = _thetaA;
thetaB = _thetaB;
[poly removeFromSuperview];
radius = circle.width / 2.0f;
theta = PI * thetaA;
A = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
theta = PI * thetaB;
B = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
theta = PI * (2.0f-thetaA);
C = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
theta = PI * (2.0f-thetaB);
D = CGPointMake(radius*[C4Math sin:theta], radius*[C4Math cos:theta]);
CGPoint polypts[4] = {A,B,C,D};
poly = [C4Shape polygon:polypts pointCount:4];
poly.style = circle.style;
poly.lineJoin = JOINBEVEL;
CGPoint polyAnchor = A;
polyAnchor.x = [C4Math map:polyAnchor.x fromMin:poly.origin.x max:poly.origin.x+poly.width toMin:0 max:1];
polyAnchor.y = [C4Math map:polyAnchor.y fromMin:poly.origin.y max:poly.origin.y+poly.height toMin:0 max:1];
poly.anchorPoint = polyAnchor;
poly.center = CGPointMake(circle.width/2.0f+A.x,circle.height/2.0f+A.y);
[poly closeShape];
[circle addShape:poly];
[self.canvas addShape:circle];
circle.center = self.canvas.center;
[self setX];
[self setM];
[self setY];
[self setPQ];
[self setAngleBD];
[self setLabelPositions];
[self addShapesToPoly];
[self setLabelPositions];
[self addLabelsToPoly];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment