Ticket UUID: | 608559 | |||
Title: | ptr smash start error / wish exit / windows | |||
Type: | Bug | Version: | obsolete: 8.4.0 | |
Submitter: | arjenmarkus | Created on: | 2002-09-12 19:24:01 | |
Subsystem: | None | Assigned To: | hobbs | |
Priority: | 8 | Severity: | ||
Status: | Closed | Last Modified: | 2003-02-19 02:28:38 | |
Resolution: | Fixed | Closed By: | hobbs | |
Closed on: | 2003-02-18 19:28:38 | |||
Description: |
In the script below, running the display command causes a fatal error. I have traced it to the "lsort -command compareView" command in that proc. Using a trivial comparison procedure does not produce the error (e.g. compareView2). # solids3d.tcl -- # # Package for displaying 3D solid bodies # (sample Workbench module) # # Notes: # This package is a quick hack to get started only # # Version information: # version 0.2: improved sorting of polygons, september 2002 # version 0.1: initial implementation, september 2002 package provide Solids3D 0.1 namespace eval ::Solids3D { namespace export func deriv variable display_options # normalToPlane -- # Return the normal vector to a plane given as three points # # Arguments: # point1 First point # point2 Second point # point3 Third point # # Result: # Vector {x,y,z}, a normal vector to the plane # proc normalToPlane {point1 point2 point3} { foreach {dummy px1 py1 pz1} $point1 {break} foreach {dummy px2 py2 pz2} $point2 {break} foreach {dummy px3 py3 pz3} $point3 {break} set vx1 [expr {$px2-$px1}] set vy1 [expr {$py2-$py1}] set vz1 [expr {$pz2-$pz1}] set vx2 [expr {$px3-$px1}] set vy2 [expr {$py3-$py1}] set vz2 [expr {$pz3-$pz1}] set nx [expr {$vy1*$vz2-$vz1*$vy2}] set ny [expr {$vz1*$vx2-$vx1*$vz2}] set nz [expr {$vx1*$vy2-$vy1*$vx2}] return [list VECTOR $nx $ny $nz] } # pointOnTorus -- # Return the coordinates of a point on a torus, as given by # two parameters (angles) # # Arguments: # phi Angle with respect to x-axis # theta Angle with respect to "inner" axis of torus # # Result: # Point {x,y,z}, the coordinates of the point # proc pointOnTorus {phi theta} { set cosphi [expr {cos($phi)}] set sinphi [expr {sin($phi)}] set costh4 [expr {0.25*cos($theta)}] set sinth4 [expr {0.25*sin($theta)}] set x [expr {$cosphi*(1.0+$costh4)}] set y [expr {$sinphi*(1.0+$costh4)}] set z [expr {1.0+$sinth4}] return [list POINT $x $y $z] } # constructTorus -- # Return a list of polygons, together forming an approximation to a # torus # # Arguments: # nophi Number of steps along main perimeter # notheta Number of steps along secondary perimeter # # Result: # List of polygons # proc constructTorus {nophi notheta} { variable angle set pi 3.1415926 set dphi [expr {2.0*$pi/double($nophi)}] set dtheta [expr {2.0*$pi/double($notheta)}] set polygons {POLYGON-LIST} for { set iphi 0 } { $iphi < $nophi } { incr iphi } { set phi1 [expr {$dphi*double($iphi)}] set phi2 [expr {$dphi*double($iphi+1)}] for { set itheta 0 } { $itheta < $notheta } { incr itheta } { set theta1 [expr {$dtheta*double($itheta)}] set theta2 [expr {$dtheta*double($itheta+1)}] set point1 [pointOnTorus $phi1 $theta1] set point2 [pointOnTorus $phi1 $theta2] set point3 [pointOnTorus $phi2 $theta2] set point4 [pointOnTorus $phi2 $theta1] set red [expr {int(125*(1.0+cos($phi1)))}] set green [expr {int(125*(1.0+sin($phi1)))}] set blue [expr {int(125*(1.0+sin($theta1)))}] set colour [format "#%2.2X%2.2X%2.2X" $red $green $blue] # set zdepth [lindex [rotateY $angle $point1] 3] set normal [normalToPlane $point1 $point2 $point4] lappend polygons \ [list POLYGON $colour $normal $point1 $point2 $point3 $point4] } } return $polygons } # rotateY -- # Rotate around the y axis # # Arguments: # angle Angle over which to rotate # point Point to rotate # # Result: # New coordinates # proc rotateY {angle point} { foreach {dummy x y z} $point break set xr [expr {$x*cos($angle)-$z*sin($angle)}] set yr $y set zr [expr {$x*sin($angle)+$z*cos($angle)}] return [list POINT $xr $yr $zr] } # projectOnYZ -- # Project a point on the YZ-plane (and scale as we do this) # # Arguments: # point Point to rotate # # Result: # XY coordinates (for the screen) # proc projectOnYZ {point} { variable scale variable yoffset variable zoffset foreach {dummy x y z} $point break set xp [expr {int($scale*($y-$yoffset))}] set yp [expr {int($scale*($zoffset-$z))}] return [list $xp $yp] } # compareView -- # Compare the relative position of two polygons w.r.t. the viewpoint # # Arguments: # polygon1 First polygon # polygon2 Second polygon # # Result: # 1, -1 if the first polygon lies before or after the second, # 0, if they intersect # # Note: # The third element of the list that constitutes a polygon (index 2!) # is supposed to be a vector normal to the polygon. For reasons of # speed. # proc compareView2 {polygon1 polygon2} { return 1 } proc compareView {polygon1 polygon2} { variable angle variable viewpoint # # Determine the relevant sign # foreach {dummy nx ny nz} [lindex $polygon1 2] {break} foreach {dummy vx vy vz} $viewpoint {break} set vn [expr {$nx*$vx+$ny*$vy+$nz*$vz}] if { $vn < 0 } { set nx [expr -$nx] set ny [expr -$ny] set nz [expr -$nz] } # # For each point of the second polygon, does the inproduct have # the same sign? If the number of identical signs is 4, then # polygon lies either on the same side as the viewpoint or # on the opposite side, but we have reached a conclusion. # set count 0 foreach point [lrange $polygon2 3 end] { foreach {dummy px py pz} $point {break} set pn [expr {$nx*$px+$ny*$py+$nz*$pz}] if { $pn > 0.0 } { incr count } else { incr count -1 } } if { $count == 4 } { return -1 } elseif { $count == -4 } { return 1 } else { set rc [compareView $polygon2 $polygon1] expr {-$rc} } } # display -- # Quick and dirty implementation to display a set of polygons # # Arguments: # polygons List of 3D polygons # # Result: # None # # Side effect: # Display of polygons in the canvas # proc display {polygons} { variable angle variable viewpoint set viewpoint [list POINT [expr cos($angle)] 0.0 [expr sin ($angle)]] # # Sort the polygons first # Note: # The comparison is too simple, but for now it should work # set plane_polygons [lrange $polygons 1 end] set sorted_polygons [lsort -command compareView $plane_polygons] foreach polygon $sorted_polygons { set colour [lindex $polygon 1] set points [lrange $polygon 3 end] set coords {} foreach point $points { set coords [concat $coords [projectOnYZ [rotateY $angle $point]]] } .cnv create polygon $coords -fill $colour -outline black } } # # Initialise the variables # variable angle [expr {0.25*3.1415926}] variable scale 100.0 variable yoffset -1.5 variable zoffset 2.0 } ;# End of namespace # # Run the program # canvas .cnv -width 300 -height 300 -background white pack .cnv -fill both set torus [::Solids3D::constructTorus 16 16] ::Solids3D::display $torus | |||
User Comments: |
hobbs added on 2003-02-19 02:28:38:
Logged In: YES user_id=72656 This is an ... expected problem in that oversize windows can fail on some window managers. In this case, the MessageBox was displaying a very long error. Since I can't see the value in very long errors there, I have truncated the displayed text to no more than 1024 chars for 8.4.2. This applies to startup errors only, not tk_messageBox in general. BTW, this was a Tk bug. kennykb added on 2003-02-16 03:39:37: Logged In: YES user_id=99768 I'm puzzled about why this one is assigned to me. All I did was reproduce the failure on my box. I'm not usually a Tk maintainer, although I'll be glad to help. hobbs added on 2002-10-22 05:14:49: Logged In: YES user_id=72656 I believe this error is due to window size limitations, as the error that pops up shows an enormous trace of the loop (goes way off screen to the bottom). I can't repro it on Win2K, but I'm fairly sure that's the problem. In general, Tk has to do a better job of limiting window size requests to < 32K pixels, in almost all cases. There are various ways you can make Tk blow up this way, on both Windows and X. dgp added on 2002-10-10 21:57:01: Logged In: YES user_id=80530 anything here we can fix for 8.4.1 ? dgp added on 2002-09-13 20:08:27: Logged In: YES user_id=80530 The submitted code has its own bugs, yes, but that's not the point. I triggers a startup error message in wish, and there is a pointer smash in the handling of that message on Windows (98?), that we still need to dig out and fix. dkf added on 2002-09-13 15:46:47: Logged In: YES user_id=79902 That's a really strange comparison routine; it doesn't even work. The one below does though (and is much faster too) so I suspect we've got a case of "pilot error". (And I don't see a crash on IRIX anyway.) proc compareView {polygon1 polygon2} { set x1 0.0 foreach point [lrange $polygon1 3 end] { foreach {dummy px py pz} $point {break} set x1 [expr {$x1+$px}] } set x2 0.0 foreach point [lrange $polygon2 3 end] { foreach {dummy px py pz} $point {break} set x2 [expr {$x2+$px}] } if {$x1<$x2} { return 1 } elseif {$x1>$x2} { return -1 } else { return 0 } } dgp added on 2002-09-13 03:04:06: Logged In: YES user_id=80530 This is really a Tk bug. Something in an exit handler. dgp added on 2002-09-13 02:51:34: Logged In: YES user_id=80530 Does the script: proc infinite {} { infinite } infinite also reproduce the bug? kennykb added on 2002-09-13 02:38:50: File Added - 31002: c:/users/kennykb/tmp/arjen.tcl Logged In: YES user_id=99768 Source above is damaged by the SF display engine. Uploading a clean copy |