My lost code was horrible - all sorts of case statements to deal with angle quadrants.
The following code - is the very start of my new Demo program
int displayWidth,displayHeight ;
String mode ;
float CX,CY ;
float degreesToRadians(float th)
{
return PI * th /180.0f ;
}
float translateX(float x)
{
return x+CX ;
}
float translateY(float y)
{
return -y+displayHeight-CY ;
}
PVector [] calcControlPoints(float angle,float ro,float radius,float tilt,float petalLength)
{
PVector [] bezControlPoints = new PVector[4] ;
float halfRo = ro / 2.0f ;
PVector[] cPoints = calcPetalPointPair(angle-halfRo,tilt,petalLength) ;
PVector startPt = cPoints[0] ;
PVector fPoint = cPoints[1] ;
bezControlPoints[0] = new PVector(startPt.x * radius,startPt.y * radius) ;
bezControlPoints[1] = new PVector(startPt.x * radius + fPoint.x,startPt.y * radius + fPoint.y) ;
PVector [] cPoints2 = calcPetalPointPair(angle+halfRo,-tilt,petalLength) ;
startPt = cPoints2[0] ;
fPoint = cPoints2[1] ;
bezControlPoints[3] = new PVector(startPt.x * radius,startPt.y * radius) ;
bezControlPoints[2] = new PVector(startPt.x * radius + fPoint.x,startPt.y * radius + fPoint.y) ;
return bezControlPoints ;
}
void drawBezier(PVector [] cps)
{
drawBezier(cps[0].x,cps[0].y,cps[1].x,cps[1].y,cps[2].x,cps[2].y,cps[3].x,cps[3].y) ;
}
void drawBezier(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4)
{
noFill() ;
stroke(0,0,0) ;
bezier(translateX(x1),translateY(y1),
translateX(x2),translateY(y2),
translateX(x3),translateY(y3),
translateX(x4),translateY(y4)) ;
}
void drawControlPoints(PVector[] cps)
{
stroke(255,0,0) ;
drawLine(cps[0].x,cps[0].y,cps[1].x,cps[1].y) ;
stroke(0,255,0) ;
drawLine(cps[2].x,cps[2].y,cps[3].x,cps[3].y) ;
}
PVector[] calcPetalPointPair(float angle,float tilt,float petalLength)
{
PVector startPt = new PVector(1.0*sin(degreesToRadians(angle)),1.0*cos(degreesToRadians(angle)));
PVector vert = new PVector(0,0,1.0f) ; // Unit Vector Perp to XY Plane
PVector nCPc = startPt.cross(vert) ; // Calculate Tangent to Circle at startPt.x,startPt.y
PMatrix2D iMat = new PMatrix2D() ;
iMat.rotate(degreesToRadians(tilt < 0 ? 180+tilt : tilt)) ; // Petal Tilt
PMatrix2D cMat = new PMatrix2D(nCPc.x,startPt.x,0f,nCPc.y,startPt.y,0.0f) ;
// Matrix
// | nCPc.x startx |
// | nCPc.y starty |
cMat.preApply(iMat) ; // Apply our orthog axis to the rotation matrix
PVector fPoint = new PVector() ;
PVector sPoint = new PVector(petalLength,0) ; // Petal Length
cMat.mult(sPoint,fPoint) ; // Apply Full transformation to petal Vector
PVector [] points = new PVector[2] ;
points[0] = startPt ;
points[1] = fPoint ;
return points;
}
void setup()
{
mode = JAVA2D ;
displayHeight = screen.height/2 ;
displayWidth = screen.width/2 ;
CX = displayWidth / 2 ;
CY = displayHeight / 2 ;
size(displayWidth, displayHeight,mode);
loop() ;
}
void drawLine(float x,float y,float x2,float y2) {
line(translateX(x),translateY(y),translateX(x2),translateY(y2)) ;
}
void drawCircle(float x,float y,float rad)
{
ellipse(translateX(x), translateY(y), rad,rad) ;
}
void draw() {
background(255);
float dt = 1/frameRate ; // We should calculate dt - time passed since last update-draw
float radius = 20.0f ;
float tilt = 70.0f ;
float petalLength = 250.0f ;
float ro = 15.0f ;
float step = 7.0f ;
float numpetals = 360.0f / step ;
noFill() ;
ellipseMode(RADIUS) ;
stroke(0,0,0) ;
drawCircle(0,0,radius) ;
for (float angle = 0.0f ; angle < step*numpetals ; angle+=step)
{
PVector [] cps = calcControlPoints(angle,ro,radius,tilt,petalLength) ;
drawBezier(cps) ;
}
}
3 comments:
I only recently found PVector in the processing documentation (I don't think it's mentioned in Greenberg). Quite possibly it should be 'introduced' in the book? SVG image would be nice for your fly, I've being thinking about creating one for my saucer shape, but it would spoil the idea of creating a hybrid shape.
Thanks Martin, Yes - your blog introduced me to PVector - You can see from my earlier blogs, I had my own Vector class for 2D and 3D points.
I wanted to stay away from any copyright material including SVG/PNG/GIF images. There needs to be a resource point to pick up these files.
Admittedly you can find some nice fly images as copyrighted clipart, but I wasn't thinking in terms of such perfection, SVG is only an XML file after all. What I meant about the PVector is that it seems to be a useful addition to to processing that perhaps should be introduced formally in the book. I've just be playing with PVector class, very handy for determining angle between vectors.
Post a Comment