Hi! I'm writing a PHP program to take advantage of .png image formats that allow alpha transparency. It is supposed to create ellipses, but I get di-polar creations instead. The problem code section is below, and "should" be basically readable to a mathematician. It creates circles just fine, but as the height/width ratio deviation from 1.0 increases (the more you squish the circle into an ellipse) the more the separation. Interestingly, at a h/w ratio of 2(pi) (approx=6.28) [or 1/6.28 squishes the ellipse top-to-bottom] you just about get 2 tangent circles. I'd post a link to a nearly-complete working demo and all the source code if it was appropriate (just say so). I'll be releasing the entire thing under an open-software license.
Remember, angles are in radians...
anything after // is a comment (until the end of line, but line may wrap on narrow screens)
I've created another test feature. This creates an ellipse outline in white, then in the (+,+) quadrant (angle<2(PI)) it resets the pixels to red AFTER it recalculates the pixel position using the same logic as the first program... It also graphs the angle and the radius...
as shown, I calculate the angle in the first program as the arctangent of the rise over run, with rise and run being calculated from the center of the ellipse, and it doesn't work. Yet the overall process DOES in the example in the second program! The graph of the angle and the radius values show them to rise, not cycle, in this quadrant.
This has been straining my brain for over a week. I took trig in college, but that was 20 years ago... From every identity I can find, my approach is correct, or so I THOUGHT. Obviously NOT. PLEASE tell me what gives before my brain melts away from overheating... :?
tangent(angle) = rise/run = opposite/adjacent
arctangent( tangent(angle) ) = angle
Remember, angles are in radians...
anything after // is a comment (until the end of line, but line may wrap on narrow screens)
Code:
for ($row=$wrkMargin['top']; $row<$height; $row++) { //loop through every row (y co-ordinate of pixel) ...
for ($column=$wrkMargin['left']; $column<$width; $column++) { //loop through every column (x co-ordinate of pixel) ...
if ($hwRatio!=1) {
// if not a circle, then calculate the length of the ray from the ellipse center through the pixel to the edge of the ellipse
if ($column==$center['x']) $angle=M_PI_2; // angle=PI/2; remember division by 0 is undefined.
else $angle=atan( abs($center['y']-$row) / abs($center['x']-$column) ); // abs is absolute value
$radius=sqrt( pow($Xradius*cos($angle), 2) + pow($Yradius*sin($angle), 2) ); // here "pow" squares the values
$ellipseFactor=$majorSemiAxis/$radius; }
$offCenter=sqrt( pow($center['x']-$column, 2) + pow($center['y']-$row, 2) ); // how far is the pixel from the center?
// if the pixel is outside the boundaries of the circle or ellipse, either reflect the colors, or ignore the pixel (user choice)
if ($¿reflect) while ($offCenter>$radius) {$offCenter=abs($radius-($offCenter-$radius));}
else if (round($offCenter)>$radius) continue; //continue with next pixel -ignore this one
$offCenter=round($offCenter*$ellipseFactor)
imagealphablending($rainbowBall, $rainbow[$offCenter]['alphablend']); // set blend mode
imagesetpixel($rainbowBall, $column, $row, $rainbow[$offCenter]['clrAllocate']); // set the pixel to the appropriate color
}
}
I've created another test feature. This creates an ellipse outline in white, then in the (+,+) quadrant (angle<2(PI)) it resets the pixels to red AFTER it recalculates the pixel position using the same logic as the first program... It also graphs the angle and the radius...
Code:
//loop through all angles from 0 to 2 times PI (approx 6.28...) at a rate of .01 radians
for ($angle=0; $angle<M_PI*2; $angle=$angle+.01) {
$x=cos($angle)*200;
$y=sin($angle)*300;
if ($angle==0) imageellipse($image, 400+$x, 400-$y, 7,7, $red); //show start point of first quadrant
if ($angle-.01<M_PI_2 and $angle+.01>M_PI_2) imageellipse($image, 400+$x, 400-$y, 7,7, $cyan); //show end of quad.
imagesetpixel($image, 400+$x, 400-$y, $white);
if ($angle<M_PI_2) { // if in the first quadrant, 'backwards calculate'
if ($x==0) $beta=M_PI_2;
else $beta=atan($y/$x); // in this quadrant x and y are positive and less than 400, no need for abs
$xb=200*cos($beta); $yb=300*sin($beta);
$radius=sqrt( pow($xb, 2) + pow($yb, 2) );
$ellipseFactor=300/$radius;
imagesetpixel($image, 400+$xb, 400-$yb, $red); //here we reset the white pixel to red - in this quadrant
imagesetpixel($image, 400+$count, 400-$beta*150, $cyan); //graph the angle's value
imagesetpixel($image, 400+$count, 400-$radius, $purple); // graph the radius' value
imagesetpixel($image, 400+$count, 400-($ellipseFactor*300), $white);
imagesetpixel($image, 400+$count++, 400-($ellipseFactor*$radius), $yellow);
}
}
as shown, I calculate the angle in the first program as the arctangent of the rise over run, with rise and run being calculated from the center of the ellipse, and it doesn't work. Yet the overall process DOES in the example in the second program! The graph of the angle and the radius values show them to rise, not cycle, in this quadrant.
This has been straining my brain for over a week. I took trig in college, but that was 20 years ago... From every identity I can find, my approach is correct, or so I THOUGHT. Obviously NOT. PLEASE tell me what gives before my brain melts away from overheating... :?
tangent(angle) = rise/run = opposite/adjacent
arctangent( tangent(angle) ) = angle