1::<HTML>
2::<HEAD><TITLE>TA </TITLE>
3::<TITLE>
4::php Triangle Graphing Program -- Andy Carter
5::</TITLE>
6::</HEAD>
7::
8::<BODY>
9::<?php
10::// works with calls from tangle028.htm <br>
11::// ta_1 org from 2008
12::// t1.010 off prohosting
13::// ta.011
14::// ta.012 strip out all .011 stuff and start over parsting error
15::// ta.013 law of sines working
16::// ta.015 put in comparison stuff into triangle class (not used yet) got dump of sides to work
17::// ta.016 sorts, but needs cleaning up need to move where sorted and note sorted length index
18::// also not getting toBool function to find falses
19::// ta.017 working on items of .016
20::// ta.018 working on list of .016 getting usort to work
21::// ta.019 still on .016 list cleaning up
22::// ta.020 ... ta.022 cleaned up from .016 list on to graphing
23::// ta.023 counts file entries and forms name
24::// ta.024 last and web page before making as an image
25::// mistake to try to make an image
26::// .027 back from .024 or .025
27::// .028 built long GET list to make image files
28::// .029 still working on making long GET list
29::// ,031 getting close on GET string
30::// .032
31::// .033 incorporated call to grphTri.php
32::// .035 is graphing but messy
33::// .036 building table to show results
34::// .037 my_Echo works
35::// .038
36::// .039
37::// .040 problems with line 386 $failureMsg
38::// .041
39::// .042 putting givens and calc values into left cell
40::// .043 better message when called with 0's in values fields
41::// .044 saved to "A" directory
42::// .045 saved for "B" dir added support for passed in $Title and T1sl[] and T2sl[]
43::// .046 saved for "B" dir
44:: $solnCnt = 0;
45::
46:: $showInfo = true;
47::
48::function my_Echo($input)
49:: {
50:: global $temp_outPut;
51:: $temp_outPut .= $input;
52:: if(true) // set to false to turn off echo
53:: echo $input;
54:: }
55::
56::// my_Echo("TEST MY ECHO \$showInfo = $showInfo TEST MY ECHO ");
57::
58::
59::$leftCell = ""; // text content on page assigned to left cell of table
60::$failureMsg = ""; // message why doesn't graph
61::
62::function Bool2Str($strIn)
63:: {
64:: if( substr( strtoupper($strIn),0,1) == "T")
65:: return TRUE;
66:: return FALSE;
67:: }
68::
69::
70::function dataI($item,$sCnt,$type,$Givens)
71:: {
72:: return $dex =($sCnt-1)*6+ ($type-1)*3+$item+($Givens-1)*12;
73:: }
74::function bldItemName($item,$sCnt,$type)
75:: {
76:: $name= "P_Val_";
77:: if($type == 1)
78:: $name= $name."S";
79:: else
80:: $name= $name."A";
81:: $name= $name.$item."_".$sCnt;
82:: return $name;
83:: }
84::function str2Bool($Input)
85:: {
86::// var $retVal;
87:: $firstChar = "";
88:: $retVal = false;
89:: $firstChar = Substr($Input,0,1);
90:: switch($firstChar)
91:: {
92:: case "T":
93:: case "t":
94:: $retVal = true;
95:: break;
96:: case "F":
97:: case "f":
98:: default:
99:: $retVal = false;
100:: break;
101:: }
102:: return $retVal;
103:: }
104::
105::
106::class side
107:: {
108:: var $length;
109:: var $given;
110:: var $sideNum;
111:: var $sideLabel;
112:: function setLength($value)
113:: {
114:: $this->length = $value;
115:: }
116:: function getLength()
117:: {
118:: return $this->length;
119:: }
120:: function setGiven($value)
121:: {
122:: $this->given = $value;
123:: }
124:: function getGiven()
125:: {
126:: return $this->given;
127:: }
128:: function setSideNum($value)
129:: {
130:: $this->sideNum = $value;
131:: }
132:: function getSideNum()
133:: {
134:: return $this->sideNum;
135:: }
136:: function setsideLabel($value)
137:: {
138:: $this->sideLabel = $value;
139:: }
140:: function getsideLabel()
141:: {
142:: return $this->sideLabel;
143:: }
144:: }
145::
146::class angle
147:: {
148:: var $angle;
149:: var $given;
150:: function setAngle($value)
151:: {
152:: $this->angle = $value;
153:: }
154:: function getAngle()
155:: {
156:: return $this->angle;
157:: }
158:: function setGiven($value)
159:: {
160:: $this->given = $value;
161:: }
162:: function getGiven()
163:: {
164:: return $this->given;
165:: }
166:: }
167::
168::// see http://stackoverflow.com/questions/4282413/php-sort-array-of-objects-by-object-fields
169::// for using usort
170::
171:: function revCompSidesLengths($a,$b)
172:: {
173:: // $a,$b being side objects in array sides of this triangle object
174:: // compares the lengths field
175:: // used by usort function for arrays
176:: // see http://stackoverflow.com/questions/4282413/php-sort-array-of-objects-by-object-fields
177:: if($a->length < $b->length)
178:: return 1;
179:: if($b->length < $a->length)
180:: return -1;
181:: return 0;
182:: }
183::
184:: function compSidesSideNum($a,$b)
185:: {
186:: // $a,$b being side objects in array sides of this triangle object
187:: // compares the sideNums field
188:: // used by usort function for arrays
189:: // see http://stackoverflow.com/questions/4282413/php-sort-array-of-objects-by-object-fields
190:: if($a->sideNum > $b->sideNum)
191:: return 1;
192:: if($b->sideNum > $a->sideNum)
193:: return -1;
194:: return 0;
195:: }
196::
197::
198::
199::
200::class tAngle
201:: {
202:: var $sides;
203:: var $angles;
204:: var $long2Short;
205:: var $setsOK = true;
206:: var $devMsg = "";
207:: // **** following for graphing
208:: var $IWidth; // wdth of image Make 400 in constructor
209:: var $IHMargin; // horizontal margin Make 15 in constuctor
210:: var $IVMargin; // vertical margin Set the same in construction
211:: var $IMinHeight; // NOt sure set in constructor
212:: var $IHeight ; // Greater of $IMinHeight or 2 * $IVMargin + height of graphed triangle
213:: var $iName;
214:: var $Title;
215:: function tAngle()
216:: {
217:: $this->sides = array ( new side(), new side(), new side() );
218:: $this->angles = array ( new angle(), new angle(), new angle() );
219:: $this->long2Short = array (0,1,2); // Dummy Data will give indices for $sides from longest to shortest
220:: $this->devMsg = "";
221::
222:: $this->IWidth = 400;
223:: $this->IHMargin = 15;
224:: $this->IVMargin = $this->IHMargin;
225:: $this->IMinHeight = 200; // arbitrary determine later
226:: $this->iName = "" ; // set later
227::
228:: $Title;
229:: }
230::
231:: function YtoGCoord($y)
232:: {
233:: if( ($retval = $this->IHeight-$y) < 0)
234:: {
235:: $retval = 0;
236:: }
237:: return $retval;
238:: }
239:: function prepareGraph()
240:: {
241:: $retVal = "";
242:: // graphics coordinates are from upper left with to right and down being positive
243:: // these calculations will be done using lower right as 0,0 and a transformation will be done
244::
245:: // Graph will have longest side (a) being a horizontal line at bottom
246:: // shortest side (c) will be at left side
247:: // Vertices are labeled opposite across the triangle from the side number
248:: // so A is the peak, B is left and C is right
249::
250:: // Determine a scaling factor margins on either side of longest side
251:: $this->dumpArrays();
252:: $longSideNum = $this->long2Short[0];
253:: $longSideLen = $this->sides[($longSideNum-1)]->getLength();
254:: $scaleFactor = ($this->IWidth - 2.0 * $this->IHMargin) / $longSideLen;
255::
256::
257:: // Since the shortest side is at the left, the angle for the opposite the mid
258:: // length side is at the left
259:: $midAngRad = $this->angles[($this->long2Short[1]-1)]->getAngle() * pi()/180;
260:: $shortSideLen = $this->sides[($this->long2Short[2]-1)]->getLength();
261::
262::
263:: // using short side as hypotenuse and angle opposite mid length side
264:: // determine height to peak and offset of peak from left
265:: $height = sin( $midAngRad )*$shortSideLen;
266:: $offset = cos( $midAngRad )*$shortSideLen;
267::
268:: $scaleHeight = round($height* $scaleFactor);
269:: $scaleOffset = round($offset* $scaleFactor);
270::
271:: if( ($this->IHeight = $this->IVMargin*2+$scaleHeight ) <$this->IMinHeight )
272:: $this->IHeight = $this->IMinHeight;
273::
274:: $this->IHeight = 400;
275::
276:: $S1= round($this->sides[0]->getLength(),1);
277:: $S2= round($this->sides[1]->getLength(),1);
278:: $S3= round($this->sides[2]->getLength(),1);
279:: $Title= $this->iName;
280:: if(strlen($tempStr=$this->sides[0]->getsideLabel()) >0)
281:: $S1 = $tempStr;
282:: if(strlen($tempStr=$this->sides[1]->getsideLabel()) >0)
283:: $S2 = $tempStr;
284:: if(strlen($tempStr=$this->sides[2]->getsideLabel()) >0)
285:: $S3 = $tempStr;
286:: if(strlen($tempStr=$this->Title) >0)
287:: $Title = $tempStr;
288::
289:: $retVal = "width=$this->IWidth&".
290:: "height=$this->IHeight&".
291:: "Ybase=".$this->YtoGCoord($this->IVMargin)."&".
292:: "Ypeak=".$this->YtoGCoord($this->IVMargin+$scaleHeight)."&".
293:: "Xleft=$this->IHMargin&".
294:: "Xpeak=".($this->IHMargin+ $scaleOffset)."&".
295:: "Xright=".($this->IWidth-$this->IHMargin)."&".
296:: "Aside=".$this->long2Short[0]."&".
297:: "Bside=".$this->long2Short[1]."&".
298:: "Cside=".$this->long2Short[2]."&".
299:: "S1=$S1&".
300:: "S2=$S2&".
301:: "S3=$S3&".
302:: "A1=".round($this->angles[0]->getAngle(),1)."&".
303:: "A2=".round($this->angles[1]->getAngle(),1)."&".
304:: "A3=".round($this->angles[2]->getAngle(),1)."&".
305:: "iName=".$this->iName."&".
306:: "Title=$Title";
307::
308::
309:: return $retVal;
310:: }
311:: function setSideAng($V,$S,$Sg,$A,$Ag,$Side)
312:: {
313:: $this->sides[$V]->setLength($S);
314:: $this->sides[$V]->setGiven($Sg);
315:: $this->sides[$V]->setSideNum($Side);
316:: $this->angles[$V]->setAngle($A);
317:: $this->angles[$V]->setGiven($Ag);
318:: if( ($S <=0) OR ($A <=0) )
319:: $this->setsOK = false;
320:: }
321:: function dumpSideInfoAng($V)
322:: {
323:: $retVal = "Side:".$this->sides[$V]->getSideNum()." Length:". $this->sides[$V]->getLength($S).
324:: "Side is Given:".$this->sides[$V]->getGiven()." Opposite Angle:".$this->angles[$V]->getAngle().
325:: "Angle is Given:".$this->angles[$V]->getGiven();
326:: return $retVal;
327:: }
328:: function dumpArrays()
329:: {
330:: $retVal = $this->dumpSideInfoAng(0)."<br>\n".$this->dumpSideInfoAng(1)."<br>\n".
331:: $this->dumpSideInfoAng(2)."<br>\n";
332:: return $retVal;
333:: }
334::
335:: function findLong2Short()
336:: {
337::// for info on usort see
338::// http://stackoverflow.com/questions/4282413/php-sort-array-of-objects-by-object-fields
339::
340::
341:: usort($this->sides,"revCompSidesLengths");
342:: // note order of sides sorted by length
343:: for($cnt=0; $cnt < 3; $cnt++)
344:: $this->long2Short[$cnt] = $this->sides[$cnt]->getSideNum();
345::
346::
347:: usort($this->sides,"compSidesSideNum");
348:: }
349::
350::
351:: function checkLawOfSines()
352:: {
353:: $ave = 0;
354:: $maxDev = 0;
355:: $tempDev = 0;
356:: $length = 0;
357:: $angR = 0;
358:: $this->devMsg = "";
359:: for($cnt = 0; $cnt<3;$cnt++)
360:: {
361:: $angR = $this->angles[$cnt]->getAngle()*pi()/180.0;
362:: $length = $this->sides[$cnt]->getLength();
363:: if($length <=0)
364:: return false; // can't divide by 0
365:: else
366:: {
367:: $ave += sin($angR)/($length*3); // save dividing by 3 later
368:: }
369:: }
370:: for($cnt = 0; $cnt<3;$cnt++)
371:: {
372:: $angR = $this->angles[$cnt]->getAngle()*pi()/180.0;
373:: $length = $this->sides[$cnt]->getLength();
374:: if( ($tempDev = ( abs( ( sin($angR)/$length - $ave )/$ave) ) )> $maxDev)
375:: $maxDev = $tempDev;
376:: }
377:: if($maxDev > 0.005)
378:: $this->devMsg = "\$maxDev = $maxDev ";
379:: if($maxDev > 0.02) // 2%
380:: return false;
381:: return true;
382:: }
383:: }
384::
385::
386::
387::$TriAngle = array (new tAngle(), new tAngle());
388::
389::if(isset($Title))
390:: {
391:: $TriAngle[0]->Title = $Title;
392:: $TriAngle[1]->Title = $Title;
393:: }
394::
395::for($cnt = 0; $cnt <3; $cnt++)
396:: {
397:: if(isset($T1S))
398:: $TriAngle[0]-> setSideAng($cnt,($T1S[$cnt]*1),str2Bool($T1Sg[$cnt]),($T1A[$cnt]*1),str2Bool($T1Ag[$cnt]),($cnt+1));
399:: else
400:: $failureMsg .= 'program was called without variable "T1S" (and presumably others) not set <br>\n';
401:: if(isset($T1Sl))
402:: {
403:: $TriAngle[0]->sides[$cnt]->setsideLabel($T1Sl[$cnt]);
404::// $TriAngle[0]->$sides[$cnt]->setsideLabel("");
405:: }
406:: else
407:: $TriAngle[0]->sides[$cnt]->setsideLabel("");
408:: if(isset($T2S))
409:: $TriAngle[1]-> setSideAng($cnt,($T2S[$cnt]*1),str2Bool($T2Sg[$cnt]),($T2A[$cnt]*1),str2Bool($T2Ag[$cnt]),($cnt+1));
410:: if(isset($T2Sl))
411:: {
412:: $TriAngle[1]->sides[$cnt]->setsideLabel($T2Sl[$cnt]);
413::// $TriAngle[1]->$sides[$cnt]->setsideLabel("");
414:: }
415:: else
416:: $TriAngle[1]->sides[$cnt]->setsideLabel("");
417:: }
418::if(!($TriAngle[0]->setsOK))
419:: $failureMsg .= 'one or more angle or side values is 0 or less -- most likely triangle not solved on calling page '."<br>\n";
420::
421:: if(isset($T1S))
422:: if($TriAngle[0]->checkLawOfSines())
423:: {
424:: $solnCnt++;
425:: $TriAngle[0]->findLong2Short();
426:: if(isset($T2S))
427:: if($TriAngle[1]->checkLawOfSines())
428:: {
429:: $solnCnt++;
430:: $TriAngle[1]->findLong2Short();
431:: }
432:: else
433:: $failureMsg .= 'Inconsistancies found in data for solution 2 :: specificly ratios of sines of angles to opposite sides not constant <br>';
434::
435:: }
436:: else
437:: $failureMsg .= 'Inconsistancies found in data:: specificly ratios of sines of angles to opposite sides not constant <br>';
438::
439::
440::
441::$imgCntFile = "./cntPicts.txt";
442::if(file_exists($imgCntFile))
443:: {
444:: $fp = fopen($imgCntFile,"r");
445:: $imgCnt= (int) fread($fp,20);
446:: fclose($fp);
447:: }
448::else
449:: $imgCnt= 515; // arbitrary #'s
450::
451::if( $imgCnt > 32000)
452:: $imgCnt= 103; // arbitrary #'s
453::
454::
455:: $fp = fopen($imgCntFile,"w");
456:: fwrite($fp,($imgCnt+$solnCnt));
457:: fclose($fp);
458::
459::
460:: // $this->long2Short = array (0,1,2); // Dummy Data will give indices for $sides from longest to shortest
461:: $solnSubSt = ""; // adds solution count if more than a
462:: $imgHTML_Str = array("","");
463:: for($cnt=0; $cnt<$solnCnt; $cnt++)
464:: {
465:: if($solnCnt>1)
466:: {
467:: $solnSubSt=" Solution: ".($cnt+1);
468:: if( strlen($tempStr = $TriAngle[0]->$Title)>0)
469:: $TriAngle[$cnt]->$Title = "$tempStr $solnSubSt";
470:: }
471:: $tempName="000000".($imgCnt+$cnt);
472:: $tempLen = strlen($tempName);
473:: $tempName = Substr($tempName,$tempLen-5,5);
474:: // should have used sprintf in 3 preceeding lines
475:: $TriAngle[$cnt]->iName = $tempName.$solnSubSt;
476:: $argStr= 'grphTri.php?'.$TriAngle[$cnt]->prepareGraph();
477:: $imgHTML_Str[$cnt] = "<img src=\"$argStr\" align=\"right\" alt=\"$argStr\" width=\"400\" height=\"400\">\n";
478:: }
479::///// *************************
480:: echo '<br clear="all">';
481::if($solnCnt > 0)
482:: {
483:: $leftCell .= "Given Values:<ul>\n";
484:: for($cnt=0; $cnt<3; $cnt++)
485:: if($TriAngle[0]->sides[$cnt]->getGiven())
486:: $leftCell .= "<li> Side ".($cnt+1)." = ".$TriAngle[0]->sides[$cnt]->getLength()."\n";
487:: for($cnt=0; $cnt<3; $cnt++)
488:: if($TriAngle[0]->angles[$cnt]->getGiven())
489:: $leftCell .= "<li> Angle ".($cnt+1)." = ".$TriAngle[0]->angles[$cnt]->getAngle()."\n";
490:: $leftCell .= "</ul>\n";
491::
492:: $MoreSoln = "";
493:: for($cnt2 = 0; $cnt2 <$solnCnt; $cnt2++)
494:: {
495:: if($solnCnt > 1)
496:: $MoreSoln = "Solution ".($cnt2+1)." ";
497:: $leftCell .= "$MoreSoln Calculated Values:<ul>\n";
498:: for($cnt=0; $cnt<3; $cnt++)
499:: if(!($TriAngle[$cnt2]->sides[$cnt]->getGiven()))
500:: $leftCell .= "<li> Side ".($cnt+1)." = ".$TriAngle[$cnt2]->sides[$cnt]->getLength()."\n";
501:: for($cnt=0; $cnt<3; $cnt++)
502:: if(!($TriAngle[$cnt2]->angles[$cnt]->getGiven()))
503:: $leftCell .= "<li> Angle ".($cnt+1)." = ".$TriAngle[$cnt2]->angles[$cnt]->getAngle()."\n";
504:: $leftCell .= "</ul>\n";
505:: }
506::
507::
508::
509:: echo '<table border="0">';
510:: echo '<tr><td ';
511:: if($solnCnt > 1)
512:: echo ' rowspan="2" ';
513:: echo "> \n $leftCell \n</td>\n <td> \n". $imgHTML_Str[0]."</td></tr>\n";
514:: if($solnCnt > 1)
515:: {
516:: echo '<tr><td> '.$imgHTML_Str[1]."\n</td></tr>\n";
517:: }
518:: echo "</table>\n";
519:: }
520::else
521:: echo $failureMsg;
522::
523::
524::
525::////////////////////////
526::// REMAINING STUFF IS VARIABLE DUMPING CODE TURNED OFF BY NEXT IF(FALSE)
527::////////////////////////
528::
529::if(false) {
530::echo "<hr>";;
531::// echo 'var_dump($_POST)<br>';
532::var_dump($_POST);
533::echo "<hr>";
534::// phpinfo();
535::echo "Passed Variables:<br>\n";
536::if (is_array($_POST) && count($_POST) > 1)
537:: {
538:: if(isset($_POST["hGSoln"]))
539:: echo "<br> found set <br>".$_POST["hGSoln"]." ".Bool2Str($_POST["hGSoln"])."<br>";
540::// $message = '';
541:: foreach ($_POST as $passedVar)
542:: echo " $passedVar isarray".is_array($passedVar)." isInt".is_int($passedVar)." <br>\n";
543:: }
544::echo "<br><br><hr><br><br>\n";
545::
546::
547::if (is_array($_POST) && count($_POST) > 1)
548:: {
549::// $message = '';
550:: foreach ($_POST as $passedVar)
551:: echo " $passedVar isarray".is_array($passedVar)." isInt".is_int($passedVar)." <br>\n";
552:: }
553::echo "<br><br><br><br>\n";
554::}
555::?>
556::
557::</BODY>
558::</HTML>