Beispiel #1
0
Intersection sceneObjectCylinderIntersectRay(const SceneObject *superobject, const Ray ray) {

	const SceneObjectCylinder *object = (SceneObjectCylinder *) superobject;

	Intersection intersection = cIntersect(object->cylinder, ray);
	intersection.material = object->material;

	return intersection;
}
Beispiel #2
0
VOID vClipSolid(
PDEV*       ppdev,
LONG        crcl,
RECTL*      prcl,
ULONG       iColor,
CLIPOBJ*    pco)
{
    BOOL            bMore;              // Flag for clip enumeration
    CLIPENUM        ce;                 // Clip enumeration object
    ULONG           i;
    ULONG           j;
    RECTL           arclTmp[4];
    ULONG           crclTmp;
    RECTL*          prclTmp;
    RECTL*          prclClipTmp;
    LONG            iLastBottom;
    RECTL*          prclClip;
    RBRUSH_COLOR    rbc;

    ASSERTDD((crcl > 0) && (crcl <= 4), "Expected 1 to 4 rectangles");
    ASSERTDD((pco != NULL) && (pco->iDComplexity != DC_TRIVIAL),
                       "Expected a non-null clip object");

    rbc.iSolidColor = iColor;
    if (pco->iDComplexity == DC_RECT)
    {
        crcl = cIntersect(&pco->rclBounds, prcl, crcl);
        if (crcl != 0)
        {
            (ppdev->pfnFillSolid)(ppdev, crcl, prcl, OVERPAINT, OVERPAINT,
                                  rbc, NULL);
        }
    }
    else // iDComplexity == DC_COMPLEX
    {
        // Bottom of last rectangle to fill

        iLastBottom = prcl[crcl - 1].bottom;

        // Initialize the clip rectangle enumeration to right-down so we can
        // take advantage of the rectangle list being right-down:

        CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);

        // Scan through all the clip rectangles, looking for intersects
        // of fill areas with region rectangles:

        do {
            // Get a batch of region rectangles:

            bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (VOID*)&ce);

            // Clip the rect list to each region rect:

            for (j = ce.c, prclClip = ce.arcl; j-- > 0; prclClip++)
            {
                // Since the rectangles and the region enumeration are both
                // right-down, we can zip through the region until we reach
                // the first fill rect, and are done when we've passed the
                // last fill rect.

                if (prclClip->top >= iLastBottom)
                {
                    // Past last fill rectangle; nothing left to do:

                    return;
                }

                // Do intersection tests only if we've reached the top of
                // the first rectangle to fill:

                if (prclClip->bottom > prcl->top)
                {
                    // We've reached the top Y scan of the first rect, so
                    // it's worth bothering checking for intersection.

                    // Generate a list of the rects clipped to this region
                    // rect:

                    prclTmp     = prcl;
                    prclClipTmp = arclTmp;

                    for (i = crcl, crclTmp = 0; i-- != 0; prclTmp++)
                    {
                        // Intersect fill and clip rectangles

                        if (bIntersect(prclTmp, prclClip, prclClipTmp))
                        {
                            // Add to list if anything's left to draw:

                            crclTmp++;
                            prclClipTmp++;
                        }
                    }

                    // Draw the clipped rects

                    if (crclTmp != 0)
                    {
                        (ppdev->pfnFillSolid)(ppdev, crclTmp, &arclTmp[0],
                                             OVERPAINT, OVERPAINT, rbc, NULL);
                    }
                }
            }
        } while (bMore);
    }
}
Beispiel #3
0
int main(){
   //Open the input file
   FILE *fin;
   fin = fopen("mice.in", "r");

   int times, k;

   //Scan in the number of ponds to process
   fscanf(fin, "%d\n", &times);

   //Begin processing input
   for(k = 1; k <= times; k++){
      //Read in case data
      double rp, rh, x, y;
      int irp, irh, ix, iy;
      fscanf(fin, "%d %d %d %d", &irp, &irh, &ix, &iy);
      rp = (double)irp;
      rh = (double)irh;
      x = (double)ix;
      y = (double)iy;

      /* The largest rectangle that fits the constraints of the problem, one side being twice the length of the other,
         and fits inside of the circle, will be inscribed in the circle. That is, its four points will all touch the circle's edge and its center
         will be the origin

         We'll assume the short side of the rectangle is length L, and the long side length 2L. Therefore, its area is 2*L^2.

         If we break the rectangle up into 8 right triangles by drawing lines from the origin to its corners and perpendicular lines bisecting its sides,
         we find that one of these triangles has sides L, (1/2)*L, and rp. Using the pythagorean theorem, we find that

         rp^2 = L^2 + (1/4)*L^2.
         rp^2 = (5/4)*L^2
         (4/5)*rp^2 = L^2

         Therefore, using the area we came up with earlier, we can replace L^2 and find that the area of the largest possible rectangle is in fact

         A = 2*((4/5)*rp^2) */

      double L = sqrt(rp*rp*4./5.); //Length of the shorter side
      double area = 2.*L*L; //Area of the original rectangle
      double narea = 0; //Area of the new rectangle

      struct Point o = nP(0, 0); //Point representing the origin
      struct Point holeCenter = nP(x, y); //Point representing the center of the hole

      //Find the two points in the hole at which the line extending from the origin to the hole center intersects with the hole
      struct Point *consider = cIntersect(rh, holeCenter, o, holeCenter);
      struct Point i; //We will place the closer of the two in this struct

      //If the hole is centered on the origin, we will need to choose two arbitrary points on the hole's circumference, as there is no line
      if(x==0&&y==0){
         consider[0] = nP(0,rh);
         consider[1] = nP(0,-rh);
      }

      //Choose the point which is closer to the origin
      if(dis(consider[0], o) < dis(consider[1], o)){
         i = consider[0];
      }else{
         i = consider[1];
      }

      //printf("Considering (%.2f %.2f) and (%.2f %.2f)\n", consider[0].x, consider[0].y, consider[1].x, consider[1].y);

      /*  Once we have this point, we will attempt to calculate the area of the largest rectangle that could be placed adjacent to it.
          Consider the placement of the rectangle. Its top side would have to be tangent to this point, touching at the midpoint to maximize its area.

          As such, imagine extending a line from this point at a 45 degree angle downward, until touching the edge of the pond. This line represents
          the diagonal of the left half of the rectangle. Finding the length of this line will allow us to find the area of the rectangle, using the following
          reasoning:

               The diagonal is of length c.
               It forms two isoscoles triangles.
               a^2 + b^2 = c^2
               In an isoscoles triangle, a = b
               a^2 + a^2 = c^2
               2*a^2 = c^2
               If one of the sides is of length a, the area of the square is a^2. Because the rectangle is composed of two of these squares, the rectangle has area 2*a^2.
               Therefore, A_rectangle = 2*a^2 = c^2

          We know that the angle will be extended at a 45 degree angle, but not much else. We do, however, have the circle to work with. By forming a triangle
          using point i, the origin, and the point on the edge of the hole, we can use the law of sines to solve the triangle for c. The length of one of the
          sides is rp, the length of another side is the distance from point i to the origin, and we have the angle of the line we extended, 45 degrees.

          What we find in solving the triangle is that it comes down to three cases. */

      //Three cases
      if(i.x==0&&i.y==0){
         //Case 1: Point i is (0,0)
         //The solution is rp*rp, as the length of the line is the radius of the circle
         narea = rp*rp;
      }else if(dis(o, holeCenter) > rh){
         //Case 2: The origin is outside of the hole, c is the hypotenuse of the triangle
         //Solve for c with sin(45)/r=sin(tb)/p.d((0,0))=sin(tc)/c
         //Solution is c^2
         narea = solveTriangle(45, rp, dis(i, o));
      }else if(dis(o, holeCenter) < rh){
         //Case 3: The origin is inside of the hole, rp is the hypotenuse
         //Solve for c with sin(135)/r=sin(tb)/p.d((0,0))=sin(tc)/c
         //Solution is c^2
         narea = solveTriangle(135, rp, dis(i, o));
      }

      //printf("Before: %.2f After: %.2f\n\n",area, narea);

      printf("Pond #%d:\n",k);
      //If the new area exceeds the original area, there is space for the original area to exist (and the new area actually goes out of bounds!)
      if(narea > area){
         //ICE CLEAR!!!
         printf("ICE CLEAR!!! %.2f\n\n", area);
      }else{
         //OBSTRUCTION!
         printf("OBSTRUCTION! %.2f\n\n", narea);
      }

      //Free your allocated memory
      free(consider);
   }

   return 0;
}