End of Path (pseudo) Author Micro-blog: @GcsSloop "related articles in this series"
Have experienced the basic operation of path and the path of the Bezier curve, this chapter finally into the end of path, this article after the completion of the path of most of the relevant methods have been explained, but path there are some more interesting gameplay, it should be in the subsequent article appears, Ah, should be ˊ_ >ˋ
One. Path Common method table
For compatibility ( lazy ) This table removes the addition of API21 (i.e. Android version 5.0). Can not help but spit groove, why seems to be able to write some of the overloaded method to wait until API21 to add AH. The baby's heart is collapsing at the moment.
function |
Related Methods |
Notes |
Move start |
MoveTo |
Move the start position of the next operation |
Set End point |
Setlastpoint |
Resets the last point position in the current path, if called before drawing, with the same effect as MoveTo |
Connecting lines |
LineTo |
Add a line to the path between the previous point and the current point |
Closed path |
Close |
Connect the first point to the last point to form a closed area |
Add content |
Addrect, Addroundrect, Addoval, Addcircle, Addpath, AddArc, ArcTo |
Add (Rectangle, rounded rectangle, ellipse, circle, Path, arc) to current path (note the difference between AddArc and ArcTo) |
is empty |
IsEmpty |
Determine if path is empty |
Whether it is a rectangle |
Isrect |
Determine if path is a rectangle |
Replace path |
Set |
Replace all content with the current path with a new path |
Offset path |
Offset |
Offsets the operation before the current path (does not affect subsequent operations) |
Bezier curve |
Quadto, Cubicto |
Methods for two and three Bezier curves, respectively |
Rxxx method |
Rmoveto, Rlineto, Rquadto, Rcubicto |
The method without r is based on the origin coordinate system (offset), and the Rxxx method is based on the current point coordinate system (offset) |
Fill mode |
Setfilltype, Getfilltype, Isinversefilltype, Toggleinversefilltype |
Set, get, judge and toggle fill mode |
Hint method |
Increserve |
Indicates how many points of path are waiting to be added (this method seems to allow path to optimize the storage structure) |
Boolean operation (API19) |
Op |
Boolean operation on two path (i.e., intersection, set, etc.) |
Calculate boundary |
Computebounds |
Calculate the bounds of a path |
Reset Path |
Reset, Rewind |
Clear the contents of path Reset does not retain the internal data structure, but it retains the filltype. Rewind retains the internal data structure, but does not retain the Filltype |
Matrix operations |
Transform |
Matrix transformations |
Second, path method detailed Rxxx method
This kind of method can see and some of the previous methods look very similar, just a few more in front of a R, then this rxxx and some of the previous methods what is the difference?
The coordinates of the Rxxx method use relative positions (displacement based on the current point), whereas the previous method's coordinates are absolute (based on the coordinates of the current coordinate system).
As an example:
new Path(); path.moveTo(100,100); path.lineTo(100,200); canvas.drawPath(path,mDeafultPaint);
In this example, move the point to the coordinates (100,100), then the connection Point (100,100) to (100,200) between the point line, very simple, draw is a vertical line, then look at the next example:
new Path(); path.moveTo(100,100); path.rLineTo(100,200); canvas.drawPath(path,mDeafultPaint);
In this example, replace the lineTo with Rlineto to see that the line that was originally vertical on the screen became a slanted line. This is because eventually we connect the line between (100,100) and (+) .
Before using Rlineto, the position of the current point is at (100,100), after using Rlineto (100,200), the position of the next point is based on the current point is added offset, that is (100+100, 100+200) This position, so the final result as shown above.
PS: In this case only Rlineto, as long as the understanding of "absolute coordinates" and "relative coordinates" of the difference, the other method analogy can be.
Fill mode
As we learned in previous articles, paint has three styles, "stroke", "fill", and "stroke and fill," and what we've learned here is the effect of different fill patterns on the graphics rendering effect when paint is set to the last two styles.
We want to give a graphic interior fill color, first need to distinguish which part is external, which part is internal, the machine is not as smart as we are, the machine is how to judge inside and outside?
Machine judging graphics inside and outside, there are generally the following two ways:
PS: All the graphics here are closed graphics, not including graphics not enclosed in this case.
Method |
Judging conditions |
explain |
Odd and even rules |
Odd numbers are inside the graph, even if they are outside the graph |
From any position p as a ray, if the number of graphic edges intersecting with the ray is odd, then P is the interior point of the graph, otherwise it is an external point. |
Non-0 surround number rule |
If the number of wraps is 0, the nonzero representation is outside the graph |
First, turn the edges of the graph into vectors. Initializes the wrapping number to zero. And then make a ray from any position p. When moving from the P-point along the ray direction, the edge count crosses the ray in each direction, and when the edges of the graph pass through the ray from right to left, the wrapping number is added 1, from left to right, and the wrapping number is reduced by 1. After all the related edges of the graph have been processed, p is the inner point if the wrapping number is nonzero, otherwise p is the outer point. |
Now let's look at how the two judgments work.
Parity rules (even-odd rule)
This one is simple and easy to understand, and is illustrated directly with a simple example.
There is a quadrilateral in it, we select three points to determine whether the points are inside the graph.
>
P1: Emits a ray from the P1, finds that the graph intersects the ray with the number of sides is 0, even, so the P1 point is outside the graph.
P2: Emit a ray from the P2, found that the graph and the ray intersection edge number is 1, odd, so P2 points in the interior of the graph.
P3: Emits a ray from the P3, finds that the graph intersects the ray with the number of sides is 2, even, so the P3 point is outside the graph.
Non-0 wrapping rules (non-zero winding number rule)
A non-0 surround number rule is relatively difficult to understand.
In our previous article, path, we learned that when adding graphics to path, you need to specify how you want the graphics to be added, clockwise or counterclockwise, and whether we use Lineto,quadto,cubicto or other connection lines, is connected from one point to another, in other words,any segment in path is directional , which is also the basis for using a non-0 surround number rule.
We still use a simple example to illustrate the use of a non-0 surround number rule:
PS: Note The directionality of the line segments in the graph!
>
P1: Emits a ray from the P1 point, moves along the Ray line, does not intersect with the edge part, the number of wrapping is 0, therefore P1 outside the graph.
P2: Emits a ray from the P2 point, moves along the direction of the beam, intersects the left edge of the graph point, crosses the edge from left to right through the rays, wraps around the number 1, and the final wrap number is-1, so the P2 is inside the graph.
P3: Emit a ray from the P3 point, move along the direction of the ray, at the first intersection, the bottom edge from right to left through the ray, around the number +1, at the second intersection, the right side from left to right through the ray, around the number 1, the final wrapping number is 0, so P3 outside the graph.
In general, the results of these two methods are the same, but there are two ways to judge the results of different situations, such as the following:
Note the direction of the graphic segment, it is not explained in detail, using the above method to judge.
Self-intersecting graphs
Self-intersecting graph definition: Polygons have other common points in the plane except vertices.
Simply mention the self-intersecting graph and understand the concept, which is a simple self-intersecting graph:
The fill mode in Android
There are four types of fill patterns in Android, an enumeration encapsulated in path.
Mode |
Introduction |
Even_odd |
Odd and even rules |
Inverse_even_odd |
Anti-parity rules |
Winding |
Non-0 surround number rule |
Inverse_winding |
Anti-non-0 surround number rule |
We can see that there are four modes, divided into two pairs, such as "parity rule" and "inverse parity rule" is a pair, what is the relationship between them?
Inverse and the meaning is "opposite, polarize", stating that the inverse parity rule is just the opposite of the parity rule, for example, for a rectangle, using the parity rule fills the interior of the rectangle, and using the inverse parity rule fills the outside of the rectangle, which in the following example shows the difference between the two.
How Android is related to fill mode
These are the methods in path.
Method |
function |
Setfilltype |
Set up a fill rule |
Getfilltype |
Get current fill rule |
Isinversefilltype |
Determine if it is a reverse (inverse) rule |
Toggleinversefilltype |
Toggle Fill rule (that is, the original rule and the reverse rule switch to each other) |
Sample Demo:
This presentation focuses on helping to understand some of the difficult and confusing problems in the fill pattern, and for some of the more simple questions, the reader can self-verify that this article will not be overly repetitive.
Parity rules and anti-parity rules
Mdeafultpaint.setstyle (Paint.Style.FILL); //set the canvas mode to fill canvas.translate (mviewwidth/2 , Mviewheight/2 ); //move canvas (coordinate system) Path PATH = new path (); //Create path //path.setfilltype (Path.FillType.EVEN_ODD); Set path fill mode to parity rule path.setfilltype (Path.FillType.INVERSE_WINDING); //anti-parity rule path.addrect (-200 ,-200 , 200 , 200 , Path.Direction.CW); //add a rectangle to path
The following two pictures are the results of the odd-even rule in the case of the inverse parity rule, which shows the exact opposite of the filled area:
PS: White for background color, black for fill color.
The effect of the direction of the graphic edge on the result of a non-0 odd-even surround number rule fill
We discussed the effect of clockwise and counterclockwise when adding graphics to path, and in addition to the handy record we talked about last time, this is another important part of this article: "as the basis of the rule of non-0 surround number." "
We've already got a rough idea of how the direction of the graphics side will affect the fill effect, and we'll verify here:
Mdeafultpaint.setstyle (Paint.Style.FILL);//Set brush mode to fillCanvas.translate (Mviewwidth/2, Mviewheight/2);//Move canvas (seated)Path PATH =NewPath ();//create path //Add small squares (with these two lines of code to control the direction of small square edges to demonstrate different effects) //Path.addrect ( -200, -200, $, Path.Direction.CW);Path.addrect (- $, - $, $, $, Path.Direction.CCW);//Add large squaresPath.addrect (- -, - -, -, -, Path.Direction.CCW); Path.setfilltype (Path.FillType.WINDING);//Set path fill mode to non-0 surround ruleCanvas.drawpath (path, mdeafultpaint);//Draw path
Boolean operation (API19)
The Boolean operation is very similar to the set operation we learned in high school, as long as we know that the collection operation is medium intersection, set and difference set, then it is easy to understand Boolean operation.
Boolean operation is an operation between two paths, the main function is to use some simple graphics to synthesize some relatively complex, or difficult to get directly to the graph .
such as the yin and yang in Tai chi, if made with Bezier curve, it may take six of Bezier curve, and here we can use four path through the Boolean operation, and it is relatively easier to understand a bit.
Canvas.translate (Mviewwidth/2, Mviewheight/2); Path path1 =NewPath (); Path path2 =NewPath (); Path Path3 =NewPath (); Path Path4 =NewPath (); Path1.addcircle (0,0, $, Path.Direction.CW); Path2.addrect (0, - $, $, $, Path.Direction.CW); Path3.addcircle (0, - -, -, Path.Direction.CW); Path4.addcircle (0, -, -, Path.Direction.CCW); Path1.op (path2, Path.Op.DIFFERENCE); Path1.op (Path3, Path.Op.UNION); Path1.op (Path4, Path.Op.DIFFERENCE); Canvas.drawpath (path1, mdeafultpaint);
Before we demonstrate the function of Boolean operations, let's look at the core of Boolean operations: Boolean logic.
The Boolean operation of path has five types of logic, as follows:
Logical Name |
analogy |
Description |
|
Difference |
Subtraction |
The remainder of the Path1 minus Path2 |
|
Reverse_difference |
Subtraction |
The remainder of the Path2 minus Path1 |
|
INTERSECT |
Intersection |
Path1 part of the intersection with PATH2 |
|
UNION |
and set |
Includes all Path1 and Path2 |
|
Xor |
XOR or |
Contains Path1 and Path2 but does not include the intersection of the two parts |
|
Boolean Operation method
Through the front to the theoretical knowledge of bedding, I believe you have a basic understanding and understanding of Boolean operations, the following we use code to demonstrate the Boolean operation:
There are two methods for Boolean operations in Path
boolean op (Path path, Path.Op op) boolean op (Path path1, Path path2, Path.Op op)
The return values in the two methods are used to determine if the Boolean operation was successful, using the following methods:
``
Java
The Boolean operation is performed on path1 and path2, and the operation is specified by the second parameter, and the result is deposited into the path1.
Path1.op (path2, Path.Op.DIFFERENCE);
// 对 path1 和 path2 执行布尔运算,运算方式由第三个参数指定,运算结果存入到path3中。path3.op(path1, path2, Path.Op.DIFFERENCE)
# # # Boolean Operation example! [] (HTTP://WW1. Sinaimg. CN/large/005Xtdi2gw1f43jz8xnbxj308c0etwes. jpg) Code: "' Java intx= the;int r = -;Canvas. Translate( -,0);Path path1 = new Path ();Path path2 = new Path ();Path Pathopresult = new Path ();Path1. Addcircle(-x,0, R, Path. Direction. CW);path2. Addcircle(x,0, R, Path. Direction. CW);Pathopresult. Op(Path1,path2, Path. Op. Difference);Canvas. Translate(0, $);Canvas. DrawText("Difference", -,0, Mdeafultpaint);Canvas. DrawPath(Pathopresult,mdeafultpaint);Pathopresult. Op(Path1,path2, Path. Op. REVERSE_difference);Canvas. Translate(0, -);Canvas. DrawText("Reverse_difference", -,0, Mdeafultpaint);Canvas. DrawPath(Pathopresult,mdeafultpaint);Pathopresult. Op(Path1,path2, Path. Op. INTERSECT);Canvas. Translate(0, -);Canvas. DrawText("INTERSECT", -,0, Mdeafultpaint);Canvas. DrawPath(Pathopresult,mdeafultpaint);Pathopresult. Op(Path1,path2, Path. Op. UNION);Canvas. Translate(0, -);Canvas. DrawText("UNION", -,0, Mdeafultpaint);Canvas. DrawPath(Pathopresult,mdeafultpaint);Pathopresult. Op(Path1,path2, Path. Op. XOR);Canvas. Translate(0, -);Canvas. DrawText("XOR", -,0, Mdeafultpaint);Canvas. DrawPath(Pathopresult,mdeafultpaint);<div class="Se-preview-section-delimiter"></div>
Calculate boundary
The main function of this method is to calculate the space occupied by the path and where it is located, as follows:
voidboolean exact)<div class="se-preview-section-delimiter"></div>
It has two parameters:
Parameters |
function |
Bounds |
The measurement results are placed in this rectangle |
Exact |
Whether accurate measurement, the current parameter has been deprecated, generally write true. |
For more information about exact, please refer to Google's official submission record path.computebounds ()
Compute Boundary Example
A simple example of calculating the path boundary.
Code:
//Mobile Canvas,mviewwidth and Mviewheight obtained in the Onsizechanged methodCanvas.translate (mviewwidth/2, mviewheight/2); RECTF Rect1 =NewRECTF ();//rectangle to store measurement resultsPath PATH =NewPath ();//create path and add some contentPath.lineto ( -,- -); Path.lineto ( -, -); Path.close (); Path.addcircle (- -,0, -, Path.Direction.CW); Path.computebounds (Rect1,true);//measurement pathCanvas.drawpath (Path,mdeafultpaint);//Draw pathMdeafultpaint.setstyle (Paint.Style.STROKE); Mdeafultpaint.setcolor (color.red); Canvas.drawrect (Rect1,mdeafultpaint);//Draw boundary
Reset Path
There are two ways to reset the path, namely reset and rewind, and the difference between the two is mainly two points:
Method |
whether to preserve Filltype settings |
whether to retain the original data structure |
Reset |
Is |
Whether |
Rewind |
Whether |
Is |
When should this two method be chosen?
Select weights: filltype > Data Structures
Because "Filltype" affects the display effect, and "data structure" affects the speed of reconstruction.
Summarize
This is the end of the usual approach to path, and hopefully it will help you deepen your understanding of path and allow you to play happily with path. ( ̄▽ ̄)
(,,? ? ?,,)
PS: Due to my limited level, some places may be misunderstood or inaccurate, if you have questions about this can submit issues for feedback. About Me author Micro-blog: @GcsSloop
Resources
Path
Wikipedia-nonzero-rule
Path Summary of Android graphics
Boolean logic
Googlecode-path.computebounds ()
Path.reset vs Path.rewind
Android Custom View advanced-Path end of chapter (pseudo)